From 43c2f366225af35d9d3a08c545253c754112424b Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Mon, 6 Aug 2018 16:49:12 +0200 Subject: QbsProjectManager: Adapt to cpp.cxxLanguageVersion type change Task-number: QTCREATORBUG-20909 Change-Id: Ic0c018b1a06e2d715d4ea6e301deeacc6aa7f480 Reviewed-by: Joerg Bornemann --- src/plugins/qbsprojectmanager/qbsproject.cpp | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/src/plugins/qbsprojectmanager/qbsproject.cpp b/src/plugins/qbsprojectmanager/qbsproject.cpp index c3d2993d5a..fe94dedb16 100644 --- a/src/plugins/qbsprojectmanager/qbsproject.cpp +++ b/src/plugins/qbsprojectmanager/qbsproject.cpp @@ -827,13 +827,15 @@ static void getExpandedCompilerFlags(QStringList &cFlags, QStringList &cxxFlags, } cFlags = cxxFlags = commonFlags; - const QString cxxLanguageVersion = getCppProp("cxxLanguageVersion").toString(); - if (cxxLanguageVersion == "c++11") - cxxFlags << "-std=c++0x"; - else if (cxxLanguageVersion == "c++14") - cxxFlags << "-std=c++1y"; + const auto cxxLanguageVersion = getCppProp("cxxLanguageVersion").toStringList(); + if (cxxLanguageVersion.contains("c++17")) + cxxFlags << "-std=c++17"; + else if (cxxLanguageVersion.contains("c++14")) + cxxFlags << "-std=c++14"; + else if (cxxLanguageVersion.contains("c++11")) + cxxFlags << "-std=c++11"; else if (!cxxLanguageVersion.isEmpty()) - cxxFlags << ("-std=" + cxxLanguageVersion); + cxxFlags << ("-std=" + cxxLanguageVersion.first()); const QString cxxStandardLibrary = getCppProp("cxxStandardLibrary").toString(); if (!cxxStandardLibrary.isEmpty() && toolchain.contains("clang")) cxxFlags << ("-stdlib=" + cxxStandardLibrary); @@ -844,11 +846,13 @@ static void getExpandedCompilerFlags(QStringList &cFlags, QStringList &cxxFlags, if (enableRtti.isValid()) cxxFlags << QLatin1String(enableRtti.toBool() ? "-frtti" : "-fno-rtti"); - const QString cLanguageVersion = getCppProp("cLanguageVersion").toString(); - if (cLanguageVersion == "c11") - cFlags << "-std=c1x"; + const auto cLanguageVersion = getCppProp("cLanguageVersion").toStringList(); + if (cLanguageVersion.contains("c11")) + cFlags << "-std=c11"; + else if (cLanguageVersion.contains("c99")) + cFlags << "-std=c99"; else if (!cLanguageVersion.isEmpty()) - cFlags << ("-std=" + cLanguageVersion); + cFlags << ("-std=" + cLanguageVersion.first()); } else if (toolchain.contains("msvc")) { if (enableExceptions.toBool()) { const QString exceptionModel = getCppProp("exceptionHandlingModel").toString(); @@ -864,6 +868,8 @@ static void getExpandedCompilerFlags(QStringList &cFlags, QStringList &cxxFlags, cxxFlags << "/TP"; if (enableRtti.isValid()) cxxFlags << QLatin1String(enableRtti.toBool() ? "/GR" : "/GR-"); + if (getCppProp("cxxLanguageVersion").toStringList().contains("c++17")) + cxxFlags << "/std:c++17"; } } -- cgit v1.2.1 From 2c6a57be9c6603eac37ab4755b738c21c3f03081 Mon Sep 17 00:00:00 2001 From: Robert Loehning Date: Fri, 3 Aug 2018 16:10:45 +0200 Subject: Squish: Move imports of "os", "re" and "sys" into shared class Change-Id: I349cb255b8fa6f96e32d5dacb3c9b58ddeb76897 Reviewed-by: Christian Stenger --- tests/system/shared/build_utils.py | 2 -- tests/system/shared/editor_utils.py | 2 -- tests/system/shared/project.py | 3 --- tests/system/shared/project_explorer.py | 2 -- tests/system/shared/qtcreator.py | 1 + tests/system/shared/utils.py | 2 -- tests/system/shared/workarounds.py | 1 - tests/system/suite_HELP/tst_HELP04/test.py | 1 - tests/system/suite_debugger/tst_qml_locals/Tree.py | 2 -- tests/system/suite_general/tst_default_settings/test.py | 2 -- 10 files changed, 1 insertion(+), 17 deletions(-) diff --git a/tests/system/shared/build_utils.py b/tests/system/shared/build_utils.py index 0aaab2ac33..ee9037557f 100644 --- a/tests/system/shared/build_utils.py +++ b/tests/system/shared/build_utils.py @@ -23,8 +23,6 @@ # ############################################################################ -import re; - def getBuildIssues(): ensureChecked(":Qt Creator_Issues_Core::Internal::OutputPaneToggleButton") model = waitForObject(":Qt Creator.Issues_QListView").model() diff --git a/tests/system/shared/editor_utils.py b/tests/system/shared/editor_utils.py index df3f7d37ea..9b391b4497 100644 --- a/tests/system/shared/editor_utils.py +++ b/tests/system/shared/editor_utils.py @@ -23,8 +23,6 @@ # ############################################################################ -import re; - # places the cursor inside the given editor into the given line # (leading and trailing whitespaces are ignored!) # and goes to the end of the line diff --git a/tests/system/shared/project.py b/tests/system/shared/project.py index bd79846102..ac6bec0d38 100644 --- a/tests/system/shared/project.py +++ b/tests/system/shared/project.py @@ -23,9 +23,6 @@ # ############################################################################ -import __builtin__ -import re - def openQbsProject(projectPath): cleanUpUserFiles(projectPath) invokeMenuItem("File", "Open File or Project...") diff --git a/tests/system/shared/project_explorer.py b/tests/system/shared/project_explorer.py index 2ad9a32957..3c7ed2535d 100644 --- a/tests/system/shared/project_explorer.py +++ b/tests/system/shared/project_explorer.py @@ -23,8 +23,6 @@ # ############################################################################ -import re; - # this function switches the MainWindow of creator to the specified view def switchViewTo(view): # make sure that no tooltip is shown, so move the mouse away and wait until all disappear diff --git a/tests/system/shared/qtcreator.py b/tests/system/shared/qtcreator.py index c812ccd624..409be0fc30 100644 --- a/tests/system/shared/qtcreator.py +++ b/tests/system/shared/qtcreator.py @@ -24,6 +24,7 @@ ############################################################################ import platform; +import re; import shutil; import os; import glob; diff --git a/tests/system/shared/utils.py b/tests/system/shared/utils.py index 097772769d..5bbec57458 100644 --- a/tests/system/shared/utils.py +++ b/tests/system/shared/utils.py @@ -457,7 +457,6 @@ def iterateQtVersions(keepOptionsOpen=False, alreadyOnOptionsDialog=False, else: currResult = additionalFunction(target, version, *argsForAdditionalFunc) except: - import sys t,v,_ = sys.exc_info() currResult = None test.fatal("Function to additionally execute on Options Dialog could not be found or " @@ -520,7 +519,6 @@ def iterateKits(keepOptionsOpen=False, alreadyOnOptionsDialog=False, else: currResult = additionalFunction(item, kitName, *argsForAdditionalFunc) except: - import sys t,v,_ = sys.exc_info() currResult = None test.fatal("Function to additionally execute on Options Dialog could not be " diff --git a/tests/system/shared/workarounds.py b/tests/system/shared/workarounds.py index cb1cc0ba84..a74fbb5981 100644 --- a/tests/system/shared/workarounds.py +++ b/tests/system/shared/workarounds.py @@ -24,7 +24,6 @@ ############################################################################ import urllib2 -import re ############ functions not related to issues tracked inside jira ############ diff --git a/tests/system/suite_HELP/tst_HELP04/test.py b/tests/system/suite_HELP/tst_HELP04/test.py index 471df57378..e6ce7932d0 100644 --- a/tests/system/suite_HELP/tst_HELP04/test.py +++ b/tests/system/suite_HELP/tst_HELP04/test.py @@ -24,7 +24,6 @@ ############################################################################ source("../../shared/qtcreator.py") -import re # test search in help mode and advanced search searchKeywordDictionary={ "abundance":True, "deplmint":False, "QODBC":True, "bld":False } diff --git a/tests/system/suite_debugger/tst_qml_locals/Tree.py b/tests/system/suite_debugger/tst_qml_locals/Tree.py index 53063b2a8b..b4202de9e7 100644 --- a/tests/system/suite_debugger/tst_qml_locals/Tree.py +++ b/tests/system/suite_debugger/tst_qml_locals/Tree.py @@ -23,8 +23,6 @@ # ############################################################################ -import os - # Helper class to create a tree structure class Tree: def __init__(self, name=None, value=None, children=None): diff --git a/tests/system/suite_general/tst_default_settings/test.py b/tests/system/suite_general/tst_default_settings/test.py index bb75bf9b32..08b8cc2253 100644 --- a/tests/system/suite_general/tst_default_settings/test.py +++ b/tests/system/suite_general/tst_default_settings/test.py @@ -25,8 +25,6 @@ source("../../shared/qtcreator.py") -import re - currentSelectedTreeItem = None warningOrError = re.compile('

((Error|Warning).*?)

') -- cgit v1.2.1 From 2a274728c2d1ab191f2a6833075dd2309c4f92d4 Mon Sep 17 00:00:00 2001 From: Robert Loehning Date: Thu, 2 Aug 2018 11:39:04 +0200 Subject: Squish: Also check for "Profile" config being checked Change-Id: I9f6598144b81240c4a92abb7e71b7c4cbf6baa4a Reviewed-by: Christian Stenger --- tests/system/shared/project.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/system/shared/project.py b/tests/system/shared/project.py index ac6bec0d38..dedea6649c 100644 --- a/tests/system/shared/project.py +++ b/tests/system/shared/project.py @@ -168,6 +168,7 @@ def __selectQtVersionDesktop__(checks, available=None, withoutQt4=False): cbObject = ("{type='QCheckBox' text='%s' unnamed='1' visible='1' " "container=%s}") verifyChecked(cbObject % ("Debug", objectMap.realName(detailsWidget))) + verifyChecked(cbObject % ("Profile", objectMap.realName(detailsWidget))) verifyChecked(cbObject % ("Release", objectMap.realName(detailsWidget))) clickButton(detailsButton) clickButton(waitForObject(":Next_QPushButton")) -- cgit v1.2.1 From 164d6ce7e0a03e779470a1b951079bc500e9df2d Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Mon, 6 Aug 2018 13:57:17 +0200 Subject: AutoTest: Fix and unify handling of group nodes QtTest had been forgotten to handle correctly as well. So, it was possible to have several levels of grouping which had not been handled correctly. By (current) definition we handle only one level of grouping, so prohibit more for QtTest tree items as well. Basically move the check into a separate function and use this beforehand instead of creating a nullptr. Change-Id: Icbf02eae67e89464f371eb349eecf2976636d05f Reviewed-by: David Schulz --- src/plugins/autotest/gtest/gtesttreeitem.cpp | 7 +++++-- src/plugins/autotest/gtest/gtesttreeitem.h | 1 + src/plugins/autotest/qtest/qttesttreeitem.cpp | 5 +++++ src/plugins/autotest/qtest/qttesttreeitem.h | 1 + src/plugins/autotest/quick/quicktesttreeitem.cpp | 10 +++++----- src/plugins/autotest/quick/quicktesttreeitem.h | 1 + src/plugins/autotest/testtreeitem.cpp | 5 +++++ src/plugins/autotest/testtreeitem.h | 1 + src/plugins/autotest/testtreemodel.cpp | 4 ++-- 9 files changed, 26 insertions(+), 9 deletions(-) diff --git a/src/plugins/autotest/gtest/gtesttreeitem.cpp b/src/plugins/autotest/gtest/gtesttreeitem.cpp index e1976771ab..0d49dfc28e 100644 --- a/src/plugins/autotest/gtest/gtesttreeitem.cpp +++ b/src/plugins/autotest/gtest/gtesttreeitem.cpp @@ -403,8 +403,6 @@ bool GTestTreeItem::modify(const TestParseResult *result) TestTreeItem *GTestTreeItem::createParentGroupNode() const { - if (type() != TestCase) - return nullptr; if (GTestFramework::groupMode() == GTest::Constants::Directory) { const QFileInfo fileInfo(filePath()); const QFileInfo base(fileInfo.absolutePath()); @@ -511,6 +509,11 @@ bool GTestTreeItem::isGroupNodeFor(const TestTreeItem *other) const } } +bool GTestTreeItem::isGroupable() const +{ + return type() == TestCase; +} + TestTreeItem *GTestTreeItem::applyFilters() { if (type() != TestCase) diff --git a/src/plugins/autotest/gtest/gtesttreeitem.h b/src/plugins/autotest/gtest/gtesttreeitem.h index 22225ae7f5..8f1300007f 100644 --- a/src/plugins/autotest/gtest/gtesttreeitem.h +++ b/src/plugins/autotest/gtest/gtesttreeitem.h @@ -72,6 +72,7 @@ public: QString nameSuffix() const; QSet internalTargets() const override; bool isGroupNodeFor(const TestTreeItem *other) const override; + bool isGroupable() const override; TestTreeItem *applyFilters() override; private: bool modifyTestSetContent(const GTestParseResult *result); diff --git a/src/plugins/autotest/qtest/qttesttreeitem.cpp b/src/plugins/autotest/qtest/qttesttreeitem.cpp index 2f375a484e..c9917d41bc 100644 --- a/src/plugins/autotest/qtest/qttesttreeitem.cpp +++ b/src/plugins/autotest/qtest/qttesttreeitem.cpp @@ -346,6 +346,11 @@ TestTreeItem *QtTestTreeItem::createParentGroupNode() const return new QtTestTreeItem(base.baseName(), fileInfo.absolutePath(), TestTreeItem::GroupNode); } +bool QtTestTreeItem::isGroupable() const +{ + return type() == TestCase; +} + TestTreeItem *QtTestTreeItem::findChildByNameAndInheritance(const QString &name, bool inherited) const { return findFirstLevelChild([name, inherited](const TestTreeItem *other) { diff --git a/src/plugins/autotest/qtest/qttesttreeitem.h b/src/plugins/autotest/qtest/qttesttreeitem.h index 2de8eb8f82..3c7f9c4bd7 100644 --- a/src/plugins/autotest/qtest/qttesttreeitem.h +++ b/src/plugins/autotest/qtest/qttesttreeitem.h @@ -52,6 +52,7 @@ public: void setInherited(bool inherited) { m_inherited = inherited; } bool inherited() const { return m_inherited; } TestTreeItem *createParentGroupNode() const override; + bool isGroupable() const override; private: TestTreeItem *findChildByNameAndInheritance(const QString &name, bool inherited) const; QString nameSuffix() const; diff --git a/src/plugins/autotest/quick/quicktesttreeitem.cpp b/src/plugins/autotest/quick/quicktesttreeitem.cpp index 227c56410f..94672bcc23 100644 --- a/src/plugins/autotest/quick/quicktesttreeitem.cpp +++ b/src/plugins/autotest/quick/quicktesttreeitem.cpp @@ -401,16 +401,16 @@ bool QuickTestTreeItem::removeOnSweepIfEmpty() const TestTreeItem *QuickTestTreeItem::createParentGroupNode() const { - if (filePath().isEmpty() || name().isEmpty()) - return nullptr; - if (type() == TestFunctionOrSet) - return nullptr; - const QFileInfo fileInfo(filePath()); const QFileInfo base(fileInfo.absolutePath()); return new QuickTestTreeItem(base.baseName(), fileInfo.absolutePath(), TestTreeItem::GroupNode); } +bool QuickTestTreeItem::isGroupable() const +{ + return type() == TestCase && !name().isEmpty() && !filePath().isEmpty(); +} + QSet QuickTestTreeItem::internalTargets() const { QSet result; diff --git a/src/plugins/autotest/quick/quicktesttreeitem.h b/src/plugins/autotest/quick/quicktesttreeitem.h index 97c287f38f..b1d49065f3 100644 --- a/src/plugins/autotest/quick/quicktesttreeitem.h +++ b/src/plugins/autotest/quick/quicktesttreeitem.h @@ -53,6 +53,7 @@ public: bool isGroupNodeFor(const TestTreeItem *other) const override; bool removeOnSweepIfEmpty() const override; TestTreeItem *createParentGroupNode() const override; + bool isGroupable() const override; QSet internalTargets() const override; void markForRemovalRecursively(const QString &filePath) override; private: diff --git a/src/plugins/autotest/testtreeitem.cpp b/src/plugins/autotest/testtreeitem.cpp index c136ed30ab..c6b5101557 100644 --- a/src/plugins/autotest/testtreeitem.cpp +++ b/src/plugins/autotest/testtreeitem.cpp @@ -302,6 +302,11 @@ bool TestTreeItem::isGroupNodeFor(const TestTreeItem *other) const return QFileInfo(other->filePath()).absolutePath() == filePath(); } +bool TestTreeItem::isGroupable() const +{ + return true; +} + QSet TestTreeItem::internalTargets() const { auto cppMM = CppTools::CppModelManager::instance(); diff --git a/src/plugins/autotest/testtreeitem.h b/src/plugins/autotest/testtreeitem.h index 10c5dee29b..de9e824eda 100644 --- a/src/plugins/autotest/testtreeitem.h +++ b/src/plugins/autotest/testtreeitem.h @@ -120,6 +120,7 @@ public: virtual TestTreeItem *findChild(const TestTreeItem *other) = 0; virtual bool modify(const TestParseResult *result) = 0; virtual bool isGroupNodeFor(const TestTreeItem *other) const; + virtual bool isGroupable() const; virtual TestTreeItem *createParentGroupNode() const = 0; // based on (internal) filters this will be used to filter out sub items (and remove them) // returns a copy of the item that contains the filtered out children or nullptr diff --git a/src/plugins/autotest/testtreemodel.cpp b/src/plugins/autotest/testtreemodel.cpp index 48e3224032..0b9eaaa426 100644 --- a/src/plugins/autotest/testtreemodel.cpp +++ b/src/plugins/autotest/testtreemodel.cpp @@ -346,13 +346,13 @@ static void applyParentCheckState(TestTreeItem *parent, TestTreeItem *newItem) void TestTreeModel::insertItemInParent(TestTreeItem *item, TestTreeItem *root, bool groupingEnabled) { TestTreeItem *parentNode = root; - if (groupingEnabled) { + if (groupingEnabled && item->isGroupable()) { parentNode = root->findFirstLevelChild([item] (const TestTreeItem *it) { return it->isGroupNodeFor(item); }); if (!parentNode) { parentNode = item->createParentGroupNode(); - if (!parentNode) // we might not get a group node at all + if (!QTC_GUARD(parentNode)) // we might not get a group node at all parentNode = root; else root->appendChild(parentNode); -- cgit v1.2.1 From d58b31c2eb930cb5568f9af5ba9d24edd9e4f07b Mon Sep 17 00:00:00 2001 From: Ivan Donchevskii Date: Wed, 8 Aug 2018 09:49:24 +0200 Subject: Clang: Fix the include paths order for libclang Clang headers should always come first. After we removed '-isystem' from other paths it was still used for clang headers which put it in the end of list. This fix returns the paths their original order. Change-Id: I0a4ab450a5303e2536e60200f479cc19f6f55e99 Reviewed-by: Christian Stenger Reviewed-by: Marco Bubke --- src/plugins/cpptools/compileroptionsbuilder.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/cpptools/compileroptionsbuilder.cpp b/src/plugins/cpptools/compileroptionsbuilder.cpp index 3c2dba239e..e16a424f3b 100644 --- a/src/plugins/cpptools/compileroptionsbuilder.cpp +++ b/src/plugins/cpptools/compileroptionsbuilder.cpp @@ -513,7 +513,7 @@ void CompilerOptionsBuilder::addPredefinedHeaderPathsOptions() void CompilerOptionsBuilder::addClangIncludeFolder() { QTC_CHECK(!m_clangVersion.isEmpty()); - add(SYSTEM_INCLUDE_PREFIX); + add(includeDirOption()); add(clangIncludeDirectory(m_clangVersion, m_clangResourceDirectory)); } -- cgit v1.2.1 From a79b32fefab835bd6e79040e59bf293ef3b4e59a Mon Sep 17 00:00:00 2001 From: Ivan Donchevskii Date: Wed, 8 Aug 2018 14:01:04 +0200 Subject: Clang: Fix resource directory path Effected clang tools in developer builds. Change-Id: I3ecbc38f37fa2a41f3777f402fd7fe5bf5ba7e94 Reviewed-by: Christian Stenger Reviewed-by: Marco Bubke --- src/plugins/clangtools/clangtoolruncontrol.cpp | 15 ++++++--------- src/plugins/clangtools/clangtoolruncontrol.h | 2 +- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/src/plugins/clangtools/clangtoolruncontrol.cpp b/src/plugins/clangtools/clangtoolruncontrol.cpp index cc25d5124d..8e33d18b3a 100644 --- a/src/plugins/clangtools/clangtoolruncontrol.cpp +++ b/src/plugins/clangtools/clangtoolruncontrol.cpp @@ -185,16 +185,14 @@ private: bool m_success = false; }; -static AnalyzeUnits toAnalyzeUnits(const FileInfos &fileInfos, - const QString &clangVersion, - const QString &clangResourceDirectory) +static AnalyzeUnits toAnalyzeUnits(const FileInfos &fileInfos) { AnalyzeUnits unitsToAnalyze; const CompilerOptionsBuilder::PchUsage pchUsage = CppTools::getPchUsage(); for (const FileInfo &fileInfo : fileInfos) { CompilerOptionsBuilder optionsBuilder(*fileInfo.projectPart, - clangVersion, - clangResourceDirectory); + CLANG_VERSION, + CLANG_RESOURCE_DIR); QStringList arguments = extraClangToolsPrependOptions(); arguments.append(optionsBuilder.build(fileInfo.kind, pchUsage)); arguments.append(extraClangToolsAppendOptions()); @@ -204,12 +202,11 @@ static AnalyzeUnits toAnalyzeUnits(const FileInfos &fileInfos, return unitsToAnalyze; } -AnalyzeUnits ClangToolRunControl::unitsToAnalyze(const QString &clangVersion) +AnalyzeUnits ClangToolRunControl::unitsToAnalyze() { QTC_ASSERT(m_projectInfo.isValid(), return AnalyzeUnits()); - const QString clangResourceDirectory = clangIncludeDirectory(m_clangExecutable, clangVersion); - return toAnalyzeUnits(m_fileInfos, clangVersion, clangResourceDirectory); + return toAnalyzeUnits(m_fileInfos); } static QDebug operator<<(QDebug debug, const Utils::Environment &environment) @@ -311,7 +308,7 @@ void ClangToolRunControl::start() } // Collect files - const AnalyzeUnits unitsToProcess = unitsToAnalyze(CLANG_VERSION); + const AnalyzeUnits unitsToProcess = unitsToAnalyze(); qCDebug(LOG) << "Files to process:" << unitsToProcess; m_unitsToProcess = unitsToProcess; m_initialFilesToProcessSize = m_unitsToProcess.count(); diff --git a/src/plugins/clangtools/clangtoolruncontrol.h b/src/plugins/clangtools/clangtoolruncontrol.h index 65f4bf35d0..dd5a95662e 100644 --- a/src/plugins/clangtools/clangtoolruncontrol.h +++ b/src/plugins/clangtools/clangtoolruncontrol.h @@ -77,7 +77,7 @@ private: void start() final; void stop() final; - AnalyzeUnits unitsToAnalyze(const QString &clangVersion); + AnalyzeUnits unitsToAnalyze(); void analyzeNextFile(); void handleFinished(); -- cgit v1.2.1 From d94cd5afcd34a35e3506d0b8d3d83a6a4499222a Mon Sep 17 00:00:00 2001 From: hjk Date: Thu, 9 Aug 2018 10:00:15 +0200 Subject: Debugger: Fix parsing of server command line option Task-number: QTCREATORBUG-20928 Change-Id: Iaa23555353f5b234c550763cdbd04d115d4e0eda Reviewed-by: Christian Stenger --- src/plugins/debugger/debuggerplugin.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp index cf0ce7d5b2..8f0c663a99 100644 --- a/src/plugins/debugger/debuggerplugin.cpp +++ b/src/plugins/debugger/debuggerplugin.cpp @@ -1175,7 +1175,7 @@ bool DebuggerPluginPrivate::parseArgument(QStringList::const_iterator &it, kit = KitManager::kit(Utils::equal(&Kit::displayName, val)); } else if (key == "server") { startMode = AttachToRemoteServer; - remoteChannel = remoteChannel; + remoteChannel = val; } else if (key == "core") { startMode = AttachCore; coreFile = val; -- cgit v1.2.1 From 975f5886a6f09b48efc052bee5aae43613492e04 Mon Sep 17 00:00:00 2001 From: David Schulz Date: Wed, 8 Aug 2018 12:11:04 +0200 Subject: Debugger: fix cdb enum dumper Change-Id: Iac407d98afd8f024a45d0f6550c8b3c00df0a515 Reviewed-by: Christian Stenger --- share/qtcreator/debugger/cdbbridge.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/share/qtcreator/debugger/cdbbridge.py b/share/qtcreator/debugger/cdbbridge.py index 00a9130641..ee2c255d2f 100644 --- a/share/qtcreator/debugger/cdbbridge.py +++ b/share/qtcreator/debugger/cdbbridge.py @@ -93,6 +93,11 @@ class Dumper(DumperBase): self.outputLock = threading.Lock() self.isCdb = True + def enumValue(self, nativeValue): + val = nativeValue.nativeDebuggerValue() + # remove '0n' decimal prefix of the native cdb value output + return val.replace('(0n', '(') + def fromNativeValue(self, nativeValue): self.check(isinstance(nativeValue, cdbext.Value)) val = self.Value(self) @@ -123,6 +128,8 @@ class Dumper(DumperBase): except: # read raw memory in case the integerString can not be interpreted pass + if val.type.code == TypeCodeEnum: + val.ldisplay = enumValue(nativeValue) val.isBaseClass = val.name == val.type.name val.nativeValue = nativeValue val.laddress = nativeValue.address() @@ -212,9 +219,7 @@ class Dumper(DumperBase): value = cdbext.createValue(addr, nativeType) if value is None: return '' - enumDisplay = value.nativeDebuggerValue() - # remove '0n' decimal prefix of the native cdb value output - return enumDisplay.replace('(0n', '(') + return enumDisplay(value) def enumExpression(self, enumType, enumValue): ns = self.qtNamespace() -- cgit v1.2.1 From 36d21d576013a25492a7454efba1c9e33724b242 Mon Sep 17 00:00:00 2001 From: David Schulz Date: Wed, 8 Aug 2018 10:42:35 +0200 Subject: ProjectExplorer: reduce amount of concurrent running vcvars.bat scripts The concurrent execution of multiple batch scripts seems to be suspicious behavior for some of the anti virus solutions out there. Task-number: QTCREATORBUG-20868 Task-number: QTCREATORBUG-20637 Task-number: QTCREATORBUG-20829 Task-number: QTCREATORBUG-20886 Change-Id: I2a05ccf937218bca09227bf34f56da38123ffbe7 Reviewed-by: Eike Ziller Reviewed-by: Christian Stenger --- src/plugins/projectexplorer/msvctoolchain.cpp | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/plugins/projectexplorer/msvctoolchain.cpp b/src/plugins/projectexplorer/msvctoolchain.cpp index 8a277fe5f1..8ed356a324 100644 --- a/src/plugins/projectexplorer/msvctoolchain.cpp +++ b/src/plugins/projectexplorer/msvctoolchain.cpp @@ -26,6 +26,7 @@ #include "msvctoolchain.h" #include "msvcparser.h" +#include "projectexplorer.h" #include "projectexplorerconstants.h" #include "taskhub.h" #include "toolchainmanager.h" @@ -65,6 +66,16 @@ namespace Internal { // Helpers: // -------------------------------------------------------------------------- +static QThreadPool *envModThreadPool() +{ + static QThreadPool *pool = nullptr; + if (!pool) { + pool = new QThreadPool(ProjectExplorerPlugin::instance()); + pool->setMaxThreadCount(1); + } + return pool; +} + struct MsvcPlatform { MsvcToolChain::Platform platform; const char *name; @@ -647,7 +658,8 @@ MsvcToolChain::MsvcToolChain(Core::Id typeId, const QString &name, const Abi &ab : AbstractMsvcToolChain(typeId, l, d, abi, varsBat) , m_varsBatArg(varsBatArg) { - initEnvModWatcher(Utils::runAsync(&MsvcToolChain::environmentModifications, + initEnvModWatcher(Utils::runAsync(envModThreadPool(), + &MsvcToolChain::environmentModifications, varsBat, varsBatArg)); Q_ASSERT(!name.isEmpty()); @@ -739,7 +751,8 @@ bool MsvcToolChain::fromMap(const QVariantMap &data) m_environmentModifications = Utils::EnvironmentItem::itemsFromVariantList( data.value(QLatin1String(environModsKeyC)).toList()); - initEnvModWatcher(Utils::runAsync(&MsvcToolChain::environmentModifications, + initEnvModWatcher(Utils::runAsync(envModThreadPool(), + &MsvcToolChain::environmentModifications, m_vcvarsBat, m_varsBatArg)); return !m_vcvarsBat.isEmpty() && m_abi.isValid(); -- cgit v1.2.1 From aed1616b351e909b870e5caccd544b66b16000bf Mon Sep 17 00:00:00 2001 From: Robert Loehning Date: Thu, 2 Aug 2018 19:55:52 +0200 Subject: Squish: Simplify mapping between kits and their names Task-number: QTCREATORBUG-20861 Change-Id: I809036dc331b93f015ee5b10381229b106e27cbd Reviewed-by: Christian Stenger --- tests/system/shared/classes.py | 36 +++++++++++------------------------- 1 file changed, 11 insertions(+), 25 deletions(-) diff --git a/tests/system/shared/classes.py b/tests/system/shared/classes.py index a8bdbf9664..cd6facb6ca 100644 --- a/tests/system/shared/classes.py +++ b/tests/system/shared/classes.py @@ -27,7 +27,7 @@ import __builtin__ # for easier re-usage (because Python hasn't an enum type) class Targets: - ALL_TARGETS = tuple(map(lambda x: 2 ** x , range(5))) + ALL_TARGETS = tuple(range(5)) (DESKTOP_4_8_7_DEFAULT, EMBEDDED_LINUX, @@ -35,6 +35,13 @@ class Targets: DESKTOP_5_6_1_DEFAULT, DESKTOP_5_10_1_DEFAULT) = ALL_TARGETS + __TARGET_NAME_DICT__ = dict(zip(ALL_TARGETS, + ["Desktop 4.8.7 default", + "Embedded Linux", + "Desktop 5.4.1 GCC", + "Desktop 5.6.1 default", + "Desktop 5.10.1 default"])) + @staticmethod def availableTargetClasses(): availableTargets = list(Targets.ALL_TARGETS) @@ -51,41 +58,20 @@ class Targets: desktopTargets.remove(Targets.EMBEDDED_LINUX) return desktopTargets - @staticmethod - def qt4Classes(): - return (Targets.DESKTOP_4_8_7_DEFAULT | Targets.EMBEDDED_LINUX) - @staticmethod def getStringForTarget(target): - if target == Targets.DESKTOP_4_8_7_DEFAULT: - return "Desktop 4.8.7 default" - elif target == Targets.EMBEDDED_LINUX: - return "Embedded Linux" - elif target == Targets.DESKTOP_5_4_1_GCC: - return "Desktop 5.4.1 GCC" - elif target == Targets.DESKTOP_5_6_1_DEFAULT: - return "Desktop 5.6.1 default" - elif target == Targets.DESKTOP_5_10_1_DEFAULT: - return "Desktop 5.10.1 default" - else: - return None + return Targets.__TARGET_NAME_DICT__[target] @staticmethod def getTargetsAsStrings(targets): if not isinstance(targets, (tuple,list)): test.fatal("Wrong usage... This function handles only tuples or lists.") return None - result = map(Targets.getStringForTarget, targets) - if None in result: - test.fatal("You've passed at least one unknown target!") - return result + return map(Targets.getStringForTarget, targets) @staticmethod def getIdForTargetName(targetName): - for id in Targets.ALL_TARGETS: - if Targets.getStringForTarget(id) == targetName: - return id - raise Exception("'%s' is not a known target name" % targetName) + return {v:k for k, v in Targets.__TARGET_NAME_DICT__.items()}[targetName] @staticmethod def getDefaultKit(): -- cgit v1.2.1 From 59f124eb07174143054ab394c6214266421cd375 Mon Sep 17 00:00:00 2001 From: Robert Loehning Date: Wed, 8 Aug 2018 15:16:23 +0200 Subject: Squish: Fix checking for Profile mode Amends 2a274728c2d1. Change-Id: Id686e031658ad737eaeeffabe857452cc8a0d7ac Reviewed-by: Robert Loehning --- tests/system/shared/project.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/system/shared/project.py b/tests/system/shared/project.py index dedea6649c..922e5befe9 100644 --- a/tests/system/shared/project.py +++ b/tests/system/shared/project.py @@ -168,7 +168,8 @@ def __selectQtVersionDesktop__(checks, available=None, withoutQt4=False): cbObject = ("{type='QCheckBox' text='%s' unnamed='1' visible='1' " "container=%s}") verifyChecked(cbObject % ("Debug", objectMap.realName(detailsWidget))) - verifyChecked(cbObject % ("Profile", objectMap.realName(detailsWidget))) + if target not in (Targets.DESKTOP_4_8_7_DEFAULT, Targets.EMBEDDED_LINUX): + verifyChecked(cbObject % ("Profile", objectMap.realName(detailsWidget))) verifyChecked(cbObject % ("Release", objectMap.realName(detailsWidget))) clickButton(detailsButton) clickButton(waitForObject(":Next_QPushButton")) -- cgit v1.2.1 From 49a498c0a622647cd3e1602382e0764e4443ce7e Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Thu, 9 Aug 2018 14:52:50 +0200 Subject: Debugger: Fix accessing member function Amends 975f5886a6f09b48efc052bee5aae43613492e04. Change-Id: I0e8f5a9ab0ccf76fc095e0e05bfbdb838a7583d3 Reviewed-by: David Schulz --- share/qtcreator/debugger/cdbbridge.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/qtcreator/debugger/cdbbridge.py b/share/qtcreator/debugger/cdbbridge.py index ee2c255d2f..4e421c2ada 100644 --- a/share/qtcreator/debugger/cdbbridge.py +++ b/share/qtcreator/debugger/cdbbridge.py @@ -129,7 +129,7 @@ class Dumper(DumperBase): # read raw memory in case the integerString can not be interpreted pass if val.type.code == TypeCodeEnum: - val.ldisplay = enumValue(nativeValue) + val.ldisplay = self.enumValue(nativeValue) val.isBaseClass = val.name == val.type.name val.nativeValue = nativeValue val.laddress = nativeValue.address() -- cgit v1.2.1 From 78c4cf9884770149fb9d69f923aa2169baa3f42a Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Thu, 9 Aug 2018 15:40:36 +0200 Subject: Fix wrong color of line/column label Fix up of a8aa4bbb312d163c1fffaa59102a49c77458404c. That introduced a non-QToolBar widget that should be styled like a tool bar, so use a StyledBar instead of plain widget. Task-number: QTCREATORBUG-20916 Change-Id: Ifd899fac136ef4e3310cd5d2b9cd9f0cd2de1376 Reviewed-by: Alessandro Portale --- src/plugins/texteditor/texteditor.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/plugins/texteditor/texteditor.cpp b/src/plugins/texteditor/texteditor.cpp index 8ad2cacf56..5e3d952db7 100644 --- a/src/plugins/texteditor/texteditor.cpp +++ b/src/plugins/texteditor/texteditor.cpp @@ -83,6 +83,7 @@ #include #include #include +#include #include #include #include @@ -804,7 +805,7 @@ TextEditorWidgetPrivate::TextEditorWidgetPrivate(TextEditorWidget *parent) auto toolBarLayout = new QHBoxLayout; toolBarLayout->setContentsMargins(0, 0, 0, 0); toolBarLayout->setSpacing(0); - m_toolBarWidget = new QWidget; + m_toolBarWidget = new Utils::StyledBar; m_toolBarWidget->setLayout(toolBarLayout); m_stretchWidget = new QWidget; m_stretchWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); -- cgit v1.2.1 From a44fe2e4f03fc18ce9c3d050f71fe369916259b8 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Wed, 3 Jan 2018 17:56:52 +0100 Subject: SSH: Use Botan2 Botan 1.10 will be completely unsupported by the end of this year, so we now target API version 2 instead. Also upgrade our bundled Botan to the latest version 2.7. We no longer check in pre-processed files, but use the upstream sources directly (with unneeded parts removed), employing Botan's own configure script for building. This will make future upgrades much simpler. A script to automate this process is also provided. Task-number: QTCREATORBUG-18802 Task-number: QTCREATORBUG-8107 Change-Id: I5a5ea62cfd30d720b556217142e8b7e06bf49f7e Reviewed-by: hjk Reviewed-by: Eike Ziller --- README.md | 1 + qbs/modules/qtc/qtc.qbs | 1 + src/libs/3rdparty/botan/.gitignore | 86 + src/libs/3rdparty/botan/.travis.yml | 1 + src/libs/3rdparty/botan/botan.cpp | 47194 ------------------- src/libs/3rdparty/botan/botan.h | 16208 ------- src/libs/3rdparty/botan/botan.pri | 56 - src/libs/3rdparty/botan/configure.py | 3876 +- src/libs/3rdparty/botan/doc/license.txt | 49 - src/libs/3rdparty/botan/license.txt | 24 + src/libs/3rdparty/botan/readme.rst | 183 + src/libs/3rdparty/botan/readme.txt | 15 - .../3rdparty/botan/src/build-data/arch/alpha.txt | 7 + .../3rdparty/botan/src/build-data/arch/arm32.txt | 20 + .../3rdparty/botan/src/build-data/arch/arm64.txt | 15 + .../3rdparty/botan/src/build-data/arch/hppa.txt | 8 + .../3rdparty/botan/src/build-data/arch/ia64.txt | 6 + .../3rdparty/botan/src/build-data/arch/llvm.txt | 1 + .../3rdparty/botan/src/build-data/arch/m68k.txt | 6 + .../3rdparty/botan/src/build-data/arch/mips32.txt | 6 + .../3rdparty/botan/src/build-data/arch/mips64.txt | 5 + .../botan/src/build-data/arch/powerpcspe.txt | 3 + .../3rdparty/botan/src/build-data/arch/ppc32.txt | 12 + .../3rdparty/botan/src/build-data/arch/ppc64.txt | 14 + .../3rdparty/botan/src/build-data/arch/riscv64.txt | 1 + .../3rdparty/botan/src/build-data/arch/s390.txt | 1 + .../3rdparty/botan/src/build-data/arch/s390x.txt | 2 + .../3rdparty/botan/src/build-data/arch/sparc32.txt | 7 + .../3rdparty/botan/src/build-data/arch/sparc64.txt | 2 + .../3rdparty/botan/src/build-data/arch/superh.txt | 4 + .../3rdparty/botan/src/build-data/arch/x32.txt | 16 + .../3rdparty/botan/src/build-data/arch/x86_32.txt | 29 + .../3rdparty/botan/src/build-data/arch/x86_64.txt | 25 + src/libs/3rdparty/botan/src/build-data/bakefile.in | 51 + .../3rdparty/botan/src/build-data/botan.doxy.in | 213 + src/libs/3rdparty/botan/src/build-data/botan.pc.in | 12 + src/libs/3rdparty/botan/src/build-data/buildh.in | 258 + .../3rdparty/botan/src/build-data/cc/clang.txt | 82 + .../3rdparty/botan/src/build-data/cc/ekopath.txt | 17 + src/libs/3rdparty/botan/src/build-data/cc/gcc.txt | 99 + src/libs/3rdparty/botan/src/build-data/cc/hpcc.txt | 18 + src/libs/3rdparty/botan/src/build-data/cc/icc.txt | 24 + src/libs/3rdparty/botan/src/build-data/cc/msvc.txt | 66 + src/libs/3rdparty/botan/src/build-data/cc/pgi.txt | 11 + .../3rdparty/botan/src/build-data/cc/sunstudio.txt | 39 + src/libs/3rdparty/botan/src/build-data/cc/xlc.txt | 24 + src/libs/3rdparty/botan/src/build-data/cmake.in | 73 + .../3rdparty/botan/src/build-data/detect_arch.cpp | 63 + .../botan/src/build-data/detect_version.cpp | 60 + .../3rdparty/botan/src/build-data/innosetup.in | 73 + src/libs/3rdparty/botan/src/build-data/makefile.in | 132 + src/libs/3rdparty/botan/src/build-data/oids.txt | 295 + src/libs/3rdparty/botan/src/build-data/os/aix.txt | 16 + .../3rdparty/botan/src/build-data/os/android.txt | 18 + .../3rdparty/botan/src/build-data/os/cygwin.txt | 18 + .../3rdparty/botan/src/build-data/os/darwin.txt | 28 + .../3rdparty/botan/src/build-data/os/dragonfly.txt | 15 + .../3rdparty/botan/src/build-data/os/freebsd.txt | 14 + .../3rdparty/botan/src/build-data/os/haiku.txt | 23 + src/libs/3rdparty/botan/src/build-data/os/hpux.txt | 18 + src/libs/3rdparty/botan/src/build-data/os/hurd.txt | 17 + .../3rdparty/botan/src/build-data/os/includeos.txt | 4 + src/libs/3rdparty/botan/src/build-data/os/ios.txt | 19 + .../3rdparty/botan/src/build-data/os/linux.txt | 20 + src/libs/3rdparty/botan/src/build-data/os/llvm.txt | 9 + .../3rdparty/botan/src/build-data/os/mingw.txt | 24 + src/libs/3rdparty/botan/src/build-data/os/nacl.txt | 5 + .../3rdparty/botan/src/build-data/os/netbsd.txt | 14 + .../3rdparty/botan/src/build-data/os/openbsd.txt | 18 + src/libs/3rdparty/botan/src/build-data/os/qnx.txt | 12 + .../3rdparty/botan/src/build-data/os/solaris.txt | 18 + src/libs/3rdparty/botan/src/build-data/os/uwp.txt | 23 + .../3rdparty/botan/src/build-data/os/windows.txt | 35 + src/libs/3rdparty/botan/src/build-data/version.txt | 10 + src/libs/3rdparty/botan/src/lib/asn1/alg_id.cpp | 117 + src/libs/3rdparty/botan/src/lib/asn1/alg_id.h | 59 + .../3rdparty/botan/src/lib/asn1/asn1_attribute.cpp | 58 + .../3rdparty/botan/src/lib/asn1/asn1_attribute.h | 45 + src/libs/3rdparty/botan/src/lib/asn1/asn1_obj.cpp | 235 + src/libs/3rdparty/botan/src/lib/asn1/asn1_obj.h | 191 + src/libs/3rdparty/botan/src/lib/asn1/asn1_oid.cpp | 199 + src/libs/3rdparty/botan/src/lib/asn1/asn1_oid.h | 110 + .../3rdparty/botan/src/lib/asn1/asn1_print.cpp | 329 + src/libs/3rdparty/botan/src/lib/asn1/asn1_print.h | 125 + src/libs/3rdparty/botan/src/lib/asn1/asn1_str.cpp | 153 + src/libs/3rdparty/botan/src/lib/asn1/asn1_str.h | 55 + src/libs/3rdparty/botan/src/lib/asn1/asn1_time.cpp | 283 + src/libs/3rdparty/botan/src/lib/asn1/asn1_time.h | 79 + src/libs/3rdparty/botan/src/lib/asn1/ber_dec.cpp | 549 + src/libs/3rdparty/botan/src/lib/asn1/ber_dec.h | 418 + src/libs/3rdparty/botan/src/lib/asn1/der_enc.cpp | 405 + src/libs/3rdparty/botan/src/lib/asn1/der_enc.h | 221 + src/libs/3rdparty/botan/src/lib/asn1/info.txt | 7 + src/libs/3rdparty/botan/src/lib/asn1/oid_maps.cpp | 447 + src/libs/3rdparty/botan/src/lib/asn1/oids.cpp | 135 + src/libs/3rdparty/botan/src/lib/asn1/oids.h | 76 + src/libs/3rdparty/botan/src/lib/base/botan.h | 45 + src/libs/3rdparty/botan/src/lib/base/buf_comp.h | 184 + src/libs/3rdparty/botan/src/lib/base/info.txt | 17 + src/libs/3rdparty/botan/src/lib/base/init.h | 33 + src/libs/3rdparty/botan/src/lib/base/key_spec.h | 100 + src/libs/3rdparty/botan/src/lib/base/lookup.h | 177 + src/libs/3rdparty/botan/src/lib/base/scan_name.cpp | 144 + src/libs/3rdparty/botan/src/lib/base/scan_name.h | 117 + src/libs/3rdparty/botan/src/lib/base/secmem.h | 202 + src/libs/3rdparty/botan/src/lib/base/sym_algo.cpp | 24 + src/libs/3rdparty/botan/src/lib/base/sym_algo.h | 108 + src/libs/3rdparty/botan/src/lib/base/symkey.cpp | 131 + src/libs/3rdparty/botan/src/lib/base/symkey.h | 145 + src/libs/3rdparty/botan/src/lib/block/aes/aes.cpp | 750 + src/libs/3rdparty/botan/src/lib/block/aes/aes.h | 153 + .../src/lib/block/aes/aes_armv8/aes_armv8.cpp | 501 + .../botan/src/lib/block/aes/aes_armv8/info.txt | 10 + .../botan/src/lib/block/aes/aes_ni/aes_ni.cpp | 792 + .../botan/src/lib/block/aes/aes_ni/info.txt | 7 + .../src/lib/block/aes/aes_power8/aes_power8.cpp | 328 + .../botan/src/lib/block/aes/aes_power8/info.txt | 9 + .../src/lib/block/aes/aes_ssse3/aes_ssse3.cpp | 637 + .../botan/src/lib/block/aes/aes_ssse3/info.txt | 15 + src/libs/3rdparty/botan/src/lib/block/aes/info.txt | 3 + .../3rdparty/botan/src/lib/block/block_cipher.cpp | 349 + .../3rdparty/botan/src/lib/block/block_cipher.h | 237 + src/libs/3rdparty/botan/src/lib/block/des/des.cpp | 381 + src/libs/3rdparty/botan/src/lib/block/des/des.h | 70 + .../3rdparty/botan/src/lib/block/des/des_tab.cpp | 636 + src/libs/3rdparty/botan/src/lib/block/des/desx.cpp | 65 + src/libs/3rdparty/botan/src/lib/block/des/desx.h | 35 + src/libs/3rdparty/botan/src/lib/block/des/info.txt | 3 + src/libs/3rdparty/botan/src/lib/block/info.txt | 7 + .../3rdparty/botan/src/lib/codec/base64/base64.cpp | 261 + .../3rdparty/botan/src/lib/codec/base64/base64.h | 141 + .../3rdparty/botan/src/lib/codec/base64/info.txt | 3 + src/libs/3rdparty/botan/src/lib/codec/hex/hex.cpp | 207 + src/libs/3rdparty/botan/src/lib/codec/hex/hex.h | 148 + src/libs/3rdparty/botan/src/lib/codec/hex/info.txt | 3 + .../entropy/darwin_secrandom/darwin_secrandom.cpp | 30 + .../entropy/darwin_secrandom/darwin_secrandom.h | 28 + .../src/lib/entropy/darwin_secrandom/info.txt | 16 + .../src/lib/entropy/dev_random/dev_random.cpp | 123 + .../botan/src/lib/entropy/dev_random/dev_random.h | 37 + .../botan/src/lib/entropy/dev_random/info.txt | 11 + .../3rdparty/botan/src/lib/entropy/entropy_src.h | 87 + .../botan/src/lib/entropy/entropy_srcs.cpp | 198 + .../src/lib/entropy/getentropy/getentropy.cpp | 35 + .../botan/src/lib/entropy/getentropy/getentropy.h | 28 + .../botan/src/lib/entropy/getentropy/info.txt | 11 + src/libs/3rdparty/botan/src/lib/entropy/info.txt | 7 + .../botan/src/lib/entropy/proc_walk/info.txt | 11 + .../botan/src/lib/entropy/proc_walk/proc_walk.cpp | 154 + .../botan/src/lib/entropy/proc_walk/proc_walk.h | 45 + .../3rdparty/botan/src/lib/entropy/rdrand/info.txt | 11 + .../botan/src/lib/entropy/rdrand/rdrand.cpp | 29 + .../3rdparty/botan/src/lib/entropy/rdrand/rdrand.h | 28 + .../3rdparty/botan/src/lib/entropy/rdseed/info.txt | 16 + .../botan/src/lib/entropy/rdseed/rdseed.cpp | 48 + .../3rdparty/botan/src/lib/entropy/rdseed/rdseed.h | 28 + .../botan/src/lib/entropy/win32_stats/es_win32.cpp | 121 + .../botan/src/lib/entropy/win32_stats/es_win32.h | 27 + .../botan/src/lib/entropy/win32_stats/info.txt | 19 + .../3rdparty/botan/src/lib/filters/aead_filt.h | 40 + .../3rdparty/botan/src/lib/filters/algo_filt.cpp | 96 + .../3rdparty/botan/src/lib/filters/basefilt.cpp | 70 + src/libs/3rdparty/botan/src/lib/filters/basefilt.h | 124 + .../3rdparty/botan/src/lib/filters/buf_filt.cpp | 103 + src/libs/3rdparty/botan/src/lib/filters/buf_filt.h | 93 + .../botan/src/lib/filters/cipher_filter.cpp | 103 + .../3rdparty/botan/src/lib/filters/cipher_filter.h | 58 + .../3rdparty/botan/src/lib/filters/comp_filter.cpp | 122 + .../3rdparty/botan/src/lib/filters/comp_filter.h | 71 + .../3rdparty/botan/src/lib/filters/data_snk.cpp | 75 + src/libs/3rdparty/botan/src/lib/filters/data_snk.h | 76 + src/libs/3rdparty/botan/src/lib/filters/filter.cpp | 129 + src/libs/3rdparty/botan/src/lib/filters/filter.h | 183 + src/libs/3rdparty/botan/src/lib/filters/filters.h | 227 + src/libs/3rdparty/botan/src/lib/filters/info.txt | 24 + .../3rdparty/botan/src/lib/filters/key_filt.cpp | 39 + src/libs/3rdparty/botan/src/lib/filters/key_filt.h | 109 + .../3rdparty/botan/src/lib/filters/out_buf.cpp | 121 + src/libs/3rdparty/botan/src/lib/filters/out_buf.h | 44 + src/libs/3rdparty/botan/src/lib/filters/pipe.cpp | 311 + src/libs/3rdparty/botan/src/lib/filters/pipe.h | 379 + .../3rdparty/botan/src/lib/filters/pipe_io.cpp | 47 + .../3rdparty/botan/src/lib/filters/pipe_rw.cpp | 181 + .../3rdparty/botan/src/lib/filters/secqueue.cpp | 232 + src/libs/3rdparty/botan/src/lib/filters/secqueue.h | 72 + .../botan/src/lib/filters/threaded_fork.cpp | 153 + src/libs/3rdparty/botan/src/lib/hash/hash.cpp | 361 + src/libs/3rdparty/botan/src/lib/hash/hash.h | 91 + src/libs/3rdparty/botan/src/lib/hash/info.txt | 7 + .../3rdparty/botan/src/lib/hash/mdx_hash/info.txt | 5 + .../botan/src/lib/hash/mdx_hash/mdx_hash.cpp | 108 + .../botan/src/lib/hash/mdx_hash/mdx_hash.h | 68 + src/libs/3rdparty/botan/src/lib/hash/sha1/info.txt | 7 + .../3rdparty/botan/src/lib/hash/sha1/sha160.cpp | 188 + src/libs/3rdparty/botan/src/lib/hash/sha1/sha160.h | 73 + .../botan/src/lib/hash/sha1/sha1_armv8/info.txt | 10 + .../src/lib/hash/sha1/sha1_armv8/sha1_armv8.cpp | 207 + .../botan/src/lib/hash/sha1/sha1_sse2/info.txt | 5 + .../src/lib/hash/sha1/sha1_sse2/sha1_sse2.cpp | 335 + .../botan/src/lib/hash/sha1/sha1_x86/info.txt | 11 + .../botan/src/lib/hash/sha1/sha1_x86/sha1_x86.cpp | 216 + .../3rdparty/botan/src/lib/hash/sha2_32/info.txt | 7 + .../botan/src/lib/hash/sha2_32/sha2_32.cpp | 236 + .../3rdparty/botan/src/lib/hash/sha2_32/sha2_32.h | 89 + .../src/lib/hash/sha2_32/sha2_32_armv8/info.txt | 10 + .../hash/sha2_32/sha2_32_armv8/sha2_32_armv8.cpp | 204 + .../src/lib/hash/sha2_32/sha2_32_bmi2/info.txt | 10 + .../lib/hash/sha2_32/sha2_32_bmi2/sha2_32_bmi2.cpp | 139 + .../src/lib/hash/sha2_32/sha2_32_x86/info.txt | 11 + .../lib/hash/sha2_32/sha2_32_x86/sha2_32_x86.cpp | 215 + .../3rdparty/botan/src/lib/hash/sha2_64/info.txt | 7 + .../botan/src/lib/hash/sha2_64/sha2_64.cpp | 241 + .../3rdparty/botan/src/lib/hash/sha2_64/sha2_64.h | 82 + src/libs/3rdparty/botan/src/lib/kdf/info.txt | 12 + src/libs/3rdparty/botan/src/lib/kdf/kdf.cpp | 251 + src/libs/3rdparty/botan/src/lib/kdf/kdf.h | 196 + src/libs/3rdparty/botan/src/lib/mac/hmac/hmac.cpp | 107 + src/libs/3rdparty/botan/src/lib/mac/hmac/hmac.h | 48 + src/libs/3rdparty/botan/src/lib/mac/hmac/info.txt | 7 + src/libs/3rdparty/botan/src/lib/mac/info.txt | 7 + src/libs/3rdparty/botan/src/lib/mac/mac.cpp | 171 + src/libs/3rdparty/botan/src/lib/mac/mac.h | 143 + .../botan/src/lib/math/bigint/big_code.cpp | 166 + .../3rdparty/botan/src/lib/math/bigint/big_io.cpp | 56 + .../botan/src/lib/math/bigint/big_ops2.cpp | 382 + .../botan/src/lib/math/bigint/big_ops3.cpp | 219 + .../botan/src/lib/math/bigint/big_rand.cpp | 64 + .../3rdparty/botan/src/lib/math/bigint/bigint.cpp | 381 + .../3rdparty/botan/src/lib/math/bigint/bigint.h | 806 + .../3rdparty/botan/src/lib/math/bigint/divide.cpp | 140 + .../3rdparty/botan/src/lib/math/bigint/divide.h | 29 + .../3rdparty/botan/src/lib/math/bigint/info.txt | 16 + src/libs/3rdparty/botan/src/lib/math/mp/info.txt | 10 + src/libs/3rdparty/botan/src/lib/math/mp/mp_asmi.h | 875 + .../3rdparty/botan/src/lib/math/mp/mp_comba.cpp | 2211 + .../3rdparty/botan/src/lib/math/mp/mp_core.cpp | 527 + src/libs/3rdparty/botan/src/lib/math/mp/mp_core.h | 209 + .../3rdparty/botan/src/lib/math/mp/mp_karat.cpp | 403 + src/libs/3rdparty/botan/src/lib/math/mp/mp_madd.h | 165 + .../3rdparty/botan/src/lib/math/mp/mp_monty.cpp | 135 + src/libs/3rdparty/botan/src/lib/math/mp/mp_monty.h | 31 + .../3rdparty/botan/src/lib/math/mp/mp_monty_n.cpp | 2614 + .../botan/src/lib/math/numbertheory/curve_nistp.h | 46 + .../botan/src/lib/math/numbertheory/def_powm.h | 68 + .../botan/src/lib/math/numbertheory/dsa_gen.cpp | 136 + .../botan/src/lib/math/numbertheory/info.txt | 24 + .../botan/src/lib/math/numbertheory/jacobi.cpp | 53 + .../botan/src/lib/math/numbertheory/make_prm.cpp | 285 + .../botan/src/lib/math/numbertheory/monty.cpp | 449 + .../botan/src/lib/math/numbertheory/monty.h | 190 + .../botan/src/lib/math/numbertheory/monty_exp.cpp | 248 + .../botan/src/lib/math/numbertheory/monty_exp.h | 54 + .../botan/src/lib/math/numbertheory/mp_numth.cpp | 84 + .../botan/src/lib/math/numbertheory/nistp_redc.cpp | 623 + .../botan/src/lib/math/numbertheory/numthry.cpp | 566 + .../botan/src/lib/math/numbertheory/numthry.h | 278 + .../botan/src/lib/math/numbertheory/pow_mod.cpp | 196 + .../botan/src/lib/math/numbertheory/pow_mod.h | 135 + .../botan/src/lib/math/numbertheory/powm_fw.cpp | 65 + .../botan/src/lib/math/numbertheory/powm_mnt.cpp | 46 + .../botan/src/lib/math/numbertheory/primes.cpp | 609 + .../botan/src/lib/math/numbertheory/reducer.cpp | 90 + .../botan/src/lib/math/numbertheory/reducer.h | 61 + .../botan/src/lib/math/numbertheory/ressol.cpp | 87 + src/libs/3rdparty/botan/src/lib/modes/cbc/cbc.cpp | 312 + src/libs/3rdparty/botan/src/lib/modes/cbc/cbc.h | 154 + src/libs/3rdparty/botan/src/lib/modes/cbc/info.txt | 8 + .../3rdparty/botan/src/lib/modes/cipher_mode.cpp | 188 + .../3rdparty/botan/src/lib/modes/cipher_mode.h | 257 + src/libs/3rdparty/botan/src/lib/modes/info.txt | 9 + .../3rdparty/botan/src/lib/modes/mode_pad/info.txt | 3 + .../botan/src/lib/modes/mode_pad/mode_pad.cpp | 196 + .../botan/src/lib/modes/mode_pad/mode_pad.h | 159 + .../3rdparty/botan/src/lib/modes/stream_mode.h | 82 + src/libs/3rdparty/botan/src/lib/pbkdf/info.txt | 12 + src/libs/3rdparty/botan/src/lib/pbkdf/pbkdf.cpp | 133 + src/libs/3rdparty/botan/src/lib/pbkdf/pbkdf.h | 243 + .../3rdparty/botan/src/lib/pbkdf/pbkdf2/info.txt | 7 + .../3rdparty/botan/src/lib/pbkdf/pbkdf2/pbkdf2.cpp | 118 + .../3rdparty/botan/src/lib/pbkdf/pbkdf2/pbkdf2.h | 57 + src/libs/3rdparty/botan/src/lib/pk_pad/eme.cpp | 94 + src/libs/3rdparty/botan/src/lib/pk_pad/eme.h | 91 + src/libs/3rdparty/botan/src/lib/pk_pad/emsa.cpp | 183 + src/libs/3rdparty/botan/src/lib/pk_pad/emsa.h | 104 + .../3rdparty/botan/src/lib/pk_pad/emsa1/emsa1.cpp | 133 + .../3rdparty/botan/src/lib/pk_pad/emsa1/emsa1.h | 53 + .../3rdparty/botan/src/lib/pk_pad/emsa1/info.txt | 3 + .../botan/src/lib/pk_pad/emsa_pkcs1/emsa_pkcs1.cpp | 170 + .../botan/src/lib/pk_pad/emsa_pkcs1/emsa_pkcs1.h | 92 + .../botan/src/lib/pk_pad/emsa_pkcs1/info.txt | 7 + .../botan/src/lib/pk_pad/emsa_pssr/info.txt | 7 + .../botan/src/lib/pk_pad/emsa_pssr/pssr.cpp | 258 + .../3rdparty/botan/src/lib/pk_pad/emsa_pssr/pssr.h | 99 + .../botan/src/lib/pk_pad/hash_id/hash_id.cpp | 163 + .../botan/src/lib/pk_pad/hash_id/hash_id.h | 34 + .../3rdparty/botan/src/lib/pk_pad/hash_id/info.txt | 3 + src/libs/3rdparty/botan/src/lib/pk_pad/info.txt | 20 + .../3rdparty/botan/src/lib/pk_pad/mgf1/info.txt | 3 + .../3rdparty/botan/src/lib/pk_pad/mgf1/mgf1.cpp | 35 + src/libs/3rdparty/botan/src/lib/pk_pad/mgf1/mgf1.h | 31 + src/libs/3rdparty/botan/src/lib/pk_pad/padding.cpp | 42 + src/libs/3rdparty/botan/src/lib/pk_pad/padding.h | 36 + .../3rdparty/botan/src/lib/pubkey/blinding.cpp | 66 + src/libs/3rdparty/botan/src/lib/pubkey/blinding.h | 78 + src/libs/3rdparty/botan/src/lib/pubkey/dh/dh.cpp | 130 + src/libs/3rdparty/botan/src/lib/pubkey/dh/dh.h | 81 + src/libs/3rdparty/botan/src/lib/pubkey/dh/info.txt | 13 + .../botan/src/lib/pubkey/dl_algo/dl_algo.cpp | 84 + .../botan/src/lib/pubkey/dl_algo/dl_algo.h | 140 + .../3rdparty/botan/src/lib/pubkey/dl_algo/info.txt | 10 + .../botan/src/lib/pubkey/dl_group/dl_group.cpp | 610 + .../botan/src/lib/pubkey/dl_group/dl_group.h | 332 + .../botan/src/lib/pubkey/dl_group/dl_named.cpp | 175 + .../botan/src/lib/pubkey/dl_group/info.txt | 10 + src/libs/3rdparty/botan/src/lib/pubkey/dsa/dsa.cpp | 218 + src/libs/3rdparty/botan/src/lib/pubkey/dsa/dsa.h | 87 + .../3rdparty/botan/src/lib/pubkey/dsa/info.txt | 12 + .../botan/src/lib/pubkey/ec_group/curve_gfp.cpp | 576 + .../botan/src/lib/pubkey/ec_group/curve_gfp.h | 269 + .../botan/src/lib/pubkey/ec_group/ec_group.cpp | 765 + .../botan/src/lib/pubkey/ec_group/ec_group.h | 372 + .../botan/src/lib/pubkey/ec_group/ec_named.cpp | 289 + .../botan/src/lib/pubkey/ec_group/info.txt | 20 + .../botan/src/lib/pubkey/ec_group/point_gfp.cpp | 727 + .../botan/src/lib/pubkey/ec_group/point_gfp.h | 444 + .../botan/src/lib/pubkey/ec_group/point_mul.cpp | 375 + .../botan/src/lib/pubkey/ec_group/point_mul.h | 84 + .../botan/src/lib/pubkey/ecc_key/ecc_key.cpp | 201 + .../botan/src/lib/pubkey/ecc_key/ecc_key.h | 172 + .../3rdparty/botan/src/lib/pubkey/ecc_key/info.txt | 10 + .../3rdparty/botan/src/lib/pubkey/ecdh/ecdh.cpp | 85 + src/libs/3rdparty/botan/src/lib/pubkey/ecdh/ecdh.h | 106 + .../3rdparty/botan/src/lib/pubkey/ecdh/info.txt | 10 + .../3rdparty/botan/src/lib/pubkey/ecdsa/ecdsa.cpp | 256 + .../3rdparty/botan/src/lib/pubkey/ecdsa/ecdsa.h | 98 + .../3rdparty/botan/src/lib/pubkey/ecdsa/info.txt | 14 + src/libs/3rdparty/botan/src/lib/pubkey/info.txt | 31 + .../3rdparty/botan/src/lib/pubkey/keypair/info.txt | 6 + .../botan/src/lib/pubkey/keypair/keypair.cpp | 85 + .../botan/src/lib/pubkey/keypair/keypair.h | 83 + .../3rdparty/botan/src/lib/pubkey/pbes2/info.txt | 10 + .../3rdparty/botan/src/lib/pubkey/pbes2/pbes2.cpp | 312 + .../3rdparty/botan/src/lib/pubkey/pbes2/pbes2.h | 85 + .../3rdparty/botan/src/lib/pubkey/pem/info.txt | 7 + src/libs/3rdparty/botan/src/lib/pubkey/pem/pem.cpp | 169 + src/libs/3rdparty/botan/src/lib/pubkey/pem/pem.h | 91 + src/libs/3rdparty/botan/src/lib/pubkey/pk_algs.cpp | 434 + src/libs/3rdparty/botan/src/lib/pubkey/pk_algs.h | 46 + src/libs/3rdparty/botan/src/lib/pubkey/pk_keys.cpp | 148 + src/libs/3rdparty/botan/src/lib/pubkey/pk_keys.h | 317 + src/libs/3rdparty/botan/src/lib/pubkey/pk_ops.cpp | 173 + src/libs/3rdparty/botan/src/lib/pubkey/pk_ops.h | 150 + .../3rdparty/botan/src/lib/pubkey/pk_ops_fwd.h | 27 + .../3rdparty/botan/src/lib/pubkey/pk_ops_impl.h | 231 + src/libs/3rdparty/botan/src/lib/pubkey/pkcs8.cpp | 468 + src/libs/3rdparty/botan/src/lib/pubkey/pkcs8.h | 288 + src/libs/3rdparty/botan/src/lib/pubkey/pubkey.cpp | 350 + src/libs/3rdparty/botan/src/lib/pubkey/pubkey.h | 771 + .../3rdparty/botan/src/lib/pubkey/rsa/info.txt | 10 + src/libs/3rdparty/botan/src/lib/pubkey/rsa/rsa.cpp | 579 + src/libs/3rdparty/botan/src/lib/pubkey/rsa/rsa.h | 164 + .../3rdparty/botan/src/lib/pubkey/workfactor.cpp | 64 + .../3rdparty/botan/src/lib/pubkey/workfactor.h | 50 + .../3rdparty/botan/src/lib/pubkey/x509_key.cpp | 106 + src/libs/3rdparty/botan/src/lib/pubkey/x509_key.h | 80 + .../botan/src/lib/rng/auto_rng/auto_rng.cpp | 112 + .../3rdparty/botan/src/lib/rng/auto_rng/auto_rng.h | 96 + .../3rdparty/botan/src/lib/rng/auto_rng/info.txt | 8 + .../botan/src/lib/rng/hmac_drbg/hmac_drbg.cpp | 184 + .../botan/src/lib/rng/hmac_drbg/hmac_drbg.h | 159 + .../3rdparty/botan/src/lib/rng/hmac_drbg/info.txt | 8 + src/libs/3rdparty/botan/src/lib/rng/info.txt | 3 + .../3rdparty/botan/src/lib/rng/rdrand_rng/info.txt | 13 + .../botan/src/lib/rng/rdrand_rng/rdrand_rng.cpp | 83 + .../botan/src/lib/rng/rdrand_rng/rdrand_rng.h | 61 + src/libs/3rdparty/botan/src/lib/rng/rng.cpp | 74 + src/libs/3rdparty/botan/src/lib/rng/rng.h | 264 + .../botan/src/lib/rng/stateful_rng/info.txt | 3 + .../src/lib/rng/stateful_rng/stateful_rng.cpp | 112 + .../botan/src/lib/rng/stateful_rng/stateful_rng.h | 151 + .../3rdparty/botan/src/lib/rng/system_rng/info.txt | 18 + .../botan/src/lib/rng/system_rng/system_rng.cpp | 231 + .../botan/src/lib/rng/system_rng/system_rng.h | 41 + src/libs/3rdparty/botan/src/lib/stream/ctr/ctr.cpp | 203 + src/libs/3rdparty/botan/src/lib/stream/ctr/ctr.h | 66 + .../3rdparty/botan/src/lib/stream/ctr/info.txt | 7 + src/libs/3rdparty/botan/src/lib/stream/info.txt | 7 + .../botan/src/lib/stream/stream_cipher.cpp | 149 + .../3rdparty/botan/src/lib/stream/stream_cipher.h | 129 + src/libs/3rdparty/botan/src/lib/utils/assert.cpp | 47 + src/libs/3rdparty/botan/src/lib/utils/assert.h | 145 + src/libs/3rdparty/botan/src/lib/utils/bit_ops.h | 161 + src/libs/3rdparty/botan/src/lib/utils/bswap.h | 99 + src/libs/3rdparty/botan/src/lib/utils/calendar.cpp | 119 + src/libs/3rdparty/botan/src/lib/utils/calendar.h | 91 + src/libs/3rdparty/botan/src/lib/utils/charset.cpp | 283 + src/libs/3rdparty/botan/src/lib/utils/charset.h | 78 + src/libs/3rdparty/botan/src/lib/utils/codec_base.h | 165 + src/libs/3rdparty/botan/src/lib/utils/compiler.h | 203 + .../3rdparty/botan/src/lib/utils/cpuid/cpuid.cpp | 179 + .../3rdparty/botan/src/lib/utils/cpuid/cpuid.h | 327 + .../botan/src/lib/utils/cpuid/cpuid_arm.cpp | 214 + .../botan/src/lib/utils/cpuid/cpuid_ppc.cpp | 129 + .../botan/src/lib/utils/cpuid/cpuid_x86.cpp | 178 + .../3rdparty/botan/src/lib/utils/cpuid/info.txt | 7 + src/libs/3rdparty/botan/src/lib/utils/ct_utils.h | 208 + src/libs/3rdparty/botan/src/lib/utils/data_src.cpp | 214 + src/libs/3rdparty/botan/src/lib/utils/data_src.h | 181 + src/libs/3rdparty/botan/src/lib/utils/database.h | 74 + src/libs/3rdparty/botan/src/lib/utils/donna128.h | 143 + .../botan/src/lib/utils/dyn_load/dyn_load.cpp | 79 + .../botan/src/lib/utils/dyn_load/dyn_load.h | 68 + .../3rdparty/botan/src/lib/utils/dyn_load/info.txt | 17 + src/libs/3rdparty/botan/src/lib/utils/exceptn.cpp | 105 + src/libs/3rdparty/botan/src/lib/utils/exceptn.h | 230 + .../3rdparty/botan/src/lib/utils/filesystem.cpp | 204 + src/libs/3rdparty/botan/src/lib/utils/filesystem.h | 33 + src/libs/3rdparty/botan/src/lib/utils/info.txt | 42 + src/libs/3rdparty/botan/src/lib/utils/loadstor.h | 697 + src/libs/3rdparty/botan/src/lib/utils/mem_ops.cpp | 63 + src/libs/3rdparty/botan/src/lib/utils/mem_ops.h | 272 + src/libs/3rdparty/botan/src/lib/utils/mul128.h | 123 + src/libs/3rdparty/botan/src/lib/utils/mutex.h | 58 + src/libs/3rdparty/botan/src/lib/utils/os_utils.cpp | 448 + src/libs/3rdparty/botan/src/lib/utils/os_utils.h | 118 + src/libs/3rdparty/botan/src/lib/utils/parsing.cpp | 477 + src/libs/3rdparty/botan/src/lib/utils/parsing.h | 153 + src/libs/3rdparty/botan/src/lib/utils/prefetch.h | 39 + src/libs/3rdparty/botan/src/lib/utils/read_cfg.cpp | 63 + src/libs/3rdparty/botan/src/lib/utils/rotate.h | 104 + src/libs/3rdparty/botan/src/lib/utils/rounding.h | 59 + src/libs/3rdparty/botan/src/lib/utils/safeint.h | 39 + .../3rdparty/botan/src/lib/utils/simd/info.txt | 7 + .../3rdparty/botan/src/lib/utils/simd/simd_32.h | 699 + .../botan/src/lib/utils/stl_compatibility.h | 77 + src/libs/3rdparty/botan/src/lib/utils/stl_util.h | 110 + src/libs/3rdparty/botan/src/lib/utils/types.h | 109 + src/libs/3rdparty/botan/src/lib/utils/version.cpp | 92 + src/libs/3rdparty/botan/src/lib/utils/version.h | 101 + .../3rdparty/botan/src/lib/x509/asn1_alt_name.cpp | 248 + .../3rdparty/botan/src/lib/x509/asn1_alt_name.h | 60 + .../3rdparty/botan/src/lib/x509/cert_status.cpp | 122 + src/libs/3rdparty/botan/src/lib/x509/cert_status.h | 99 + src/libs/3rdparty/botan/src/lib/x509/certstor.cpp | 216 + src/libs/3rdparty/botan/src/lib/x509/certstor.h | 163 + src/libs/3rdparty/botan/src/lib/x509/crl_ent.cpp | 140 + src/libs/3rdparty/botan/src/lib/x509/crl_ent.h | 104 + src/libs/3rdparty/botan/src/lib/x509/datastor.cpp | 205 + src/libs/3rdparty/botan/src/lib/x509/datastor.h | 84 + src/libs/3rdparty/botan/src/lib/x509/info.txt | 11 + .../3rdparty/botan/src/lib/x509/key_constraint.cpp | 100 + .../3rdparty/botan/src/lib/x509/key_constraint.h | 49 + .../botan/src/lib/x509/name_constraint.cpp | 269 + .../3rdparty/botan/src/lib/x509/name_constraint.h | 182 + src/libs/3rdparty/botan/src/lib/x509/ocsp.cpp | 354 + src/libs/3rdparty/botan/src/lib/x509/ocsp.h | 212 + .../3rdparty/botan/src/lib/x509/ocsp_types.cpp | 105 + src/libs/3rdparty/botan/src/lib/x509/ocsp_types.h | 68 + src/libs/3rdparty/botan/src/lib/x509/pkcs10.cpp | 314 + src/libs/3rdparty/botan/src/lib/x509/pkcs10.h | 148 + src/libs/3rdparty/botan/src/lib/x509/x509_ca.cpp | 338 + src/libs/3rdparty/botan/src/lib/x509/x509_ca.h | 262 + src/libs/3rdparty/botan/src/lib/x509/x509_crl.cpp | 268 + src/libs/3rdparty/botan/src/lib/x509/x509_crl.h | 141 + src/libs/3rdparty/botan/src/lib/x509/x509_dn.cpp | 382 + src/libs/3rdparty/botan/src/lib/x509/x509_dn.h | 97 + .../3rdparty/botan/src/lib/x509/x509_dn_ub.cpp | 58 + src/libs/3rdparty/botan/src/lib/x509/x509_ext.cpp | 1000 + src/libs/3rdparty/botan/src/lib/x509/x509_ext.h | 790 + src/libs/3rdparty/botan/src/lib/x509/x509_obj.cpp | 379 + src/libs/3rdparty/botan/src/lib/x509/x509_obj.h | 145 + src/libs/3rdparty/botan/src/lib/x509/x509cert.cpp | 879 + src/libs/3rdparty/botan/src/lib/x509/x509cert.h | 464 + src/libs/3rdparty/botan/src/lib/x509/x509opt.cpp | 101 + src/libs/3rdparty/botan/src/lib/x509/x509path.cpp | 1070 + src/libs/3rdparty/botan/src/lib/x509/x509path.h | 454 + src/libs/3rdparty/botan/src/lib/x509/x509self.cpp | 147 + src/libs/3rdparty/botan/src/lib/x509/x509self.h | 215 + src/libs/botan/botan.pri | 5 + src/libs/botan/botan.pro | 55 + src/libs/botan/botan.qbs | 112 + src/libs/botan/botan_dependencies.pri | 0 src/libs/botan/update-botan.sh | 62 + src/libs/libs.pro | 6 +- src/libs/libs.qbs | 1 + src/libs/ssh/ssh.pro | 14 +- src/libs/ssh/ssh.qbs | 76 +- src/libs/ssh/sshbotanconversions_p.h | 16 +- src/libs/ssh/sshchannel.cpp | 2 - src/libs/ssh/sshconnection.cpp | 14 +- src/libs/ssh/sshcryptofacility.cpp | 44 +- src/libs/ssh/sshcryptofacility_p.h | 8 +- src/libs/ssh/sshinit.cpp | 49 - src/libs/ssh/sshinit_p.h | 32 - src/libs/ssh/sshkeyexchange.cpp | 30 +- src/libs/ssh/sshkeyexchange_p.h | 6 +- src/libs/ssh/sshkeygenerator.cpp | 22 +- src/libs/ssh/sshkeypasswordretriever.cpp | 8 +- src/libs/ssh/sshkeypasswordretriever_p.h | 9 +- src/libs/ssh/sshpacketparser_p.h | 2 +- src/libs/ssh/sshremoteprocess.cpp | 2 - 501 files changed, 75446 insertions(+), 65031 deletions(-) create mode 100644 src/libs/3rdparty/botan/.gitignore create mode 120000 src/libs/3rdparty/botan/.travis.yml delete mode 100644 src/libs/3rdparty/botan/botan.cpp delete mode 100644 src/libs/3rdparty/botan/botan.h delete mode 100644 src/libs/3rdparty/botan/botan.pri mode change 100644 => 100755 src/libs/3rdparty/botan/configure.py delete mode 100644 src/libs/3rdparty/botan/doc/license.txt create mode 100644 src/libs/3rdparty/botan/license.txt create mode 100644 src/libs/3rdparty/botan/readme.rst delete mode 100644 src/libs/3rdparty/botan/readme.txt create mode 100644 src/libs/3rdparty/botan/src/build-data/arch/alpha.txt create mode 100644 src/libs/3rdparty/botan/src/build-data/arch/arm32.txt create mode 100644 src/libs/3rdparty/botan/src/build-data/arch/arm64.txt create mode 100644 src/libs/3rdparty/botan/src/build-data/arch/hppa.txt create mode 100644 src/libs/3rdparty/botan/src/build-data/arch/ia64.txt create mode 100644 src/libs/3rdparty/botan/src/build-data/arch/llvm.txt create mode 100644 src/libs/3rdparty/botan/src/build-data/arch/m68k.txt create mode 100644 src/libs/3rdparty/botan/src/build-data/arch/mips32.txt create mode 100644 src/libs/3rdparty/botan/src/build-data/arch/mips64.txt create mode 100644 src/libs/3rdparty/botan/src/build-data/arch/powerpcspe.txt create mode 100644 src/libs/3rdparty/botan/src/build-data/arch/ppc32.txt create mode 100644 src/libs/3rdparty/botan/src/build-data/arch/ppc64.txt create mode 100644 src/libs/3rdparty/botan/src/build-data/arch/riscv64.txt create mode 100644 src/libs/3rdparty/botan/src/build-data/arch/s390.txt create mode 100644 src/libs/3rdparty/botan/src/build-data/arch/s390x.txt create mode 100644 src/libs/3rdparty/botan/src/build-data/arch/sparc32.txt create mode 100644 src/libs/3rdparty/botan/src/build-data/arch/sparc64.txt create mode 100644 src/libs/3rdparty/botan/src/build-data/arch/superh.txt create mode 100644 src/libs/3rdparty/botan/src/build-data/arch/x32.txt create mode 100644 src/libs/3rdparty/botan/src/build-data/arch/x86_32.txt create mode 100644 src/libs/3rdparty/botan/src/build-data/arch/x86_64.txt create mode 100644 src/libs/3rdparty/botan/src/build-data/bakefile.in create mode 100644 src/libs/3rdparty/botan/src/build-data/botan.doxy.in create mode 100644 src/libs/3rdparty/botan/src/build-data/botan.pc.in create mode 100644 src/libs/3rdparty/botan/src/build-data/buildh.in create mode 100644 src/libs/3rdparty/botan/src/build-data/cc/clang.txt create mode 100644 src/libs/3rdparty/botan/src/build-data/cc/ekopath.txt create mode 100644 src/libs/3rdparty/botan/src/build-data/cc/gcc.txt create mode 100644 src/libs/3rdparty/botan/src/build-data/cc/hpcc.txt create mode 100644 src/libs/3rdparty/botan/src/build-data/cc/icc.txt create mode 100644 src/libs/3rdparty/botan/src/build-data/cc/msvc.txt create mode 100644 src/libs/3rdparty/botan/src/build-data/cc/pgi.txt create mode 100644 src/libs/3rdparty/botan/src/build-data/cc/sunstudio.txt create mode 100644 src/libs/3rdparty/botan/src/build-data/cc/xlc.txt create mode 100644 src/libs/3rdparty/botan/src/build-data/cmake.in create mode 100644 src/libs/3rdparty/botan/src/build-data/detect_arch.cpp create mode 100644 src/libs/3rdparty/botan/src/build-data/detect_version.cpp create mode 100644 src/libs/3rdparty/botan/src/build-data/innosetup.in create mode 100644 src/libs/3rdparty/botan/src/build-data/makefile.in create mode 100644 src/libs/3rdparty/botan/src/build-data/oids.txt create mode 100644 src/libs/3rdparty/botan/src/build-data/os/aix.txt create mode 100644 src/libs/3rdparty/botan/src/build-data/os/android.txt create mode 100644 src/libs/3rdparty/botan/src/build-data/os/cygwin.txt create mode 100644 src/libs/3rdparty/botan/src/build-data/os/darwin.txt create mode 100644 src/libs/3rdparty/botan/src/build-data/os/dragonfly.txt create mode 100644 src/libs/3rdparty/botan/src/build-data/os/freebsd.txt create mode 100644 src/libs/3rdparty/botan/src/build-data/os/haiku.txt create mode 100644 src/libs/3rdparty/botan/src/build-data/os/hpux.txt create mode 100644 src/libs/3rdparty/botan/src/build-data/os/hurd.txt create mode 100644 src/libs/3rdparty/botan/src/build-data/os/includeos.txt create mode 100644 src/libs/3rdparty/botan/src/build-data/os/ios.txt create mode 100644 src/libs/3rdparty/botan/src/build-data/os/linux.txt create mode 100644 src/libs/3rdparty/botan/src/build-data/os/llvm.txt create mode 100644 src/libs/3rdparty/botan/src/build-data/os/mingw.txt create mode 100644 src/libs/3rdparty/botan/src/build-data/os/nacl.txt create mode 100644 src/libs/3rdparty/botan/src/build-data/os/netbsd.txt create mode 100644 src/libs/3rdparty/botan/src/build-data/os/openbsd.txt create mode 100644 src/libs/3rdparty/botan/src/build-data/os/qnx.txt create mode 100644 src/libs/3rdparty/botan/src/build-data/os/solaris.txt create mode 100644 src/libs/3rdparty/botan/src/build-data/os/uwp.txt create mode 100644 src/libs/3rdparty/botan/src/build-data/os/windows.txt create mode 100644 src/libs/3rdparty/botan/src/build-data/version.txt create mode 100644 src/libs/3rdparty/botan/src/lib/asn1/alg_id.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/asn1/alg_id.h create mode 100644 src/libs/3rdparty/botan/src/lib/asn1/asn1_attribute.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/asn1/asn1_attribute.h create mode 100644 src/libs/3rdparty/botan/src/lib/asn1/asn1_obj.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/asn1/asn1_obj.h create mode 100644 src/libs/3rdparty/botan/src/lib/asn1/asn1_oid.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/asn1/asn1_oid.h create mode 100644 src/libs/3rdparty/botan/src/lib/asn1/asn1_print.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/asn1/asn1_print.h create mode 100644 src/libs/3rdparty/botan/src/lib/asn1/asn1_str.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/asn1/asn1_str.h create mode 100644 src/libs/3rdparty/botan/src/lib/asn1/asn1_time.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/asn1/asn1_time.h create mode 100644 src/libs/3rdparty/botan/src/lib/asn1/ber_dec.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/asn1/ber_dec.h create mode 100644 src/libs/3rdparty/botan/src/lib/asn1/der_enc.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/asn1/der_enc.h create mode 100644 src/libs/3rdparty/botan/src/lib/asn1/info.txt create mode 100644 src/libs/3rdparty/botan/src/lib/asn1/oid_maps.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/asn1/oids.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/asn1/oids.h create mode 100644 src/libs/3rdparty/botan/src/lib/base/botan.h create mode 100644 src/libs/3rdparty/botan/src/lib/base/buf_comp.h create mode 100644 src/libs/3rdparty/botan/src/lib/base/info.txt create mode 100644 src/libs/3rdparty/botan/src/lib/base/init.h create mode 100644 src/libs/3rdparty/botan/src/lib/base/key_spec.h create mode 100644 src/libs/3rdparty/botan/src/lib/base/lookup.h create mode 100644 src/libs/3rdparty/botan/src/lib/base/scan_name.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/base/scan_name.h create mode 100644 src/libs/3rdparty/botan/src/lib/base/secmem.h create mode 100644 src/libs/3rdparty/botan/src/lib/base/sym_algo.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/base/sym_algo.h create mode 100644 src/libs/3rdparty/botan/src/lib/base/symkey.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/base/symkey.h create mode 100644 src/libs/3rdparty/botan/src/lib/block/aes/aes.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/block/aes/aes.h create mode 100644 src/libs/3rdparty/botan/src/lib/block/aes/aes_armv8/aes_armv8.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/block/aes/aes_armv8/info.txt create mode 100644 src/libs/3rdparty/botan/src/lib/block/aes/aes_ni/aes_ni.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/block/aes/aes_ni/info.txt create mode 100644 src/libs/3rdparty/botan/src/lib/block/aes/aes_power8/aes_power8.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/block/aes/aes_power8/info.txt create mode 100644 src/libs/3rdparty/botan/src/lib/block/aes/aes_ssse3/aes_ssse3.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/block/aes/aes_ssse3/info.txt create mode 100644 src/libs/3rdparty/botan/src/lib/block/aes/info.txt create mode 100644 src/libs/3rdparty/botan/src/lib/block/block_cipher.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/block/block_cipher.h create mode 100644 src/libs/3rdparty/botan/src/lib/block/des/des.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/block/des/des.h create mode 100644 src/libs/3rdparty/botan/src/lib/block/des/des_tab.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/block/des/desx.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/block/des/desx.h create mode 100644 src/libs/3rdparty/botan/src/lib/block/des/info.txt create mode 100644 src/libs/3rdparty/botan/src/lib/block/info.txt create mode 100644 src/libs/3rdparty/botan/src/lib/codec/base64/base64.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/codec/base64/base64.h create mode 100644 src/libs/3rdparty/botan/src/lib/codec/base64/info.txt create mode 100644 src/libs/3rdparty/botan/src/lib/codec/hex/hex.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/codec/hex/hex.h create mode 100644 src/libs/3rdparty/botan/src/lib/codec/hex/info.txt create mode 100644 src/libs/3rdparty/botan/src/lib/entropy/darwin_secrandom/darwin_secrandom.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/entropy/darwin_secrandom/darwin_secrandom.h create mode 100644 src/libs/3rdparty/botan/src/lib/entropy/darwin_secrandom/info.txt create mode 100644 src/libs/3rdparty/botan/src/lib/entropy/dev_random/dev_random.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/entropy/dev_random/dev_random.h create mode 100644 src/libs/3rdparty/botan/src/lib/entropy/dev_random/info.txt create mode 100644 src/libs/3rdparty/botan/src/lib/entropy/entropy_src.h create mode 100644 src/libs/3rdparty/botan/src/lib/entropy/entropy_srcs.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/entropy/getentropy/getentropy.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/entropy/getentropy/getentropy.h create mode 100644 src/libs/3rdparty/botan/src/lib/entropy/getentropy/info.txt create mode 100644 src/libs/3rdparty/botan/src/lib/entropy/info.txt create mode 100644 src/libs/3rdparty/botan/src/lib/entropy/proc_walk/info.txt create mode 100644 src/libs/3rdparty/botan/src/lib/entropy/proc_walk/proc_walk.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/entropy/proc_walk/proc_walk.h create mode 100644 src/libs/3rdparty/botan/src/lib/entropy/rdrand/info.txt create mode 100644 src/libs/3rdparty/botan/src/lib/entropy/rdrand/rdrand.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/entropy/rdrand/rdrand.h create mode 100644 src/libs/3rdparty/botan/src/lib/entropy/rdseed/info.txt create mode 100644 src/libs/3rdparty/botan/src/lib/entropy/rdseed/rdseed.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/entropy/rdseed/rdseed.h create mode 100644 src/libs/3rdparty/botan/src/lib/entropy/win32_stats/es_win32.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/entropy/win32_stats/es_win32.h create mode 100644 src/libs/3rdparty/botan/src/lib/entropy/win32_stats/info.txt create mode 100644 src/libs/3rdparty/botan/src/lib/filters/aead_filt.h create mode 100644 src/libs/3rdparty/botan/src/lib/filters/algo_filt.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/filters/basefilt.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/filters/basefilt.h create mode 100644 src/libs/3rdparty/botan/src/lib/filters/buf_filt.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/filters/buf_filt.h create mode 100644 src/libs/3rdparty/botan/src/lib/filters/cipher_filter.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/filters/cipher_filter.h create mode 100644 src/libs/3rdparty/botan/src/lib/filters/comp_filter.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/filters/comp_filter.h create mode 100644 src/libs/3rdparty/botan/src/lib/filters/data_snk.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/filters/data_snk.h create mode 100644 src/libs/3rdparty/botan/src/lib/filters/filter.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/filters/filter.h create mode 100644 src/libs/3rdparty/botan/src/lib/filters/filters.h create mode 100644 src/libs/3rdparty/botan/src/lib/filters/info.txt create mode 100644 src/libs/3rdparty/botan/src/lib/filters/key_filt.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/filters/key_filt.h create mode 100644 src/libs/3rdparty/botan/src/lib/filters/out_buf.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/filters/out_buf.h create mode 100644 src/libs/3rdparty/botan/src/lib/filters/pipe.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/filters/pipe.h create mode 100644 src/libs/3rdparty/botan/src/lib/filters/pipe_io.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/filters/pipe_rw.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/filters/secqueue.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/filters/secqueue.h create mode 100644 src/libs/3rdparty/botan/src/lib/filters/threaded_fork.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/hash/hash.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/hash/hash.h create mode 100644 src/libs/3rdparty/botan/src/lib/hash/info.txt create mode 100644 src/libs/3rdparty/botan/src/lib/hash/mdx_hash/info.txt create mode 100644 src/libs/3rdparty/botan/src/lib/hash/mdx_hash/mdx_hash.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/hash/mdx_hash/mdx_hash.h create mode 100644 src/libs/3rdparty/botan/src/lib/hash/sha1/info.txt create mode 100644 src/libs/3rdparty/botan/src/lib/hash/sha1/sha160.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/hash/sha1/sha160.h create mode 100644 src/libs/3rdparty/botan/src/lib/hash/sha1/sha1_armv8/info.txt create mode 100644 src/libs/3rdparty/botan/src/lib/hash/sha1/sha1_armv8/sha1_armv8.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/hash/sha1/sha1_sse2/info.txt create mode 100644 src/libs/3rdparty/botan/src/lib/hash/sha1/sha1_sse2/sha1_sse2.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/hash/sha1/sha1_x86/info.txt create mode 100644 src/libs/3rdparty/botan/src/lib/hash/sha1/sha1_x86/sha1_x86.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/hash/sha2_32/info.txt create mode 100644 src/libs/3rdparty/botan/src/lib/hash/sha2_32/sha2_32.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/hash/sha2_32/sha2_32.h create mode 100644 src/libs/3rdparty/botan/src/lib/hash/sha2_32/sha2_32_armv8/info.txt create mode 100644 src/libs/3rdparty/botan/src/lib/hash/sha2_32/sha2_32_armv8/sha2_32_armv8.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/hash/sha2_32/sha2_32_bmi2/info.txt create mode 100644 src/libs/3rdparty/botan/src/lib/hash/sha2_32/sha2_32_bmi2/sha2_32_bmi2.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/hash/sha2_32/sha2_32_x86/info.txt create mode 100644 src/libs/3rdparty/botan/src/lib/hash/sha2_32/sha2_32_x86/sha2_32_x86.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/hash/sha2_64/info.txt create mode 100644 src/libs/3rdparty/botan/src/lib/hash/sha2_64/sha2_64.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/hash/sha2_64/sha2_64.h create mode 100644 src/libs/3rdparty/botan/src/lib/kdf/info.txt create mode 100644 src/libs/3rdparty/botan/src/lib/kdf/kdf.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/kdf/kdf.h create mode 100644 src/libs/3rdparty/botan/src/lib/mac/hmac/hmac.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/mac/hmac/hmac.h create mode 100644 src/libs/3rdparty/botan/src/lib/mac/hmac/info.txt create mode 100644 src/libs/3rdparty/botan/src/lib/mac/info.txt create mode 100644 src/libs/3rdparty/botan/src/lib/mac/mac.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/mac/mac.h create mode 100644 src/libs/3rdparty/botan/src/lib/math/bigint/big_code.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/math/bigint/big_io.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/math/bigint/big_ops2.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/math/bigint/big_ops3.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/math/bigint/big_rand.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/math/bigint/bigint.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/math/bigint/bigint.h create mode 100644 src/libs/3rdparty/botan/src/lib/math/bigint/divide.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/math/bigint/divide.h create mode 100644 src/libs/3rdparty/botan/src/lib/math/bigint/info.txt create mode 100644 src/libs/3rdparty/botan/src/lib/math/mp/info.txt create mode 100644 src/libs/3rdparty/botan/src/lib/math/mp/mp_asmi.h create mode 100644 src/libs/3rdparty/botan/src/lib/math/mp/mp_comba.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/math/mp/mp_core.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/math/mp/mp_core.h create mode 100644 src/libs/3rdparty/botan/src/lib/math/mp/mp_karat.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/math/mp/mp_madd.h create mode 100644 src/libs/3rdparty/botan/src/lib/math/mp/mp_monty.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/math/mp/mp_monty.h create mode 100644 src/libs/3rdparty/botan/src/lib/math/mp/mp_monty_n.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/math/numbertheory/curve_nistp.h create mode 100644 src/libs/3rdparty/botan/src/lib/math/numbertheory/def_powm.h create mode 100644 src/libs/3rdparty/botan/src/lib/math/numbertheory/dsa_gen.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/math/numbertheory/info.txt create mode 100644 src/libs/3rdparty/botan/src/lib/math/numbertheory/jacobi.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/math/numbertheory/make_prm.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/math/numbertheory/monty.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/math/numbertheory/monty.h create mode 100644 src/libs/3rdparty/botan/src/lib/math/numbertheory/monty_exp.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/math/numbertheory/monty_exp.h create mode 100644 src/libs/3rdparty/botan/src/lib/math/numbertheory/mp_numth.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/math/numbertheory/nistp_redc.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/math/numbertheory/numthry.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/math/numbertheory/numthry.h create mode 100644 src/libs/3rdparty/botan/src/lib/math/numbertheory/pow_mod.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/math/numbertheory/pow_mod.h create mode 100644 src/libs/3rdparty/botan/src/lib/math/numbertheory/powm_fw.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/math/numbertheory/powm_mnt.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/math/numbertheory/primes.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/math/numbertheory/reducer.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/math/numbertheory/reducer.h create mode 100644 src/libs/3rdparty/botan/src/lib/math/numbertheory/ressol.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/modes/cbc/cbc.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/modes/cbc/cbc.h create mode 100644 src/libs/3rdparty/botan/src/lib/modes/cbc/info.txt create mode 100644 src/libs/3rdparty/botan/src/lib/modes/cipher_mode.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/modes/cipher_mode.h create mode 100644 src/libs/3rdparty/botan/src/lib/modes/info.txt create mode 100644 src/libs/3rdparty/botan/src/lib/modes/mode_pad/info.txt create mode 100644 src/libs/3rdparty/botan/src/lib/modes/mode_pad/mode_pad.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/modes/mode_pad/mode_pad.h create mode 100644 src/libs/3rdparty/botan/src/lib/modes/stream_mode.h create mode 100644 src/libs/3rdparty/botan/src/lib/pbkdf/info.txt create mode 100644 src/libs/3rdparty/botan/src/lib/pbkdf/pbkdf.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/pbkdf/pbkdf.h create mode 100644 src/libs/3rdparty/botan/src/lib/pbkdf/pbkdf2/info.txt create mode 100644 src/libs/3rdparty/botan/src/lib/pbkdf/pbkdf2/pbkdf2.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/pbkdf/pbkdf2/pbkdf2.h create mode 100644 src/libs/3rdparty/botan/src/lib/pk_pad/eme.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/pk_pad/eme.h create mode 100644 src/libs/3rdparty/botan/src/lib/pk_pad/emsa.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/pk_pad/emsa.h create mode 100644 src/libs/3rdparty/botan/src/lib/pk_pad/emsa1/emsa1.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/pk_pad/emsa1/emsa1.h create mode 100644 src/libs/3rdparty/botan/src/lib/pk_pad/emsa1/info.txt create mode 100644 src/libs/3rdparty/botan/src/lib/pk_pad/emsa_pkcs1/emsa_pkcs1.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/pk_pad/emsa_pkcs1/emsa_pkcs1.h create mode 100644 src/libs/3rdparty/botan/src/lib/pk_pad/emsa_pkcs1/info.txt create mode 100644 src/libs/3rdparty/botan/src/lib/pk_pad/emsa_pssr/info.txt create mode 100644 src/libs/3rdparty/botan/src/lib/pk_pad/emsa_pssr/pssr.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/pk_pad/emsa_pssr/pssr.h create mode 100644 src/libs/3rdparty/botan/src/lib/pk_pad/hash_id/hash_id.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/pk_pad/hash_id/hash_id.h create mode 100644 src/libs/3rdparty/botan/src/lib/pk_pad/hash_id/info.txt create mode 100644 src/libs/3rdparty/botan/src/lib/pk_pad/info.txt create mode 100644 src/libs/3rdparty/botan/src/lib/pk_pad/mgf1/info.txt create mode 100644 src/libs/3rdparty/botan/src/lib/pk_pad/mgf1/mgf1.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/pk_pad/mgf1/mgf1.h create mode 100644 src/libs/3rdparty/botan/src/lib/pk_pad/padding.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/pk_pad/padding.h create mode 100644 src/libs/3rdparty/botan/src/lib/pubkey/blinding.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/pubkey/blinding.h create mode 100644 src/libs/3rdparty/botan/src/lib/pubkey/dh/dh.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/pubkey/dh/dh.h create mode 100644 src/libs/3rdparty/botan/src/lib/pubkey/dh/info.txt create mode 100644 src/libs/3rdparty/botan/src/lib/pubkey/dl_algo/dl_algo.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/pubkey/dl_algo/dl_algo.h create mode 100644 src/libs/3rdparty/botan/src/lib/pubkey/dl_algo/info.txt create mode 100644 src/libs/3rdparty/botan/src/lib/pubkey/dl_group/dl_group.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/pubkey/dl_group/dl_group.h create mode 100644 src/libs/3rdparty/botan/src/lib/pubkey/dl_group/dl_named.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/pubkey/dl_group/info.txt create mode 100644 src/libs/3rdparty/botan/src/lib/pubkey/dsa/dsa.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/pubkey/dsa/dsa.h create mode 100644 src/libs/3rdparty/botan/src/lib/pubkey/dsa/info.txt create mode 100644 src/libs/3rdparty/botan/src/lib/pubkey/ec_group/curve_gfp.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/pubkey/ec_group/curve_gfp.h create mode 100644 src/libs/3rdparty/botan/src/lib/pubkey/ec_group/ec_group.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/pubkey/ec_group/ec_group.h create mode 100644 src/libs/3rdparty/botan/src/lib/pubkey/ec_group/ec_named.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/pubkey/ec_group/info.txt create mode 100644 src/libs/3rdparty/botan/src/lib/pubkey/ec_group/point_gfp.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/pubkey/ec_group/point_gfp.h create mode 100644 src/libs/3rdparty/botan/src/lib/pubkey/ec_group/point_mul.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/pubkey/ec_group/point_mul.h create mode 100644 src/libs/3rdparty/botan/src/lib/pubkey/ecc_key/ecc_key.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/pubkey/ecc_key/ecc_key.h create mode 100644 src/libs/3rdparty/botan/src/lib/pubkey/ecc_key/info.txt create mode 100644 src/libs/3rdparty/botan/src/lib/pubkey/ecdh/ecdh.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/pubkey/ecdh/ecdh.h create mode 100644 src/libs/3rdparty/botan/src/lib/pubkey/ecdh/info.txt create mode 100644 src/libs/3rdparty/botan/src/lib/pubkey/ecdsa/ecdsa.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/pubkey/ecdsa/ecdsa.h create mode 100644 src/libs/3rdparty/botan/src/lib/pubkey/ecdsa/info.txt create mode 100644 src/libs/3rdparty/botan/src/lib/pubkey/info.txt create mode 100644 src/libs/3rdparty/botan/src/lib/pubkey/keypair/info.txt create mode 100644 src/libs/3rdparty/botan/src/lib/pubkey/keypair/keypair.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/pubkey/keypair/keypair.h create mode 100644 src/libs/3rdparty/botan/src/lib/pubkey/pbes2/info.txt create mode 100644 src/libs/3rdparty/botan/src/lib/pubkey/pbes2/pbes2.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/pubkey/pbes2/pbes2.h create mode 100644 src/libs/3rdparty/botan/src/lib/pubkey/pem/info.txt create mode 100644 src/libs/3rdparty/botan/src/lib/pubkey/pem/pem.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/pubkey/pem/pem.h create mode 100644 src/libs/3rdparty/botan/src/lib/pubkey/pk_algs.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/pubkey/pk_algs.h create mode 100644 src/libs/3rdparty/botan/src/lib/pubkey/pk_keys.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/pubkey/pk_keys.h create mode 100644 src/libs/3rdparty/botan/src/lib/pubkey/pk_ops.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/pubkey/pk_ops.h create mode 100644 src/libs/3rdparty/botan/src/lib/pubkey/pk_ops_fwd.h create mode 100644 src/libs/3rdparty/botan/src/lib/pubkey/pk_ops_impl.h create mode 100644 src/libs/3rdparty/botan/src/lib/pubkey/pkcs8.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/pubkey/pkcs8.h create mode 100644 src/libs/3rdparty/botan/src/lib/pubkey/pubkey.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/pubkey/pubkey.h create mode 100644 src/libs/3rdparty/botan/src/lib/pubkey/rsa/info.txt create mode 100644 src/libs/3rdparty/botan/src/lib/pubkey/rsa/rsa.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/pubkey/rsa/rsa.h create mode 100644 src/libs/3rdparty/botan/src/lib/pubkey/workfactor.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/pubkey/workfactor.h create mode 100644 src/libs/3rdparty/botan/src/lib/pubkey/x509_key.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/pubkey/x509_key.h create mode 100644 src/libs/3rdparty/botan/src/lib/rng/auto_rng/auto_rng.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/rng/auto_rng/auto_rng.h create mode 100644 src/libs/3rdparty/botan/src/lib/rng/auto_rng/info.txt create mode 100644 src/libs/3rdparty/botan/src/lib/rng/hmac_drbg/hmac_drbg.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/rng/hmac_drbg/hmac_drbg.h create mode 100644 src/libs/3rdparty/botan/src/lib/rng/hmac_drbg/info.txt create mode 100644 src/libs/3rdparty/botan/src/lib/rng/info.txt create mode 100644 src/libs/3rdparty/botan/src/lib/rng/rdrand_rng/info.txt create mode 100644 src/libs/3rdparty/botan/src/lib/rng/rdrand_rng/rdrand_rng.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/rng/rdrand_rng/rdrand_rng.h create mode 100644 src/libs/3rdparty/botan/src/lib/rng/rng.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/rng/rng.h create mode 100644 src/libs/3rdparty/botan/src/lib/rng/stateful_rng/info.txt create mode 100644 src/libs/3rdparty/botan/src/lib/rng/stateful_rng/stateful_rng.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/rng/stateful_rng/stateful_rng.h create mode 100644 src/libs/3rdparty/botan/src/lib/rng/system_rng/info.txt create mode 100644 src/libs/3rdparty/botan/src/lib/rng/system_rng/system_rng.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/rng/system_rng/system_rng.h create mode 100644 src/libs/3rdparty/botan/src/lib/stream/ctr/ctr.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/stream/ctr/ctr.h create mode 100644 src/libs/3rdparty/botan/src/lib/stream/ctr/info.txt create mode 100644 src/libs/3rdparty/botan/src/lib/stream/info.txt create mode 100644 src/libs/3rdparty/botan/src/lib/stream/stream_cipher.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/stream/stream_cipher.h create mode 100644 src/libs/3rdparty/botan/src/lib/utils/assert.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/utils/assert.h create mode 100644 src/libs/3rdparty/botan/src/lib/utils/bit_ops.h create mode 100644 src/libs/3rdparty/botan/src/lib/utils/bswap.h create mode 100644 src/libs/3rdparty/botan/src/lib/utils/calendar.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/utils/calendar.h create mode 100644 src/libs/3rdparty/botan/src/lib/utils/charset.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/utils/charset.h create mode 100644 src/libs/3rdparty/botan/src/lib/utils/codec_base.h create mode 100644 src/libs/3rdparty/botan/src/lib/utils/compiler.h create mode 100644 src/libs/3rdparty/botan/src/lib/utils/cpuid/cpuid.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/utils/cpuid/cpuid.h create mode 100644 src/libs/3rdparty/botan/src/lib/utils/cpuid/cpuid_arm.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/utils/cpuid/cpuid_ppc.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/utils/cpuid/cpuid_x86.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/utils/cpuid/info.txt create mode 100644 src/libs/3rdparty/botan/src/lib/utils/ct_utils.h create mode 100644 src/libs/3rdparty/botan/src/lib/utils/data_src.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/utils/data_src.h create mode 100644 src/libs/3rdparty/botan/src/lib/utils/database.h create mode 100644 src/libs/3rdparty/botan/src/lib/utils/donna128.h create mode 100644 src/libs/3rdparty/botan/src/lib/utils/dyn_load/dyn_load.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/utils/dyn_load/dyn_load.h create mode 100644 src/libs/3rdparty/botan/src/lib/utils/dyn_load/info.txt create mode 100644 src/libs/3rdparty/botan/src/lib/utils/exceptn.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/utils/exceptn.h create mode 100644 src/libs/3rdparty/botan/src/lib/utils/filesystem.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/utils/filesystem.h create mode 100644 src/libs/3rdparty/botan/src/lib/utils/info.txt create mode 100644 src/libs/3rdparty/botan/src/lib/utils/loadstor.h create mode 100644 src/libs/3rdparty/botan/src/lib/utils/mem_ops.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/utils/mem_ops.h create mode 100644 src/libs/3rdparty/botan/src/lib/utils/mul128.h create mode 100644 src/libs/3rdparty/botan/src/lib/utils/mutex.h create mode 100644 src/libs/3rdparty/botan/src/lib/utils/os_utils.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/utils/os_utils.h create mode 100644 src/libs/3rdparty/botan/src/lib/utils/parsing.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/utils/parsing.h create mode 100644 src/libs/3rdparty/botan/src/lib/utils/prefetch.h create mode 100644 src/libs/3rdparty/botan/src/lib/utils/read_cfg.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/utils/rotate.h create mode 100644 src/libs/3rdparty/botan/src/lib/utils/rounding.h create mode 100644 src/libs/3rdparty/botan/src/lib/utils/safeint.h create mode 100644 src/libs/3rdparty/botan/src/lib/utils/simd/info.txt create mode 100644 src/libs/3rdparty/botan/src/lib/utils/simd/simd_32.h create mode 100644 src/libs/3rdparty/botan/src/lib/utils/stl_compatibility.h create mode 100644 src/libs/3rdparty/botan/src/lib/utils/stl_util.h create mode 100644 src/libs/3rdparty/botan/src/lib/utils/types.h create mode 100644 src/libs/3rdparty/botan/src/lib/utils/version.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/utils/version.h create mode 100644 src/libs/3rdparty/botan/src/lib/x509/asn1_alt_name.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/x509/asn1_alt_name.h create mode 100644 src/libs/3rdparty/botan/src/lib/x509/cert_status.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/x509/cert_status.h create mode 100644 src/libs/3rdparty/botan/src/lib/x509/certstor.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/x509/certstor.h create mode 100644 src/libs/3rdparty/botan/src/lib/x509/crl_ent.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/x509/crl_ent.h create mode 100644 src/libs/3rdparty/botan/src/lib/x509/datastor.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/x509/datastor.h create mode 100644 src/libs/3rdparty/botan/src/lib/x509/info.txt create mode 100644 src/libs/3rdparty/botan/src/lib/x509/key_constraint.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/x509/key_constraint.h create mode 100644 src/libs/3rdparty/botan/src/lib/x509/name_constraint.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/x509/name_constraint.h create mode 100644 src/libs/3rdparty/botan/src/lib/x509/ocsp.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/x509/ocsp.h create mode 100644 src/libs/3rdparty/botan/src/lib/x509/ocsp_types.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/x509/ocsp_types.h create mode 100644 src/libs/3rdparty/botan/src/lib/x509/pkcs10.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/x509/pkcs10.h create mode 100644 src/libs/3rdparty/botan/src/lib/x509/x509_ca.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/x509/x509_ca.h create mode 100644 src/libs/3rdparty/botan/src/lib/x509/x509_crl.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/x509/x509_crl.h create mode 100644 src/libs/3rdparty/botan/src/lib/x509/x509_dn.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/x509/x509_dn.h create mode 100644 src/libs/3rdparty/botan/src/lib/x509/x509_dn_ub.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/x509/x509_ext.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/x509/x509_ext.h create mode 100644 src/libs/3rdparty/botan/src/lib/x509/x509_obj.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/x509/x509_obj.h create mode 100644 src/libs/3rdparty/botan/src/lib/x509/x509cert.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/x509/x509cert.h create mode 100644 src/libs/3rdparty/botan/src/lib/x509/x509opt.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/x509/x509path.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/x509/x509path.h create mode 100644 src/libs/3rdparty/botan/src/lib/x509/x509self.cpp create mode 100644 src/libs/3rdparty/botan/src/lib/x509/x509self.h create mode 100644 src/libs/botan/botan.pri create mode 100644 src/libs/botan/botan.pro create mode 100644 src/libs/botan/botan.qbs create mode 100644 src/libs/botan/botan_dependencies.pri create mode 100644 src/libs/botan/update-botan.sh delete mode 100644 src/libs/ssh/sshinit.cpp delete mode 100644 src/libs/ssh/sshinit_p.h diff --git a/README.md b/README.md index f47c4a007c..cb49a7e024 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,7 @@ Prerequisites: * LLVM/Clang 6.0.0 or later (optional, needed for the Clang Code Model, see the section "Get LLVM/Clang for the Clang Code Model") * CMake (only for manual builds of LLVM/Clang) +* Python 2.6 or later (needed for building the bundled Botan library) * Qbs 1.7.x (optional, sources also contain Qbs itself) The installed toolchains have to match the one Qt was compiled with. diff --git a/qbs/modules/qtc/qtc.qbs b/qbs/modules/qtc/qtc.qbs index b7477f3888..9d739f926b 100644 --- a/qbs/modules/qtc/qtc.qbs +++ b/qbs/modules/qtc/qtc.qbs @@ -69,6 +69,7 @@ Module { property string export_data_base: project.ide_source_tree + "/share/qtcreator" property bool testsEnabled: Environment.getEnv("TEST") || qbs.buildVariant === "debug" + property bool useSystemBotan: Environment.getEnv("USE_SYSTEM_BOTAN") === "1" property stringList generalDefines: [ "QT_CREATOR", 'IDE_LIBRARY_BASENAME="' + libDirName + '"', diff --git a/src/libs/3rdparty/botan/.gitignore b/src/libs/3rdparty/botan/.gitignore new file mode 100644 index 0000000000..8c7a071b78 --- /dev/null +++ b/src/libs/3rdparty/botan/.gitignore @@ -0,0 +1,86 @@ +/Makefile +CMakeLists.txt* +libbotan*.so.* +*.a +*.so +*.dylib +*.exp +*.lib +*.pdb +*.ilk +*.dll +*.exe +*.manifest +build +build.log +botan +botan-test + +core.* +vgcore.* + +# Text file backups (e.g. gedit, joe) +*~ +\#*\# +.\#* + +# Archive files +*.tgz +*.tar + +# Logs +*.log + +# Patch files +*.patch +*.diff +*.orig +*.rej + +# Cache and temporary files +*.pyc +.DS_Store +*.swp + +# ctags/etags files +/TAGS +/tags + +# Amalgamation code +botan_all.h +botan_all_internal.h +botan_all.cpp +botan_all_*.cpp + +# Coverage output +coverage.info +coverage.info.raw +coverage/ +lcov-out/ + +/fuzzer_corpus + +# Profiler outputs +cachegrind.* +callgrind.* + +# Ignore stuff in the top level dir that shouldn't be checked in +/*.c +/*.cpp +/*.h +/*.py +/*.key +/*.pem +/*.der +/*.ber +/*.gpg +/*.pub +/*.crt +/*.txt +/*.rst + +# Add back files from the toplevel +!/news.rst +!/readme.rst +!/configure.py +!/license.txt diff --git a/src/libs/3rdparty/botan/.travis.yml b/src/libs/3rdparty/botan/.travis.yml new file mode 120000 index 0000000000..0a16c6e8f2 --- /dev/null +++ b/src/libs/3rdparty/botan/.travis.yml @@ -0,0 +1 @@ +src/scripts/ci/travis.yml \ No newline at end of file diff --git a/src/libs/3rdparty/botan/botan.cpp b/src/libs/3rdparty/botan/botan.cpp deleted file mode 100644 index 0d912062b3..0000000000 --- a/src/libs/3rdparty/botan/botan.cpp +++ /dev/null @@ -1,47194 +0,0 @@ -/* -* Botan 1.10.2 Amalgamation -* (C) 1999-2011 Jack Lloyd and others -* -* Distributed under the terms of the Botan license -*/ - -#include "botan.h" -#include - -#ifdef Q_OS_WIN -#ifndef NOMINMAX -#define NOMINMAX -#endif -#endif - - -namespace Botan { - -/** -* Represents a DLL or shared object -*/ -class Dynamically_Loaded_Library - { - public: - /** - * Load a DLL (or fail with an exception) - * @param lib_name name or path to a library - * - * If you don't use a full path, the search order will be defined - * by whatever the system linker does by default. Always using fully - * qualified pathnames can help prevent code injection attacks (eg - * via manipulation of LD_LIBRARY_PATH on Linux) - */ - Dynamically_Loaded_Library(const std::string& lib_name); - - /** - * Unload the DLL - * @warning Any pointers returned by resolve()/resolve_symbol() - * should not be used after this destructor runs. - */ - ~Dynamically_Loaded_Library(); - - /** - * Load a symbol (or fail with an exception) - * @param symbol names the symbol to load - * @return address of the loaded symbol - */ - void* resolve_symbol(const std::string& symbol); - - /** - * Convenience function for casting symbol to the right type - * @param symbol names the symbol to load - * @return address of the loaded symbol - */ - template - T resolve(const std::string& symbol) - { -#if defined(__GNUC__) && __GNUC__ < 4 - return (T)(resolve_symbol(symbol)); -#else - return reinterpret_cast(resolve_symbol(symbol)); -#endif - } - - private: - Dynamically_Loaded_Library(const Dynamically_Loaded_Library&); - Dynamically_Loaded_Library& operator=(const Dynamically_Loaded_Library&); - - std::string lib_name; - void* lib; - }; - -} - -#ifdef Q_OS_WIN -namespace Botan { - -/** -* Win32 Entropy Source -*/ -class Win32_EntropySource : public EntropySource - { - public: - std::string name() const { return "Win32 Statistics"; } - void poll(Entropy_Accumulator& accum); - }; - -} -#endif - -namespace Botan { - -/** -* Fake SIMD, using plain scalar operations -* Often still faster than iterative on superscalar machines -*/ -class SIMD_Scalar - { - public: - static bool enabled() { return true; } - - SIMD_Scalar(const u32bit B[4]) - { - R0 = B[0]; - R1 = B[1]; - R2 = B[2]; - R3 = B[3]; - } - - SIMD_Scalar(u32bit B0, u32bit B1, u32bit B2, u32bit B3) - { - R0 = B0; - R1 = B1; - R2 = B2; - R3 = B3; - } - - SIMD_Scalar(u32bit B) - { - R0 = B; - R1 = B; - R2 = B; - R3 = B; - } - - static SIMD_Scalar load_le(const void* in) - { - const byte* in_b = static_cast(in); - return SIMD_Scalar(Botan::load_le(in_b, 0), - Botan::load_le(in_b, 1), - Botan::load_le(in_b, 2), - Botan::load_le(in_b, 3)); - } - - static SIMD_Scalar load_be(const void* in) - { - const byte* in_b = static_cast(in); - return SIMD_Scalar(Botan::load_be(in_b, 0), - Botan::load_be(in_b, 1), - Botan::load_be(in_b, 2), - Botan::load_be(in_b, 3)); - } - - void store_le(byte out[]) const - { - Botan::store_le(out, R0, R1, R2, R3); - } - - void store_be(byte out[]) const - { - Botan::store_be(out, R0, R1, R2, R3); - } - - void rotate_left(size_t rot) - { - R0 = Botan::rotate_left(R0, rot); - R1 = Botan::rotate_left(R1, rot); - R2 = Botan::rotate_left(R2, rot); - R3 = Botan::rotate_left(R3, rot); - } - - void rotate_right(size_t rot) - { - R0 = Botan::rotate_right(R0, rot); - R1 = Botan::rotate_right(R1, rot); - R2 = Botan::rotate_right(R2, rot); - R3 = Botan::rotate_right(R3, rot); - } - - void operator+=(const SIMD_Scalar& other) - { - R0 += other.R0; - R1 += other.R1; - R2 += other.R2; - R3 += other.R3; - } - - SIMD_Scalar operator+(const SIMD_Scalar& other) const - { - return SIMD_Scalar(R0 + other.R0, - R1 + other.R1, - R2 + other.R2, - R3 + other.R3); - } - - void operator-=(const SIMD_Scalar& other) - { - R0 -= other.R0; - R1 -= other.R1; - R2 -= other.R2; - R3 -= other.R3; - } - - SIMD_Scalar operator-(const SIMD_Scalar& other) const - { - return SIMD_Scalar(R0 - other.R0, - R1 - other.R1, - R2 - other.R2, - R3 - other.R3); - } - - void operator^=(const SIMD_Scalar& other) - { - R0 ^= other.R0; - R1 ^= other.R1; - R2 ^= other.R2; - R3 ^= other.R3; - } - - SIMD_Scalar operator^(const SIMD_Scalar& other) const - { - return SIMD_Scalar(R0 ^ other.R0, - R1 ^ other.R1, - R2 ^ other.R2, - R3 ^ other.R3); - } - - void operator|=(const SIMD_Scalar& other) - { - R0 |= other.R0; - R1 |= other.R1; - R2 |= other.R2; - R3 |= other.R3; - } - - SIMD_Scalar operator&(const SIMD_Scalar& other) - { - return SIMD_Scalar(R0 & other.R0, - R1 & other.R1, - R2 & other.R2, - R3 & other.R3); - } - - void operator&=(const SIMD_Scalar& other) - { - R0 &= other.R0; - R1 &= other.R1; - R2 &= other.R2; - R3 &= other.R3; - } - - SIMD_Scalar operator<<(size_t shift) const - { - return SIMD_Scalar(R0 << shift, - R1 << shift, - R2 << shift, - R3 << shift); - } - - SIMD_Scalar operator>>(size_t shift) const - { - return SIMD_Scalar(R0 >> shift, - R1 >> shift, - R2 >> shift, - R3 >> shift); - } - - SIMD_Scalar operator~() const - { - return SIMD_Scalar(~R0, ~R1, ~R2, ~R3); - } - - // (~reg) & other - SIMD_Scalar andc(const SIMD_Scalar& other) - { - return SIMD_Scalar(~R0 & other.R0, - ~R1 & other.R1, - ~R2 & other.R2, - ~R3 & other.R3); - } - - SIMD_Scalar bswap() const - { - return SIMD_Scalar(reverse_bytes(R0), - reverse_bytes(R1), - reverse_bytes(R2), - reverse_bytes(R3)); - } - - static void transpose(SIMD_Scalar& B0, SIMD_Scalar& B1, - SIMD_Scalar& B2, SIMD_Scalar& B3) - { - SIMD_Scalar T0(B0.R0, B1.R0, B2.R0, B3.R0); - SIMD_Scalar T1(B0.R1, B1.R1, B2.R1, B3.R1); - SIMD_Scalar T2(B0.R2, B1.R2, B2.R2, B3.R2); - SIMD_Scalar T3(B0.R3, B1.R3, B2.R3, B3.R3); - - B0 = T0; - B1 = T1; - B2 = T2; - B3 = T3; - } - - private: - u32bit R0, R1, R2, R3; - }; - -} - - -namespace Botan { - -/** -* XOR arrays. Postcondition out[i] = in[i] ^ out[i] forall i = 0...length -* @param out the input/output buffer -* @param in the read-only input buffer -* @param length the length of the buffers -*/ -inline void xor_buf(byte out[], const byte in[], size_t length) - { - while(length >= 8) - { -#if BOTAN_TARGET_UNALIGNED_MEMORY_ACCESS_OK - *reinterpret_cast(out) ^= *reinterpret_cast(in); -#else - out[0] ^= in[0]; out[1] ^= in[1]; - out[2] ^= in[2]; out[3] ^= in[3]; - out[4] ^= in[4]; out[5] ^= in[5]; - out[6] ^= in[6]; out[7] ^= in[7]; -#endif - - out += 8; in += 8; length -= 8; - } - - for(size_t i = 0; i != length; ++i) - out[i] ^= in[i]; - } - -/** -* XOR arrays. Postcondition out[i] = in[i] ^ in2[i] forall i = 0...length -* @param out the output buffer -* @param in the first input buffer -* @param in2 the second output buffer -* @param length the length of the three buffers -*/ -inline void xor_buf(byte out[], - const byte in[], - const byte in2[], - size_t length) - { - while(length >= 8) - { -#if BOTAN_TARGET_UNALIGNED_MEMORY_ACCESS_OK - *reinterpret_cast(out) = - *reinterpret_cast(in) ^ - *reinterpret_cast(in2); -#else - out[0] = in[0] ^ in2[0]; out[1] = in[1] ^ in2[1]; - out[2] = in[2] ^ in2[2]; out[3] = in[3] ^ in2[3]; - out[4] = in[4] ^ in2[4]; out[5] = in[5] ^ in2[5]; - out[6] = in[6] ^ in2[6]; out[7] = in[7] ^ in2[7]; -#endif - - in += 8; in2 += 8; out += 8; length -= 8; - } - - for(size_t i = 0; i != length; ++i) - out[i] = in[i] ^ in2[i]; - } - -} - - -namespace Botan { - -/** -* Mutex Base Class -*/ -class Mutex - { - public: - /** - * Lock the mutex - */ - virtual void lock() = 0; - - /** - * Unlock the mutex - */ - virtual void unlock() = 0; - virtual ~Mutex() Q_DECL_NOEXCEPT_EXPR(false) {} - }; - -/** -* Mutex Factory -*/ -class Mutex_Factory - { - public: - /** - * @return newly allocated mutex - */ - virtual Mutex* make() = 0; - - virtual ~Mutex_Factory() {} - }; - -/** -* Mutex Holding Class for RAII -*/ -class Mutex_Holder - { - public: - /** - * Hold onto a mutex until we leave scope - * @param m the mutex to lock - */ - Mutex_Holder(Mutex* m) : mux(m) - { - if(!mux) - throw Invalid_Argument("Mutex_Holder: Argument was NULL"); - mux->lock(); - } - - ~Mutex_Holder() { mux->unlock(); } - private: - Mutex* mux; - }; - -} - - -namespace Botan { - -/** -* Copy-on-Predicate Algorithm -* @param current the first iterator value -* @param end the final iterator value -* @param dest an output iterator -* @param copy_p the predicate -*/ -template -OutputIterator copy_if(InputIterator current, InputIterator end, - OutputIterator dest, Predicate copy_p) - { - while(current != end) - { - if(copy_p(*current)) - *dest++ = *current; - ++current; - } - return dest; - } - -/** -* Searching through a std::map -* @param mapping the map to search -* @param key is what to look for -* @param null_result is the value to return if key is not in mapping -* @return mapping[key] or null_result -*/ -template -inline V search_map(const std::map& mapping, - const K& key, - const V& null_result = V()) - { - typename std::map::const_iterator i = mapping.find(key); - if(i == mapping.end()) - return null_result; - return i->second; - } - -/** -* Function adaptor for delete operation -*/ -template -class del_fun - { - public: - void operator()(T* ptr) { delete ptr; } - }; - -/** -* Delete the second half of a pair of objects -*/ -template -void delete2nd(Pair& pair) - { - delete pair.second; - } - -/** -* Insert a key/value pair into a multimap -*/ -template -void multimap_insert(std::multimap& multimap, - const K& key, const V& value) - { -#if defined(BOTAN_BUILD_COMPILER_IS_SUN_STUDIO) - // Work around a strange bug in Sun Studio - multimap.insert(std::make_pair(key, value)); -#else - multimap.insert(std::make_pair(key, value)); -#endif - } - -} - - -namespace Botan { - -/** -* @param prov_name a provider name -* @return weight for this provider -*/ -size_t static_provider_weight(const std::string& prov_name); - -/** -* Algorithm_Cache (used by Algorithm_Factory) -*/ -template -class Algorithm_Cache - { - public: - /** - * @param algo_spec names the requested algorithm - * @param pref_provider suggests a preferred provider - * @return prototype object, or NULL - */ - const T* get(const std::string& algo_spec, - const std::string& pref_provider); - - /** - * Add a new algorithm implementation to the cache - * @param algo the algorithm prototype object - * @param requested_name how this name will be requested - * @param provider_name is the name of the provider of this prototype - */ - void add(T* algo, - const std::string& requested_name, - const std::string& provider_name); - - /** - * Set the preferred provider - * @param algo_spec names the algorithm - * @param provider names the preferred provider - */ - void set_preferred_provider(const std::string& algo_spec, - const std::string& provider); - - /** - * Return the list of providers of this algorithm - * @param algo_name names the algorithm - * @return list of providers of this algorithm - */ - std::vector providers_of(const std::string& algo_name); - - /** - * Clear the cache - */ - void clear_cache(); - - /** - * Constructor - * @param m a mutex to serialize internal access - */ - Algorithm_Cache(Mutex* m) : mutex(m) {} - ~Algorithm_Cache() { clear_cache(); delete mutex; } - private: - typedef typename std::map >::iterator - algorithms_iterator; - - typedef typename std::map::iterator provider_iterator; - - algorithms_iterator find_algorithm(const std::string& algo_spec); - - Mutex* mutex; - std::map aliases; - std::map pref_providers; - std::map > algorithms; - }; - -/* -* Look for an algorithm implementation in the cache, also checking aliases -* Assumes object lock is held -*/ -template -typename Algorithm_Cache::algorithms_iterator -Algorithm_Cache::find_algorithm(const std::string& algo_spec) - { - algorithms_iterator algo = algorithms.find(algo_spec); - - // Not found? Check if a known alias - if(algo == algorithms.end()) - { - std::map::const_iterator alias = - aliases.find(algo_spec); - - if(alias != aliases.end()) - algo = algorithms.find(alias->second); - } - - return algo; - } - -/* -* Look for an algorithm implementation by a particular provider -*/ -template -const T* Algorithm_Cache::get(const std::string& algo_spec, - const std::string& requested_provider) - { - Mutex_Holder lock(mutex); - - algorithms_iterator algo = find_algorithm(algo_spec); - if(algo == algorithms.end()) // algo not found at all (no providers) - return 0; - - // If a provider is requested specifically, return it or fail entirely - if(requested_provider != "") - { - provider_iterator prov = algo->second.find(requested_provider); - if(prov != algo->second.end()) - return prov->second; - return 0; - } - - const T* prototype = 0; - std::string prototype_provider; - size_t prototype_prov_weight = 0; - - const std::string pref_provider = search_map(pref_providers, algo_spec); - - for(provider_iterator i = algo->second.begin(); i != algo->second.end(); ++i) - { - const std::string prov_name = i->first; - const size_t prov_weight = static_provider_weight(prov_name); - - // preferred prov exists, return immediately - if(prov_name == pref_provider) - return i->second; - - if(prototype == 0 || prov_weight > prototype_prov_weight) - { - prototype = i->second; - prototype_provider = i->first; - prototype_prov_weight = prov_weight; - } - } - - return prototype; - } - -/* -* Add an implementation to the cache -*/ -template -void Algorithm_Cache::add(T* algo, - const std::string& requested_name, - const std::string& provider) - { - if(!algo) - return; - - Mutex_Holder lock(mutex); - - if(algo->name() != requested_name && - aliases.find(requested_name) == aliases.end()) - { - aliases[requested_name] = algo->name(); - } - - if(!algorithms[algo->name()][provider]) - algorithms[algo->name()][provider] = algo; - else - delete algo; - } - -/* -* Find the providers of this algo (if any) -*/ -template std::vector -Algorithm_Cache::providers_of(const std::string& algo_name) - { - Mutex_Holder lock(mutex); - - std::vector providers; - - algorithms_iterator algo = find_algorithm(algo_name); - - if(algo != algorithms.end()) - { - provider_iterator provider = algo->second.begin(); - - while(provider != algo->second.end()) - { - providers.push_back(provider->first); - ++provider; - } - } - - return providers; - } - -/* -* Set the preferred provider for an algorithm -*/ -template -void Algorithm_Cache::set_preferred_provider(const std::string& algo_spec, - const std::string& provider) - { - Mutex_Holder lock(mutex); - - pref_providers[algo_spec] = provider; - } - -/* -* Clear out the cache -*/ -template -void Algorithm_Cache::clear_cache() - { - algorithms_iterator algo = algorithms.begin(); - - while(algo != algorithms.end()) - { - provider_iterator provider = algo->second.begin(); - - while(provider != algo->second.end()) - { - delete provider->second; - ++provider; - } - - ++algo; - } - - algorithms.clear(); - } - -} - - -namespace Botan { - -/** -* Round up -* @param n an integer -* @param align_to the alignment boundary -* @return n rounded up to a multiple of align_to -*/ -template -inline T round_up(T n, T align_to) - { - if(n % align_to || n == 0) - n += align_to - (n % align_to); - return n; - } - -/** -* Round down -* @param n an integer -* @param align_to the alignment boundary -* @return n rounded down to a multiple of align_to -*/ -template -inline T round_down(T n, T align_to) - { - return (n - (n % align_to)); - } - -} - - -namespace Botan { - -/** -* Engine for implementations that use some kind of SIMD -*/ -class SIMD_Engine : public Engine - { - public: - std::string provider_name() const { return "simd"; } - - BlockCipher* find_block_cipher(const SCAN_Name&, - Algorithm_Factory&) const; - - HashFunction* find_hash(const SCAN_Name& request, - Algorithm_Factory&) const; - }; - -} - - -namespace Botan { - -/** -* File Tree Walking Entropy Source -*/ -class FTW_EntropySource : public EntropySource - { - public: - std::string name() const { return "Proc Walker"; } - - void poll(Entropy_Accumulator& accum); - - FTW_EntropySource(const std::string& root_dir); - ~FTW_EntropySource(); - private: - std::string path; - class File_Descriptor_Source* dir; - }; - -} - - -namespace Botan { - -/** -* Entropy source using high resolution timers -* -* @note Any results from timers are marked as not contributing entropy -* to the poll, as a local attacker could observe them directly. -*/ -class High_Resolution_Timestamp : public EntropySource - { - public: - std::string name() const { return "High Resolution Timestamp"; } - void poll(Entropy_Accumulator& accum); - }; - -} - -#ifdef Q_OS_WIN -namespace Botan { - -/** -* Win32 Mutex Factory -*/ -class Win32_Mutex_Factory : public Mutex_Factory - { - public: - Mutex* make(); - }; -} -#endif - - -namespace Botan { - -/** -* Power of 2 test. T should be an unsigned integer type -* @param arg an integer value -* @return true iff arg is 2^n for some n > 0 -*/ -template -inline bool power_of_2(T arg) - { - return ((arg != 0 && arg != 1) && ((arg & (arg-1)) == 0)); - } - -/** -* Return the index of the highest set bit -* T is an unsigned integer type -* @param n an integer value -* @return index of the highest set bit in n -*/ -template -inline size_t high_bit(T n) - { - for(size_t i = 8*sizeof(T); i > 0; --i) - if((n >> (i - 1)) & 0x01) - return i; - return 0; - } - -/** -* Return the index of the lowest set bit -* T is an unsigned integer type -* @param n an integer value -* @return index of the lowest set bit in n -*/ -template -inline size_t low_bit(T n) - { - for(size_t i = 0; i != 8*sizeof(T); ++i) - if((n >> i) & 0x01) - return (i + 1); - return 0; - } - -/** -* Return the number of significant bytes in n -* @param n an integer value -* @return number of significant bytes in n -*/ -template -inline size_t significant_bytes(T n) - { - for(size_t i = 0; i != sizeof(T); ++i) - if(get_byte(i, n)) - return sizeof(T)-i; - return 0; - } - -/** -* Compute Hamming weights -* @param n an integer value -* @return number of bits in n set to 1 -*/ -template -inline size_t hamming_weight(T n) - { - const byte NIBBLE_WEIGHTS[] = { - 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 }; - - size_t weight = 0; - for(size_t i = 0; i != 2*sizeof(T); ++i) - weight += NIBBLE_WEIGHTS[(n >> (4*i)) & 0x0F]; - return weight; - } - -/** -* Count the trailing zero bits in n -* @param n an integer value -* @return maximum x st 2^x divides n -*/ -template -inline size_t ctz(T n) - { - for(size_t i = 0; i != 8*sizeof(T); ++i) - if((n >> i) & 0x01) - return i; - return 8*sizeof(T); - } - -} - - -namespace Botan { - -/** -* Estimate work factor for discrete logarithm -* @param prime_group_size size of the group in bits -* @return estimated security level for this group -*/ -size_t dl_work_factor(size_t prime_group_size); - -} - - -namespace Botan { - -/** -* No-Op Mutex Factory -*/ -class Noop_Mutex_Factory : public Mutex_Factory - { - public: - Mutex* make(); - }; - -} - - -namespace Botan { - -/** -* Pooling Allocator -*/ -class Pooling_Allocator : public Allocator - { - public: - void* allocate(size_t); - void deallocate(void*, size_t); - - void destroy(); - - /** - * @param mutex used for internal locking - */ - Pooling_Allocator(Mutex* mutex); - ~Pooling_Allocator(); - private: - void get_more_core(size_t); - byte* allocate_blocks(size_t); - - virtual void* alloc_block(size_t) = 0; - virtual void dealloc_block(void*, size_t) = 0; - - class Memory_Block - { - public: - Memory_Block(void*); - - static size_t bitmap_size() { return BITMAP_SIZE; } - static size_t block_size() { return BLOCK_SIZE; } - - bool contains(void*, size_t) const; - byte* alloc(size_t); - void free(void*, size_t); - - bool operator<(const Memory_Block& other) const - { - if(buffer < other.buffer && other.buffer < buffer_end) - return false; - return (buffer < other.buffer); - } - private: - typedef u64bit bitmap_type; - static const size_t BITMAP_SIZE = 8 * sizeof(bitmap_type); - static const size_t BLOCK_SIZE = 64; - - bitmap_type bitmap; - byte* buffer, *buffer_end; - }; - - std::vector blocks; - std::vector::iterator last_used; - std::vector > allocated; - Mutex* mutex; - }; - -} - - -namespace Botan { - -/** -* Allocator using malloc -*/ -class Malloc_Allocator : public Allocator - { - public: - void* allocate(size_t); - void deallocate(void*, size_t); - - std::string type() const { return "malloc"; } - }; - -/** -* Allocator using malloc plus locking -*/ -class Locking_Allocator : public Pooling_Allocator - { - public: - /** - * @param mutex used for internal locking - */ - Locking_Allocator(Mutex* mutex) : Pooling_Allocator(mutex) {} - - std::string type() const { return "locking"; } - private: - void* alloc_block(size_t); - void dealloc_block(void*, size_t); - }; - -} - - -namespace Botan { - -/** -* Fixed Window Exponentiator -*/ -class Fixed_Window_Exponentiator : public Modular_Exponentiator - { - public: - void set_exponent(const BigInt&); - void set_base(const BigInt&); - BigInt execute() const; - - Modular_Exponentiator* copy() const - { return new Fixed_Window_Exponentiator(*this); } - - Fixed_Window_Exponentiator(const BigInt&, Power_Mod::Usage_Hints); - private: - Modular_Reducer reducer; - BigInt exp; - size_t window_bits; - std::vector g; - Power_Mod::Usage_Hints hints; - }; - -/** -* Montgomery Exponentiator -*/ -class Montgomery_Exponentiator : public Modular_Exponentiator - { - public: - void set_exponent(const BigInt&); - void set_base(const BigInt&); - BigInt execute() const; - - Modular_Exponentiator* copy() const - { return new Montgomery_Exponentiator(*this); } - - Montgomery_Exponentiator(const BigInt&, Power_Mod::Usage_Hints); - private: - BigInt exp, modulus; - BigInt R2, R_mod; - std::vector g; - word mod_prime; - size_t mod_words, exp_bits, window_bits; - Power_Mod::Usage_Hints hints; - }; - -} - - -#if (BOTAN_MP_WORD_BITS != 32) - #error The mp_x86_32 module requires that BOTAN_MP_WORD_BITS == 32 -#endif - -#ifdef Q_OS_UNIX -namespace Botan { - -extern "C" { - -/* -* Helper Macros for x86 Assembly -*/ -#define ASM(x) x "\n\t" - -/* -* Word Multiply -*/ -inline word word_madd2(word a, word b, word* c) - { - asm( - ASM("mull %[b]") - ASM("addl %[c],%[a]") - ASM("adcl $0,%[carry]") - - : [a]"=a"(a), [b]"=rm"(b), [carry]"=&d"(*c) - : "0"(a), "1"(b), [c]"g"(*c) : "cc"); - - return a; - } - -/* -* Word Multiply/Add -*/ -inline word word_madd3(word a, word b, word c, word* d) - { - asm( - ASM("mull %[b]") - - ASM("addl %[c],%[a]") - ASM("adcl $0,%[carry]") - - ASM("addl %[d],%[a]") - ASM("adcl $0,%[carry]") - - : [a]"=a"(a), [b]"=rm"(b), [carry]"=&d"(*d) - : "0"(a), "1"(b), [c]"g"(c), [d]"g"(*d) : "cc"); - - return a; - } - -} - -} -#endif - - - -namespace Botan { - -/** -* Unix Program Info -*/ -struct Unix_Program - { - /** - * @param n is the name and arguments of what we are going run - * @param p is the priority level (lower prio numbers get polled first) - */ - Unix_Program(const char* n, size_t p) - { name_and_args = n; priority = p; working = true; } - - /** - * The name and arguments for this command - */ - std::string name_and_args; - - /** - * Priority: we scan from low to high - */ - size_t priority; - - /** - * Does this source seem to be working? - */ - bool working; - }; - -/** -* Command Output DataSource -*/ -class DataSource_Command : public DataSource - { - public: - size_t read(byte[], size_t); - size_t peek(byte[], size_t, size_t) const; - bool end_of_data() const; - std::string id() const; - - int fd() const; - - DataSource_Command(const std::string&, - const std::vector& paths); - ~DataSource_Command(); - private: - void create_pipe(const std::vector&); - void shutdown_pipe(); - - const size_t MAX_BLOCK_USECS, KILL_WAIT; - - std::vector arg_list; - struct pipe_wrapper* pipe; - }; - -} - - -namespace Botan { - -/** -* Allocator that uses memory maps backed by disk. We zeroize the map -* upon deallocation. If swap occurs, the VM will swap to the shared -* file backing rather than to a swap device, which means we know where -* it is and can zap it later. -*/ -class MemoryMapping_Allocator : public Pooling_Allocator - { - public: - /** - * @param mutex used for internal locking - */ - MemoryMapping_Allocator(Mutex* mutex) : Pooling_Allocator(mutex) {} - std::string type() const { return "mmap"; } - private: - void* alloc_block(size_t); - void dealloc_block(void*, size_t); - }; - -} - - -#if defined(BOTAN_HAS_SIMD_SSE2) - namespace Botan { typedef SIMD_SSE2 SIMD_32; } - -#elif defined(BOTAN_HAS_SIMD_ALTIVEC) - namespace Botan { typedef SIMD_Altivec SIMD_32; } - -#elif defined(BOTAN_HAS_SIMD_SCALAR) - namespace Botan { typedef SIMD_Scalar SIMD_32; } - -#else - #error "No SIMD module defined" - -#endif - - -namespace Botan { - -/** -* Entropy source reading from kernel devices like /dev/random -*/ -class Device_EntropySource : public EntropySource - { - public: - std::string name() const { return "RNG Device Reader"; } - - void poll(Entropy_Accumulator& accum); - - Device_EntropySource(const std::vector& fsnames); - ~Device_EntropySource(); - private: - - /** - A class handling reading from a Unix character device - */ - class Device_Reader - { - public: - typedef int fd_type; - - // Does not own fd, a transient class - Device_Reader(fd_type device_fd) : fd(device_fd) {} - - void close(); - - size_t get(byte out[], size_t length, size_t ms_wait_time); - - static fd_type open(const std::string& pathname); - private: - fd_type fd; - }; - - std::vector devices; - }; - -} - -namespace Botan { - -void assertion_failure(const char* expr_str, - const char* msg, - const char* func, - const char* file, - int line); - -#define BOTAN_ASSERT(expr, msg) \ - do { \ - if(!(expr)) \ - Botan::assertion_failure(#expr, \ - msg, \ - BOTAN_ASSERT_FUNCTION, \ - __FILE__, \ - __LINE__); \ - } while(0) - -#define BOTAN_ASSERT_EQUAL(value1, value2, msg) \ - do { \ - if(value1 != value2) \ - Botan::assertion_failure(#value1 " == " #value2, \ - msg, \ - BOTAN_ASSERT_FUNCTION, \ - __FILE__, \ - __LINE__); \ - } while(0) - -/* -* Unfortunately getting the function name from the preprocessor -* isn't standard in C++98 (C++0x uses C99's __func__) -*/ -#if defined(BOTAN_BUILD_COMPILER_IS_GCC) || \ - defined(BOTAN_BUILD_COMPILER_IS_CLANG) || \ - defined(BOTAN_BUILD_COMPILER_IS_INTEL) - - #define BOTAN_ASSERT_FUNCTION __PRETTY_FUNCTION__ - -#elif defined(BOTAN_BUILD_COMPILER_IS_MSVC) - - #define BOTAN_ASSERT_FUNCTION __FUNCTION__ - -#else - #define BOTAN_ASSERT_FUNCTION ((const char*)0) -#endif - -} - - -namespace Botan { - -/* -* The size of the word type, in bits -*/ -const size_t MP_WORD_BITS = BOTAN_MP_WORD_BITS; - -extern "C" { - -/* -* Addition/Subtraction Operations -*/ -void bigint_add2(word x[], size_t x_size, - const word y[], size_t y_size); - -void bigint_add3(word z[], - const word x[], size_t x_size, - const word y[], size_t y_size); - -word bigint_add2_nc(word x[], size_t x_size, const word y[], size_t y_size); - -word bigint_add3_nc(word z[], - const word x[], size_t x_size, - const word y[], size_t y_size); - -word bigint_sub2(word x[], size_t x_size, - const word y[], size_t y_size); - -/** -* x = y - x; assumes y >= x -*/ -void bigint_sub2_rev(word x[], const word y[], size_t y_size); - -word bigint_sub3(word z[], - const word x[], size_t x_size, - const word y[], size_t y_size); - -/* -* Shift Operations -*/ -void bigint_shl1(word x[], size_t x_size, - size_t word_shift, size_t bit_shift); - -void bigint_shr1(word x[], size_t x_size, - size_t word_shift, size_t bit_shift); - -void bigint_shl2(word y[], const word x[], size_t x_size, - size_t word_shift, size_t bit_shift); - -void bigint_shr2(word y[], const word x[], size_t x_size, - size_t word_shift, size_t bit_shift); - -/* -* Simple O(N^2) Multiplication and Squaring -*/ -void bigint_simple_mul(word z[], - const word x[], size_t x_size, - const word y[], size_t y_size); - -void bigint_simple_sqr(word z[], const word x[], size_t x_size); - -/* -* Linear Multiply -*/ -void bigint_linmul2(word x[], size_t x_size, word y); -void bigint_linmul3(word z[], const word x[], size_t x_size, word y); - -/** -* Montgomery Reduction -* @param z integer to reduce (also output in first p_size+1 words) -* @param z_size size of z (should be >= 2*p_size+1) -* @param p modulus -* @param p_size size of p -* @param p_dash Montgomery value -* @param workspace array of at least 2*(p_size+1) words -*/ -void bigint_monty_redc(word z[], size_t z_size, - const word p[], size_t p_size, word p_dash, - word workspace[]); - -/* -* Montgomery Multiplication -*/ -void bigint_monty_mul(word z[], size_t z_size, - const word x[], size_t x_size, size_t x_sw, - const word y[], size_t y_size, size_t y_sw, - const word p[], size_t p_size, word p_dash, - word workspace[]); - -/* -* Montgomery Squaring -*/ -void bigint_monty_sqr(word z[], size_t z_size, - const word x[], size_t x_size, size_t x_sw, - const word p[], size_t p_size, word p_dash, - word workspace[]); - -/* -* Division operation -*/ -size_t bigint_divcore(word q, word y2, word y1, - word x3, word x2, word x1); - -/** -* Compare x and y -*/ -s32bit bigint_cmp(const word x[], size_t x_size, - const word y[], size_t y_size); - -/** -* Compute ((n1<& path); - private: - static std::vector get_default_sources(); - void fast_poll(Entropy_Accumulator& accum); - - const std::vector PATH; - std::vector sources; - }; - -} - -namespace Botan { - -/** -* EGD Entropy Source -*/ -class EGD_EntropySource : public EntropySource - { - public: - std::string name() const { return "EGD/PRNGD"; } - - void poll(Entropy_Accumulator& accum); - - EGD_EntropySource(const std::vector&); - ~EGD_EntropySource(); - private: - class EGD_Socket - { - public: - EGD_Socket(const std::string& path); - - void close(); - size_t read(byte outbuf[], size_t length); - private: - static int open_socket(const std::string& path); - - std::string socket_path; - int m_fd; // cached fd - }; - - std::vector sockets; - }; - -} -#endif - -namespace Botan { - -Public_Key* make_public_key(const AlgorithmIdentifier& alg_id, - const MemoryRegion& key_bits); - -Private_Key* make_private_key(const AlgorithmIdentifier& alg_id, - const MemoryRegion& key_bits, - RandomNumberGenerator& rng); - -} - - -namespace Botan { - -/** -* Container of output buffers for Pipe -*/ -class Output_Buffers - { - public: - size_t read(byte[], size_t, Pipe::message_id); - size_t peek(byte[], size_t, size_t, Pipe::message_id) const; - size_t remaining(Pipe::message_id) const; - - void add(class SecureQueue*); - void retire(); - - Pipe::message_id message_count() const; - - Output_Buffers(); - ~Output_Buffers(); - private: - class SecureQueue* get(Pipe::message_id) const; - - std::deque buffers; - Pipe::message_id offset; - }; - -} - - -namespace Botan { - -/** -* Check if we can at least potentially lock memory -*/ -bool has_mlock(); - -/** -* Lock memory into RAM if possible -* @param addr the start of the memory block -* @param length the length of the memory block in bytes -* @returns true if successful, false otherwise -*/ -bool lock_mem(void* addr, size_t length); - -/** -* Unlock memory locked with lock_mem() -* @param addr the start of the memory block -* @param length the length of the memory block in bytes -*/ -void unlock_mem(void* addr, size_t length); - -} - -#ifdef Q_OS_WIN -#if (BOTAN_MP_WORD_BITS == 8) - typedef Botan::u16bit dword; -#elif (BOTAN_MP_WORD_BITS == 16) - typedef Botan::u32bit dword; -#elif (BOTAN_MP_WORD_BITS == 32) - typedef Botan::u64bit dword; -#elif (BOTAN_MP_WORD_BITS == 64) - #error BOTAN_MP_WORD_BITS can be 64 only with assembly support -#else - #error BOTAN_MP_WORD_BITS must be 8, 16, 32, or 64 -#endif - -namespace Botan { - -extern "C" { - -/* -* Word Multiply/Add -*/ -inline word word_madd2(word a, word b, word* c) - { - dword z = (dword)a * b + *c; - *c = (word)(z >> BOTAN_MP_WORD_BITS); - return (word)z; - } - -/* -* Word Multiply/Add -*/ -inline word word_madd3(word a, word b, word c, word* d) - { - dword z = (dword)a * b + c + *d; - *d = (word)(z >> BOTAN_MP_WORD_BITS); - return (word)z; - } - -} - -/** -* Win32 CAPI Entropy Source -*/ -class Win32_CAPI_EntropySource : public EntropySource - { - public: - std::string name() const { return "Win32 CryptoGenRandom"; } - - void poll(Entropy_Accumulator& accum); - - /** - * Win32_Capi_Entropysource Constructor - * @param provs list of providers, separated by ':' - */ - Win32_CAPI_EntropySource(const std::string& provs = ""); - private: - std::vector prov_types; - }; - -} -#endif - - -namespace Botan { - -template -inline void prefetch_readonly(const T* addr, size_t length) - { -#if defined(__GNUG__) - const size_t Ts_per_cache_line = CPUID::cache_line_size() / sizeof(T); - - for(size_t i = 0; i <= length; i += Ts_per_cache_line) - __builtin_prefetch(addr + i, 0); -#endif - } - -template -inline void prefetch_readwrite(const T* addr, size_t length) - { -#if defined(__GNUG__) - const size_t Ts_per_cache_line = CPUID::cache_line_size() / sizeof(T); - - for(size_t i = 0; i <= length; i += Ts_per_cache_line) - __builtin_prefetch(addr + i, 1); -#endif - } - -} - - -namespace Botan { - -const u64bit Camellia_SBOX1[256] = { -0x7070700070000070ULL, 0x8282820082000082ULL, 0x2C2C2C002C00002CULL, 0xECECEC00EC0000ECULL, -0xB3B3B300B30000B3ULL, 0x2727270027000027ULL, 0xC0C0C000C00000C0ULL, 0xE5E5E500E50000E5ULL, -0xE4E4E400E40000E4ULL, 0x8585850085000085ULL, 0x5757570057000057ULL, 0x3535350035000035ULL, -0xEAEAEA00EA0000EAULL, 0x0C0C0C000C00000CULL, 0xAEAEAE00AE0000AEULL, 0x4141410041000041ULL, -0x2323230023000023ULL, 0xEFEFEF00EF0000EFULL, 0x6B6B6B006B00006BULL, 0x9393930093000093ULL, -0x4545450045000045ULL, 0x1919190019000019ULL, 0xA5A5A500A50000A5ULL, 0x2121210021000021ULL, -0xEDEDED00ED0000EDULL, 0x0E0E0E000E00000EULL, 0x4F4F4F004F00004FULL, 0x4E4E4E004E00004EULL, -0x1D1D1D001D00001DULL, 0x6565650065000065ULL, 0x9292920092000092ULL, 0xBDBDBD00BD0000BDULL, -0x8686860086000086ULL, 0xB8B8B800B80000B8ULL, 0xAFAFAF00AF0000AFULL, 0x8F8F8F008F00008FULL, -0x7C7C7C007C00007CULL, 0xEBEBEB00EB0000EBULL, 0x1F1F1F001F00001FULL, 0xCECECE00CE0000CEULL, -0x3E3E3E003E00003EULL, 0x3030300030000030ULL, 0xDCDCDC00DC0000DCULL, 0x5F5F5F005F00005FULL, -0x5E5E5E005E00005EULL, 0xC5C5C500C50000C5ULL, 0x0B0B0B000B00000BULL, 0x1A1A1A001A00001AULL, -0xA6A6A600A60000A6ULL, 0xE1E1E100E10000E1ULL, 0x3939390039000039ULL, 0xCACACA00CA0000CAULL, -0xD5D5D500D50000D5ULL, 0x4747470047000047ULL, 0x5D5D5D005D00005DULL, 0x3D3D3D003D00003DULL, -0xD9D9D900D90000D9ULL, 0x0101010001000001ULL, 0x5A5A5A005A00005AULL, 0xD6D6D600D60000D6ULL, -0x5151510051000051ULL, 0x5656560056000056ULL, 0x6C6C6C006C00006CULL, 0x4D4D4D004D00004DULL, -0x8B8B8B008B00008BULL, 0x0D0D0D000D00000DULL, 0x9A9A9A009A00009AULL, 0x6666660066000066ULL, -0xFBFBFB00FB0000FBULL, 0xCCCCCC00CC0000CCULL, 0xB0B0B000B00000B0ULL, 0x2D2D2D002D00002DULL, -0x7474740074000074ULL, 0x1212120012000012ULL, 0x2B2B2B002B00002BULL, 0x2020200020000020ULL, -0xF0F0F000F00000F0ULL, 0xB1B1B100B10000B1ULL, 0x8484840084000084ULL, 0x9999990099000099ULL, -0xDFDFDF00DF0000DFULL, 0x4C4C4C004C00004CULL, 0xCBCBCB00CB0000CBULL, 0xC2C2C200C20000C2ULL, -0x3434340034000034ULL, 0x7E7E7E007E00007EULL, 0x7676760076000076ULL, 0x0505050005000005ULL, -0x6D6D6D006D00006DULL, 0xB7B7B700B70000B7ULL, 0xA9A9A900A90000A9ULL, 0x3131310031000031ULL, -0xD1D1D100D10000D1ULL, 0x1717170017000017ULL, 0x0404040004000004ULL, 0xD7D7D700D70000D7ULL, -0x1414140014000014ULL, 0x5858580058000058ULL, 0x3A3A3A003A00003AULL, 0x6161610061000061ULL, -0xDEDEDE00DE0000DEULL, 0x1B1B1B001B00001BULL, 0x1111110011000011ULL, 0x1C1C1C001C00001CULL, -0x3232320032000032ULL, 0x0F0F0F000F00000FULL, 0x9C9C9C009C00009CULL, 0x1616160016000016ULL, -0x5353530053000053ULL, 0x1818180018000018ULL, 0xF2F2F200F20000F2ULL, 0x2222220022000022ULL, -0xFEFEFE00FE0000FEULL, 0x4444440044000044ULL, 0xCFCFCF00CF0000CFULL, 0xB2B2B200B20000B2ULL, -0xC3C3C300C30000C3ULL, 0xB5B5B500B50000B5ULL, 0x7A7A7A007A00007AULL, 0x9191910091000091ULL, -0x2424240024000024ULL, 0x0808080008000008ULL, 0xE8E8E800E80000E8ULL, 0xA8A8A800A80000A8ULL, -0x6060600060000060ULL, 0xFCFCFC00FC0000FCULL, 0x6969690069000069ULL, 0x5050500050000050ULL, -0xAAAAAA00AA0000AAULL, 0xD0D0D000D00000D0ULL, 0xA0A0A000A00000A0ULL, 0x7D7D7D007D00007DULL, -0xA1A1A100A10000A1ULL, 0x8989890089000089ULL, 0x6262620062000062ULL, 0x9797970097000097ULL, -0x5454540054000054ULL, 0x5B5B5B005B00005BULL, 0x1E1E1E001E00001EULL, 0x9595950095000095ULL, -0xE0E0E000E00000E0ULL, 0xFFFFFF00FF0000FFULL, 0x6464640064000064ULL, 0xD2D2D200D20000D2ULL, -0x1010100010000010ULL, 0xC4C4C400C40000C4ULL, 0x0000000000000000ULL, 0x4848480048000048ULL, -0xA3A3A300A30000A3ULL, 0xF7F7F700F70000F7ULL, 0x7575750075000075ULL, 0xDBDBDB00DB0000DBULL, -0x8A8A8A008A00008AULL, 0x0303030003000003ULL, 0xE6E6E600E60000E6ULL, 0xDADADA00DA0000DAULL, -0x0909090009000009ULL, 0x3F3F3F003F00003FULL, 0xDDDDDD00DD0000DDULL, 0x9494940094000094ULL, -0x8787870087000087ULL, 0x5C5C5C005C00005CULL, 0x8383830083000083ULL, 0x0202020002000002ULL, -0xCDCDCD00CD0000CDULL, 0x4A4A4A004A00004AULL, 0x9090900090000090ULL, 0x3333330033000033ULL, -0x7373730073000073ULL, 0x6767670067000067ULL, 0xF6F6F600F60000F6ULL, 0xF3F3F300F30000F3ULL, -0x9D9D9D009D00009DULL, 0x7F7F7F007F00007FULL, 0xBFBFBF00BF0000BFULL, 0xE2E2E200E20000E2ULL, -0x5252520052000052ULL, 0x9B9B9B009B00009BULL, 0xD8D8D800D80000D8ULL, 0x2626260026000026ULL, -0xC8C8C800C80000C8ULL, 0x3737370037000037ULL, 0xC6C6C600C60000C6ULL, 0x3B3B3B003B00003BULL, -0x8181810081000081ULL, 0x9696960096000096ULL, 0x6F6F6F006F00006FULL, 0x4B4B4B004B00004BULL, -0x1313130013000013ULL, 0xBEBEBE00BE0000BEULL, 0x6363630063000063ULL, 0x2E2E2E002E00002EULL, -0xE9E9E900E90000E9ULL, 0x7979790079000079ULL, 0xA7A7A700A70000A7ULL, 0x8C8C8C008C00008CULL, -0x9F9F9F009F00009FULL, 0x6E6E6E006E00006EULL, 0xBCBCBC00BC0000BCULL, 0x8E8E8E008E00008EULL, -0x2929290029000029ULL, 0xF5F5F500F50000F5ULL, 0xF9F9F900F90000F9ULL, 0xB6B6B600B60000B6ULL, -0x2F2F2F002F00002FULL, 0xFDFDFD00FD0000FDULL, 0xB4B4B400B40000B4ULL, 0x5959590059000059ULL, -0x7878780078000078ULL, 0x9898980098000098ULL, 0x0606060006000006ULL, 0x6A6A6A006A00006AULL, -0xE7E7E700E70000E7ULL, 0x4646460046000046ULL, 0x7171710071000071ULL, 0xBABABA00BA0000BAULL, -0xD4D4D400D40000D4ULL, 0x2525250025000025ULL, 0xABABAB00AB0000ABULL, 0x4242420042000042ULL, -0x8888880088000088ULL, 0xA2A2A200A20000A2ULL, 0x8D8D8D008D00008DULL, 0xFAFAFA00FA0000FAULL, -0x7272720072000072ULL, 0x0707070007000007ULL, 0xB9B9B900B90000B9ULL, 0x5555550055000055ULL, -0xF8F8F800F80000F8ULL, 0xEEEEEE00EE0000EEULL, 0xACACAC00AC0000ACULL, 0x0A0A0A000A00000AULL, -0x3636360036000036ULL, 0x4949490049000049ULL, 0x2A2A2A002A00002AULL, 0x6868680068000068ULL, -0x3C3C3C003C00003CULL, 0x3838380038000038ULL, 0xF1F1F100F10000F1ULL, 0xA4A4A400A40000A4ULL, -0x4040400040000040ULL, 0x2828280028000028ULL, 0xD3D3D300D30000D3ULL, 0x7B7B7B007B00007BULL, -0xBBBBBB00BB0000BBULL, 0xC9C9C900C90000C9ULL, 0x4343430043000043ULL, 0xC1C1C100C10000C1ULL, -0x1515150015000015ULL, 0xE3E3E300E30000E3ULL, 0xADADAD00AD0000ADULL, 0xF4F4F400F40000F4ULL, -0x7777770077000077ULL, 0xC7C7C700C70000C7ULL, 0x8080800080000080ULL, 0x9E9E9E009E00009EULL }; - -const u64bit Camellia_SBOX2[256] = { -0x00E0E0E0E0E00000ULL, 0x0005050505050000ULL, 0x0058585858580000ULL, 0x00D9D9D9D9D90000ULL, -0x0067676767670000ULL, 0x004E4E4E4E4E0000ULL, 0x0081818181810000ULL, 0x00CBCBCBCBCB0000ULL, -0x00C9C9C9C9C90000ULL, 0x000B0B0B0B0B0000ULL, 0x00AEAEAEAEAE0000ULL, 0x006A6A6A6A6A0000ULL, -0x00D5D5D5D5D50000ULL, 0x0018181818180000ULL, 0x005D5D5D5D5D0000ULL, 0x0082828282820000ULL, -0x0046464646460000ULL, 0x00DFDFDFDFDF0000ULL, 0x00D6D6D6D6D60000ULL, 0x0027272727270000ULL, -0x008A8A8A8A8A0000ULL, 0x0032323232320000ULL, 0x004B4B4B4B4B0000ULL, 0x0042424242420000ULL, -0x00DBDBDBDBDB0000ULL, 0x001C1C1C1C1C0000ULL, 0x009E9E9E9E9E0000ULL, 0x009C9C9C9C9C0000ULL, -0x003A3A3A3A3A0000ULL, 0x00CACACACACA0000ULL, 0x0025252525250000ULL, 0x007B7B7B7B7B0000ULL, -0x000D0D0D0D0D0000ULL, 0x0071717171710000ULL, 0x005F5F5F5F5F0000ULL, 0x001F1F1F1F1F0000ULL, -0x00F8F8F8F8F80000ULL, 0x00D7D7D7D7D70000ULL, 0x003E3E3E3E3E0000ULL, 0x009D9D9D9D9D0000ULL, -0x007C7C7C7C7C0000ULL, 0x0060606060600000ULL, 0x00B9B9B9B9B90000ULL, 0x00BEBEBEBEBE0000ULL, -0x00BCBCBCBCBC0000ULL, 0x008B8B8B8B8B0000ULL, 0x0016161616160000ULL, 0x0034343434340000ULL, -0x004D4D4D4D4D0000ULL, 0x00C3C3C3C3C30000ULL, 0x0072727272720000ULL, 0x0095959595950000ULL, -0x00ABABABABAB0000ULL, 0x008E8E8E8E8E0000ULL, 0x00BABABABABA0000ULL, 0x007A7A7A7A7A0000ULL, -0x00B3B3B3B3B30000ULL, 0x0002020202020000ULL, 0x00B4B4B4B4B40000ULL, 0x00ADADADADAD0000ULL, -0x00A2A2A2A2A20000ULL, 0x00ACACACACAC0000ULL, 0x00D8D8D8D8D80000ULL, 0x009A9A9A9A9A0000ULL, -0x0017171717170000ULL, 0x001A1A1A1A1A0000ULL, 0x0035353535350000ULL, 0x00CCCCCCCCCC0000ULL, -0x00F7F7F7F7F70000ULL, 0x0099999999990000ULL, 0x0061616161610000ULL, 0x005A5A5A5A5A0000ULL, -0x00E8E8E8E8E80000ULL, 0x0024242424240000ULL, 0x0056565656560000ULL, 0x0040404040400000ULL, -0x00E1E1E1E1E10000ULL, 0x0063636363630000ULL, 0x0009090909090000ULL, 0x0033333333330000ULL, -0x00BFBFBFBFBF0000ULL, 0x0098989898980000ULL, 0x0097979797970000ULL, 0x0085858585850000ULL, -0x0068686868680000ULL, 0x00FCFCFCFCFC0000ULL, 0x00ECECECECEC0000ULL, 0x000A0A0A0A0A0000ULL, -0x00DADADADADA0000ULL, 0x006F6F6F6F6F0000ULL, 0x0053535353530000ULL, 0x0062626262620000ULL, -0x00A3A3A3A3A30000ULL, 0x002E2E2E2E2E0000ULL, 0x0008080808080000ULL, 0x00AFAFAFAFAF0000ULL, -0x0028282828280000ULL, 0x00B0B0B0B0B00000ULL, 0x0074747474740000ULL, 0x00C2C2C2C2C20000ULL, -0x00BDBDBDBDBD0000ULL, 0x0036363636360000ULL, 0x0022222222220000ULL, 0x0038383838380000ULL, -0x0064646464640000ULL, 0x001E1E1E1E1E0000ULL, 0x0039393939390000ULL, 0x002C2C2C2C2C0000ULL, -0x00A6A6A6A6A60000ULL, 0x0030303030300000ULL, 0x00E5E5E5E5E50000ULL, 0x0044444444440000ULL, -0x00FDFDFDFDFD0000ULL, 0x0088888888880000ULL, 0x009F9F9F9F9F0000ULL, 0x0065656565650000ULL, -0x0087878787870000ULL, 0x006B6B6B6B6B0000ULL, 0x00F4F4F4F4F40000ULL, 0x0023232323230000ULL, -0x0048484848480000ULL, 0x0010101010100000ULL, 0x00D1D1D1D1D10000ULL, 0x0051515151510000ULL, -0x00C0C0C0C0C00000ULL, 0x00F9F9F9F9F90000ULL, 0x00D2D2D2D2D20000ULL, 0x00A0A0A0A0A00000ULL, -0x0055555555550000ULL, 0x00A1A1A1A1A10000ULL, 0x0041414141410000ULL, 0x00FAFAFAFAFA0000ULL, -0x0043434343430000ULL, 0x0013131313130000ULL, 0x00C4C4C4C4C40000ULL, 0x002F2F2F2F2F0000ULL, -0x00A8A8A8A8A80000ULL, 0x00B6B6B6B6B60000ULL, 0x003C3C3C3C3C0000ULL, 0x002B2B2B2B2B0000ULL, -0x00C1C1C1C1C10000ULL, 0x00FFFFFFFFFF0000ULL, 0x00C8C8C8C8C80000ULL, 0x00A5A5A5A5A50000ULL, -0x0020202020200000ULL, 0x0089898989890000ULL, 0x0000000000000000ULL, 0x0090909090900000ULL, -0x0047474747470000ULL, 0x00EFEFEFEFEF0000ULL, 0x00EAEAEAEAEA0000ULL, 0x00B7B7B7B7B70000ULL, -0x0015151515150000ULL, 0x0006060606060000ULL, 0x00CDCDCDCDCD0000ULL, 0x00B5B5B5B5B50000ULL, -0x0012121212120000ULL, 0x007E7E7E7E7E0000ULL, 0x00BBBBBBBBBB0000ULL, 0x0029292929290000ULL, -0x000F0F0F0F0F0000ULL, 0x00B8B8B8B8B80000ULL, 0x0007070707070000ULL, 0x0004040404040000ULL, -0x009B9B9B9B9B0000ULL, 0x0094949494940000ULL, 0x0021212121210000ULL, 0x0066666666660000ULL, -0x00E6E6E6E6E60000ULL, 0x00CECECECECE0000ULL, 0x00EDEDEDEDED0000ULL, 0x00E7E7E7E7E70000ULL, -0x003B3B3B3B3B0000ULL, 0x00FEFEFEFEFE0000ULL, 0x007F7F7F7F7F0000ULL, 0x00C5C5C5C5C50000ULL, -0x00A4A4A4A4A40000ULL, 0x0037373737370000ULL, 0x00B1B1B1B1B10000ULL, 0x004C4C4C4C4C0000ULL, -0x0091919191910000ULL, 0x006E6E6E6E6E0000ULL, 0x008D8D8D8D8D0000ULL, 0x0076767676760000ULL, -0x0003030303030000ULL, 0x002D2D2D2D2D0000ULL, 0x00DEDEDEDEDE0000ULL, 0x0096969696960000ULL, -0x0026262626260000ULL, 0x007D7D7D7D7D0000ULL, 0x00C6C6C6C6C60000ULL, 0x005C5C5C5C5C0000ULL, -0x00D3D3D3D3D30000ULL, 0x00F2F2F2F2F20000ULL, 0x004F4F4F4F4F0000ULL, 0x0019191919190000ULL, -0x003F3F3F3F3F0000ULL, 0x00DCDCDCDCDC0000ULL, 0x0079797979790000ULL, 0x001D1D1D1D1D0000ULL, -0x0052525252520000ULL, 0x00EBEBEBEBEB0000ULL, 0x00F3F3F3F3F30000ULL, 0x006D6D6D6D6D0000ULL, -0x005E5E5E5E5E0000ULL, 0x00FBFBFBFBFB0000ULL, 0x0069696969690000ULL, 0x00B2B2B2B2B20000ULL, -0x00F0F0F0F0F00000ULL, 0x0031313131310000ULL, 0x000C0C0C0C0C0000ULL, 0x00D4D4D4D4D40000ULL, -0x00CFCFCFCFCF0000ULL, 0x008C8C8C8C8C0000ULL, 0x00E2E2E2E2E20000ULL, 0x0075757575750000ULL, -0x00A9A9A9A9A90000ULL, 0x004A4A4A4A4A0000ULL, 0x0057575757570000ULL, 0x0084848484840000ULL, -0x0011111111110000ULL, 0x0045454545450000ULL, 0x001B1B1B1B1B0000ULL, 0x00F5F5F5F5F50000ULL, -0x00E4E4E4E4E40000ULL, 0x000E0E0E0E0E0000ULL, 0x0073737373730000ULL, 0x00AAAAAAAAAA0000ULL, -0x00F1F1F1F1F10000ULL, 0x00DDDDDDDDDD0000ULL, 0x0059595959590000ULL, 0x0014141414140000ULL, -0x006C6C6C6C6C0000ULL, 0x0092929292920000ULL, 0x0054545454540000ULL, 0x00D0D0D0D0D00000ULL, -0x0078787878780000ULL, 0x0070707070700000ULL, 0x00E3E3E3E3E30000ULL, 0x0049494949490000ULL, -0x0080808080800000ULL, 0x0050505050500000ULL, 0x00A7A7A7A7A70000ULL, 0x00F6F6F6F6F60000ULL, -0x0077777777770000ULL, 0x0093939393930000ULL, 0x0086868686860000ULL, 0x0083838383830000ULL, -0x002A2A2A2A2A0000ULL, 0x00C7C7C7C7C70000ULL, 0x005B5B5B5B5B0000ULL, 0x00E9E9E9E9E90000ULL, -0x00EEEEEEEEEE0000ULL, 0x008F8F8F8F8F0000ULL, 0x0001010101010000ULL, 0x003D3D3D3D3D0000ULL }; - -const u64bit Camellia_SBOX3[256] = { -0x3800383800383800ULL, 0x4100414100414100ULL, 0x1600161600161600ULL, 0x7600767600767600ULL, -0xD900D9D900D9D900ULL, 0x9300939300939300ULL, 0x6000606000606000ULL, 0xF200F2F200F2F200ULL, -0x7200727200727200ULL, 0xC200C2C200C2C200ULL, 0xAB00ABAB00ABAB00ULL, 0x9A009A9A009A9A00ULL, -0x7500757500757500ULL, 0x0600060600060600ULL, 0x5700575700575700ULL, 0xA000A0A000A0A000ULL, -0x9100919100919100ULL, 0xF700F7F700F7F700ULL, 0xB500B5B500B5B500ULL, 0xC900C9C900C9C900ULL, -0xA200A2A200A2A200ULL, 0x8C008C8C008C8C00ULL, 0xD200D2D200D2D200ULL, 0x9000909000909000ULL, -0xF600F6F600F6F600ULL, 0x0700070700070700ULL, 0xA700A7A700A7A700ULL, 0x2700272700272700ULL, -0x8E008E8E008E8E00ULL, 0xB200B2B200B2B200ULL, 0x4900494900494900ULL, 0xDE00DEDE00DEDE00ULL, -0x4300434300434300ULL, 0x5C005C5C005C5C00ULL, 0xD700D7D700D7D700ULL, 0xC700C7C700C7C700ULL, -0x3E003E3E003E3E00ULL, 0xF500F5F500F5F500ULL, 0x8F008F8F008F8F00ULL, 0x6700676700676700ULL, -0x1F001F1F001F1F00ULL, 0x1800181800181800ULL, 0x6E006E6E006E6E00ULL, 0xAF00AFAF00AFAF00ULL, -0x2F002F2F002F2F00ULL, 0xE200E2E200E2E200ULL, 0x8500858500858500ULL, 0x0D000D0D000D0D00ULL, -0x5300535300535300ULL, 0xF000F0F000F0F000ULL, 0x9C009C9C009C9C00ULL, 0x6500656500656500ULL, -0xEA00EAEA00EAEA00ULL, 0xA300A3A300A3A300ULL, 0xAE00AEAE00AEAE00ULL, 0x9E009E9E009E9E00ULL, -0xEC00ECEC00ECEC00ULL, 0x8000808000808000ULL, 0x2D002D2D002D2D00ULL, 0x6B006B6B006B6B00ULL, -0xA800A8A800A8A800ULL, 0x2B002B2B002B2B00ULL, 0x3600363600363600ULL, 0xA600A6A600A6A600ULL, -0xC500C5C500C5C500ULL, 0x8600868600868600ULL, 0x4D004D4D004D4D00ULL, 0x3300333300333300ULL, -0xFD00FDFD00FDFD00ULL, 0x6600666600666600ULL, 0x5800585800585800ULL, 0x9600969600969600ULL, -0x3A003A3A003A3A00ULL, 0x0900090900090900ULL, 0x9500959500959500ULL, 0x1000101000101000ULL, -0x7800787800787800ULL, 0xD800D8D800D8D800ULL, 0x4200424200424200ULL, 0xCC00CCCC00CCCC00ULL, -0xEF00EFEF00EFEF00ULL, 0x2600262600262600ULL, 0xE500E5E500E5E500ULL, 0x6100616100616100ULL, -0x1A001A1A001A1A00ULL, 0x3F003F3F003F3F00ULL, 0x3B003B3B003B3B00ULL, 0x8200828200828200ULL, -0xB600B6B600B6B600ULL, 0xDB00DBDB00DBDB00ULL, 0xD400D4D400D4D400ULL, 0x9800989800989800ULL, -0xE800E8E800E8E800ULL, 0x8B008B8B008B8B00ULL, 0x0200020200020200ULL, 0xEB00EBEB00EBEB00ULL, -0x0A000A0A000A0A00ULL, 0x2C002C2C002C2C00ULL, 0x1D001D1D001D1D00ULL, 0xB000B0B000B0B000ULL, -0x6F006F6F006F6F00ULL, 0x8D008D8D008D8D00ULL, 0x8800888800888800ULL, 0x0E000E0E000E0E00ULL, -0x1900191900191900ULL, 0x8700878700878700ULL, 0x4E004E4E004E4E00ULL, 0x0B000B0B000B0B00ULL, -0xA900A9A900A9A900ULL, 0x0C000C0C000C0C00ULL, 0x7900797900797900ULL, 0x1100111100111100ULL, -0x7F007F7F007F7F00ULL, 0x2200222200222200ULL, 0xE700E7E700E7E700ULL, 0x5900595900595900ULL, -0xE100E1E100E1E100ULL, 0xDA00DADA00DADA00ULL, 0x3D003D3D003D3D00ULL, 0xC800C8C800C8C800ULL, -0x1200121200121200ULL, 0x0400040400040400ULL, 0x7400747400747400ULL, 0x5400545400545400ULL, -0x3000303000303000ULL, 0x7E007E7E007E7E00ULL, 0xB400B4B400B4B400ULL, 0x2800282800282800ULL, -0x5500555500555500ULL, 0x6800686800686800ULL, 0x5000505000505000ULL, 0xBE00BEBE00BEBE00ULL, -0xD000D0D000D0D000ULL, 0xC400C4C400C4C400ULL, 0x3100313100313100ULL, 0xCB00CBCB00CBCB00ULL, -0x2A002A2A002A2A00ULL, 0xAD00ADAD00ADAD00ULL, 0x0F000F0F000F0F00ULL, 0xCA00CACA00CACA00ULL, -0x7000707000707000ULL, 0xFF00FFFF00FFFF00ULL, 0x3200323200323200ULL, 0x6900696900696900ULL, -0x0800080800080800ULL, 0x6200626200626200ULL, 0x0000000000000000ULL, 0x2400242400242400ULL, -0xD100D1D100D1D100ULL, 0xFB00FBFB00FBFB00ULL, 0xBA00BABA00BABA00ULL, 0xED00EDED00EDED00ULL, -0x4500454500454500ULL, 0x8100818100818100ULL, 0x7300737300737300ULL, 0x6D006D6D006D6D00ULL, -0x8400848400848400ULL, 0x9F009F9F009F9F00ULL, 0xEE00EEEE00EEEE00ULL, 0x4A004A4A004A4A00ULL, -0xC300C3C300C3C300ULL, 0x2E002E2E002E2E00ULL, 0xC100C1C100C1C100ULL, 0x0100010100010100ULL, -0xE600E6E600E6E600ULL, 0x2500252500252500ULL, 0x4800484800484800ULL, 0x9900999900999900ULL, -0xB900B9B900B9B900ULL, 0xB300B3B300B3B300ULL, 0x7B007B7B007B7B00ULL, 0xF900F9F900F9F900ULL, -0xCE00CECE00CECE00ULL, 0xBF00BFBF00BFBF00ULL, 0xDF00DFDF00DFDF00ULL, 0x7100717100717100ULL, -0x2900292900292900ULL, 0xCD00CDCD00CDCD00ULL, 0x6C006C6C006C6C00ULL, 0x1300131300131300ULL, -0x6400646400646400ULL, 0x9B009B9B009B9B00ULL, 0x6300636300636300ULL, 0x9D009D9D009D9D00ULL, -0xC000C0C000C0C000ULL, 0x4B004B4B004B4B00ULL, 0xB700B7B700B7B700ULL, 0xA500A5A500A5A500ULL, -0x8900898900898900ULL, 0x5F005F5F005F5F00ULL, 0xB100B1B100B1B100ULL, 0x1700171700171700ULL, -0xF400F4F400F4F400ULL, 0xBC00BCBC00BCBC00ULL, 0xD300D3D300D3D300ULL, 0x4600464600464600ULL, -0xCF00CFCF00CFCF00ULL, 0x3700373700373700ULL, 0x5E005E5E005E5E00ULL, 0x4700474700474700ULL, -0x9400949400949400ULL, 0xFA00FAFA00FAFA00ULL, 0xFC00FCFC00FCFC00ULL, 0x5B005B5B005B5B00ULL, -0x9700979700979700ULL, 0xFE00FEFE00FEFE00ULL, 0x5A005A5A005A5A00ULL, 0xAC00ACAC00ACAC00ULL, -0x3C003C3C003C3C00ULL, 0x4C004C4C004C4C00ULL, 0x0300030300030300ULL, 0x3500353500353500ULL, -0xF300F3F300F3F300ULL, 0x2300232300232300ULL, 0xB800B8B800B8B800ULL, 0x5D005D5D005D5D00ULL, -0x6A006A6A006A6A00ULL, 0x9200929200929200ULL, 0xD500D5D500D5D500ULL, 0x2100212100212100ULL, -0x4400444400444400ULL, 0x5100515100515100ULL, 0xC600C6C600C6C600ULL, 0x7D007D7D007D7D00ULL, -0x3900393900393900ULL, 0x8300838300838300ULL, 0xDC00DCDC00DCDC00ULL, 0xAA00AAAA00AAAA00ULL, -0x7C007C7C007C7C00ULL, 0x7700777700777700ULL, 0x5600565600565600ULL, 0x0500050500050500ULL, -0x1B001B1B001B1B00ULL, 0xA400A4A400A4A400ULL, 0x1500151500151500ULL, 0x3400343400343400ULL, -0x1E001E1E001E1E00ULL, 0x1C001C1C001C1C00ULL, 0xF800F8F800F8F800ULL, 0x5200525200525200ULL, -0x2000202000202000ULL, 0x1400141400141400ULL, 0xE900E9E900E9E900ULL, 0xBD00BDBD00BDBD00ULL, -0xDD00DDDD00DDDD00ULL, 0xE400E4E400E4E400ULL, 0xA100A1A100A1A100ULL, 0xE000E0E000E0E000ULL, -0x8A008A8A008A8A00ULL, 0xF100F1F100F1F100ULL, 0xD600D6D600D6D600ULL, 0x7A007A7A007A7A00ULL, -0xBB00BBBB00BBBB00ULL, 0xE300E3E300E3E300ULL, 0x4000404000404000ULL, 0x4F004F4F004F4F00ULL }; - -const u64bit Camellia_SBOX4[256] = { -0x7070007000007070ULL, 0x2C2C002C00002C2CULL, 0xB3B300B30000B3B3ULL, 0xC0C000C00000C0C0ULL, -0xE4E400E40000E4E4ULL, 0x5757005700005757ULL, 0xEAEA00EA0000EAEAULL, 0xAEAE00AE0000AEAEULL, -0x2323002300002323ULL, 0x6B6B006B00006B6BULL, 0x4545004500004545ULL, 0xA5A500A50000A5A5ULL, -0xEDED00ED0000EDEDULL, 0x4F4F004F00004F4FULL, 0x1D1D001D00001D1DULL, 0x9292009200009292ULL, -0x8686008600008686ULL, 0xAFAF00AF0000AFAFULL, 0x7C7C007C00007C7CULL, 0x1F1F001F00001F1FULL, -0x3E3E003E00003E3EULL, 0xDCDC00DC0000DCDCULL, 0x5E5E005E00005E5EULL, 0x0B0B000B00000B0BULL, -0xA6A600A60000A6A6ULL, 0x3939003900003939ULL, 0xD5D500D50000D5D5ULL, 0x5D5D005D00005D5DULL, -0xD9D900D90000D9D9ULL, 0x5A5A005A00005A5AULL, 0x5151005100005151ULL, 0x6C6C006C00006C6CULL, -0x8B8B008B00008B8BULL, 0x9A9A009A00009A9AULL, 0xFBFB00FB0000FBFBULL, 0xB0B000B00000B0B0ULL, -0x7474007400007474ULL, 0x2B2B002B00002B2BULL, 0xF0F000F00000F0F0ULL, 0x8484008400008484ULL, -0xDFDF00DF0000DFDFULL, 0xCBCB00CB0000CBCBULL, 0x3434003400003434ULL, 0x7676007600007676ULL, -0x6D6D006D00006D6DULL, 0xA9A900A90000A9A9ULL, 0xD1D100D10000D1D1ULL, 0x0404000400000404ULL, -0x1414001400001414ULL, 0x3A3A003A00003A3AULL, 0xDEDE00DE0000DEDEULL, 0x1111001100001111ULL, -0x3232003200003232ULL, 0x9C9C009C00009C9CULL, 0x5353005300005353ULL, 0xF2F200F20000F2F2ULL, -0xFEFE00FE0000FEFEULL, 0xCFCF00CF0000CFCFULL, 0xC3C300C30000C3C3ULL, 0x7A7A007A00007A7AULL, -0x2424002400002424ULL, 0xE8E800E80000E8E8ULL, 0x6060006000006060ULL, 0x6969006900006969ULL, -0xAAAA00AA0000AAAAULL, 0xA0A000A00000A0A0ULL, 0xA1A100A10000A1A1ULL, 0x6262006200006262ULL, -0x5454005400005454ULL, 0x1E1E001E00001E1EULL, 0xE0E000E00000E0E0ULL, 0x6464006400006464ULL, -0x1010001000001010ULL, 0x0000000000000000ULL, 0xA3A300A30000A3A3ULL, 0x7575007500007575ULL, -0x8A8A008A00008A8AULL, 0xE6E600E60000E6E6ULL, 0x0909000900000909ULL, 0xDDDD00DD0000DDDDULL, -0x8787008700008787ULL, 0x8383008300008383ULL, 0xCDCD00CD0000CDCDULL, 0x9090009000009090ULL, -0x7373007300007373ULL, 0xF6F600F60000F6F6ULL, 0x9D9D009D00009D9DULL, 0xBFBF00BF0000BFBFULL, -0x5252005200005252ULL, 0xD8D800D80000D8D8ULL, 0xC8C800C80000C8C8ULL, 0xC6C600C60000C6C6ULL, -0x8181008100008181ULL, 0x6F6F006F00006F6FULL, 0x1313001300001313ULL, 0x6363006300006363ULL, -0xE9E900E90000E9E9ULL, 0xA7A700A70000A7A7ULL, 0x9F9F009F00009F9FULL, 0xBCBC00BC0000BCBCULL, -0x2929002900002929ULL, 0xF9F900F90000F9F9ULL, 0x2F2F002F00002F2FULL, 0xB4B400B40000B4B4ULL, -0x7878007800007878ULL, 0x0606000600000606ULL, 0xE7E700E70000E7E7ULL, 0x7171007100007171ULL, -0xD4D400D40000D4D4ULL, 0xABAB00AB0000ABABULL, 0x8888008800008888ULL, 0x8D8D008D00008D8DULL, -0x7272007200007272ULL, 0xB9B900B90000B9B9ULL, 0xF8F800F80000F8F8ULL, 0xACAC00AC0000ACACULL, -0x3636003600003636ULL, 0x2A2A002A00002A2AULL, 0x3C3C003C00003C3CULL, 0xF1F100F10000F1F1ULL, -0x4040004000004040ULL, 0xD3D300D30000D3D3ULL, 0xBBBB00BB0000BBBBULL, 0x4343004300004343ULL, -0x1515001500001515ULL, 0xADAD00AD0000ADADULL, 0x7777007700007777ULL, 0x8080008000008080ULL, -0x8282008200008282ULL, 0xECEC00EC0000ECECULL, 0x2727002700002727ULL, 0xE5E500E50000E5E5ULL, -0x8585008500008585ULL, 0x3535003500003535ULL, 0x0C0C000C00000C0CULL, 0x4141004100004141ULL, -0xEFEF00EF0000EFEFULL, 0x9393009300009393ULL, 0x1919001900001919ULL, 0x2121002100002121ULL, -0x0E0E000E00000E0EULL, 0x4E4E004E00004E4EULL, 0x6565006500006565ULL, 0xBDBD00BD0000BDBDULL, -0xB8B800B80000B8B8ULL, 0x8F8F008F00008F8FULL, 0xEBEB00EB0000EBEBULL, 0xCECE00CE0000CECEULL, -0x3030003000003030ULL, 0x5F5F005F00005F5FULL, 0xC5C500C50000C5C5ULL, 0x1A1A001A00001A1AULL, -0xE1E100E10000E1E1ULL, 0xCACA00CA0000CACAULL, 0x4747004700004747ULL, 0x3D3D003D00003D3DULL, -0x0101000100000101ULL, 0xD6D600D60000D6D6ULL, 0x5656005600005656ULL, 0x4D4D004D00004D4DULL, -0x0D0D000D00000D0DULL, 0x6666006600006666ULL, 0xCCCC00CC0000CCCCULL, 0x2D2D002D00002D2DULL, -0x1212001200001212ULL, 0x2020002000002020ULL, 0xB1B100B10000B1B1ULL, 0x9999009900009999ULL, -0x4C4C004C00004C4CULL, 0xC2C200C20000C2C2ULL, 0x7E7E007E00007E7EULL, 0x0505000500000505ULL, -0xB7B700B70000B7B7ULL, 0x3131003100003131ULL, 0x1717001700001717ULL, 0xD7D700D70000D7D7ULL, -0x5858005800005858ULL, 0x6161006100006161ULL, 0x1B1B001B00001B1BULL, 0x1C1C001C00001C1CULL, -0x0F0F000F00000F0FULL, 0x1616001600001616ULL, 0x1818001800001818ULL, 0x2222002200002222ULL, -0x4444004400004444ULL, 0xB2B200B20000B2B2ULL, 0xB5B500B50000B5B5ULL, 0x9191009100009191ULL, -0x0808000800000808ULL, 0xA8A800A80000A8A8ULL, 0xFCFC00FC0000FCFCULL, 0x5050005000005050ULL, -0xD0D000D00000D0D0ULL, 0x7D7D007D00007D7DULL, 0x8989008900008989ULL, 0x9797009700009797ULL, -0x5B5B005B00005B5BULL, 0x9595009500009595ULL, 0xFFFF00FF0000FFFFULL, 0xD2D200D20000D2D2ULL, -0xC4C400C40000C4C4ULL, 0x4848004800004848ULL, 0xF7F700F70000F7F7ULL, 0xDBDB00DB0000DBDBULL, -0x0303000300000303ULL, 0xDADA00DA0000DADAULL, 0x3F3F003F00003F3FULL, 0x9494009400009494ULL, -0x5C5C005C00005C5CULL, 0x0202000200000202ULL, 0x4A4A004A00004A4AULL, 0x3333003300003333ULL, -0x6767006700006767ULL, 0xF3F300F30000F3F3ULL, 0x7F7F007F00007F7FULL, 0xE2E200E20000E2E2ULL, -0x9B9B009B00009B9BULL, 0x2626002600002626ULL, 0x3737003700003737ULL, 0x3B3B003B00003B3BULL, -0x9696009600009696ULL, 0x4B4B004B00004B4BULL, 0xBEBE00BE0000BEBEULL, 0x2E2E002E00002E2EULL, -0x7979007900007979ULL, 0x8C8C008C00008C8CULL, 0x6E6E006E00006E6EULL, 0x8E8E008E00008E8EULL, -0xF5F500F50000F5F5ULL, 0xB6B600B60000B6B6ULL, 0xFDFD00FD0000FDFDULL, 0x5959005900005959ULL, -0x9898009800009898ULL, 0x6A6A006A00006A6AULL, 0x4646004600004646ULL, 0xBABA00BA0000BABAULL, -0x2525002500002525ULL, 0x4242004200004242ULL, 0xA2A200A20000A2A2ULL, 0xFAFA00FA0000FAFAULL, -0x0707000700000707ULL, 0x5555005500005555ULL, 0xEEEE00EE0000EEEEULL, 0x0A0A000A00000A0AULL, -0x4949004900004949ULL, 0x6868006800006868ULL, 0x3838003800003838ULL, 0xA4A400A40000A4A4ULL, -0x2828002800002828ULL, 0x7B7B007B00007B7BULL, 0xC9C900C90000C9C9ULL, 0xC1C100C10000C1C1ULL, -0xE3E300E30000E3E3ULL, 0xF4F400F40000F4F4ULL, 0xC7C700C70000C7C7ULL, 0x9E9E009E00009E9EULL }; - -const u64bit Camellia_SBOX5[256] = { -0x00E0E0E000E0E0E0ULL, 0x0005050500050505ULL, 0x0058585800585858ULL, 0x00D9D9D900D9D9D9ULL, -0x0067676700676767ULL, 0x004E4E4E004E4E4EULL, 0x0081818100818181ULL, 0x00CBCBCB00CBCBCBULL, -0x00C9C9C900C9C9C9ULL, 0x000B0B0B000B0B0BULL, 0x00AEAEAE00AEAEAEULL, 0x006A6A6A006A6A6AULL, -0x00D5D5D500D5D5D5ULL, 0x0018181800181818ULL, 0x005D5D5D005D5D5DULL, 0x0082828200828282ULL, -0x0046464600464646ULL, 0x00DFDFDF00DFDFDFULL, 0x00D6D6D600D6D6D6ULL, 0x0027272700272727ULL, -0x008A8A8A008A8A8AULL, 0x0032323200323232ULL, 0x004B4B4B004B4B4BULL, 0x0042424200424242ULL, -0x00DBDBDB00DBDBDBULL, 0x001C1C1C001C1C1CULL, 0x009E9E9E009E9E9EULL, 0x009C9C9C009C9C9CULL, -0x003A3A3A003A3A3AULL, 0x00CACACA00CACACAULL, 0x0025252500252525ULL, 0x007B7B7B007B7B7BULL, -0x000D0D0D000D0D0DULL, 0x0071717100717171ULL, 0x005F5F5F005F5F5FULL, 0x001F1F1F001F1F1FULL, -0x00F8F8F800F8F8F8ULL, 0x00D7D7D700D7D7D7ULL, 0x003E3E3E003E3E3EULL, 0x009D9D9D009D9D9DULL, -0x007C7C7C007C7C7CULL, 0x0060606000606060ULL, 0x00B9B9B900B9B9B9ULL, 0x00BEBEBE00BEBEBEULL, -0x00BCBCBC00BCBCBCULL, 0x008B8B8B008B8B8BULL, 0x0016161600161616ULL, 0x0034343400343434ULL, -0x004D4D4D004D4D4DULL, 0x00C3C3C300C3C3C3ULL, 0x0072727200727272ULL, 0x0095959500959595ULL, -0x00ABABAB00ABABABULL, 0x008E8E8E008E8E8EULL, 0x00BABABA00BABABAULL, 0x007A7A7A007A7A7AULL, -0x00B3B3B300B3B3B3ULL, 0x0002020200020202ULL, 0x00B4B4B400B4B4B4ULL, 0x00ADADAD00ADADADULL, -0x00A2A2A200A2A2A2ULL, 0x00ACACAC00ACACACULL, 0x00D8D8D800D8D8D8ULL, 0x009A9A9A009A9A9AULL, -0x0017171700171717ULL, 0x001A1A1A001A1A1AULL, 0x0035353500353535ULL, 0x00CCCCCC00CCCCCCULL, -0x00F7F7F700F7F7F7ULL, 0x0099999900999999ULL, 0x0061616100616161ULL, 0x005A5A5A005A5A5AULL, -0x00E8E8E800E8E8E8ULL, 0x0024242400242424ULL, 0x0056565600565656ULL, 0x0040404000404040ULL, -0x00E1E1E100E1E1E1ULL, 0x0063636300636363ULL, 0x0009090900090909ULL, 0x0033333300333333ULL, -0x00BFBFBF00BFBFBFULL, 0x0098989800989898ULL, 0x0097979700979797ULL, 0x0085858500858585ULL, -0x0068686800686868ULL, 0x00FCFCFC00FCFCFCULL, 0x00ECECEC00ECECECULL, 0x000A0A0A000A0A0AULL, -0x00DADADA00DADADAULL, 0x006F6F6F006F6F6FULL, 0x0053535300535353ULL, 0x0062626200626262ULL, -0x00A3A3A300A3A3A3ULL, 0x002E2E2E002E2E2EULL, 0x0008080800080808ULL, 0x00AFAFAF00AFAFAFULL, -0x0028282800282828ULL, 0x00B0B0B000B0B0B0ULL, 0x0074747400747474ULL, 0x00C2C2C200C2C2C2ULL, -0x00BDBDBD00BDBDBDULL, 0x0036363600363636ULL, 0x0022222200222222ULL, 0x0038383800383838ULL, -0x0064646400646464ULL, 0x001E1E1E001E1E1EULL, 0x0039393900393939ULL, 0x002C2C2C002C2C2CULL, -0x00A6A6A600A6A6A6ULL, 0x0030303000303030ULL, 0x00E5E5E500E5E5E5ULL, 0x0044444400444444ULL, -0x00FDFDFD00FDFDFDULL, 0x0088888800888888ULL, 0x009F9F9F009F9F9FULL, 0x0065656500656565ULL, -0x0087878700878787ULL, 0x006B6B6B006B6B6BULL, 0x00F4F4F400F4F4F4ULL, 0x0023232300232323ULL, -0x0048484800484848ULL, 0x0010101000101010ULL, 0x00D1D1D100D1D1D1ULL, 0x0051515100515151ULL, -0x00C0C0C000C0C0C0ULL, 0x00F9F9F900F9F9F9ULL, 0x00D2D2D200D2D2D2ULL, 0x00A0A0A000A0A0A0ULL, -0x0055555500555555ULL, 0x00A1A1A100A1A1A1ULL, 0x0041414100414141ULL, 0x00FAFAFA00FAFAFAULL, -0x0043434300434343ULL, 0x0013131300131313ULL, 0x00C4C4C400C4C4C4ULL, 0x002F2F2F002F2F2FULL, -0x00A8A8A800A8A8A8ULL, 0x00B6B6B600B6B6B6ULL, 0x003C3C3C003C3C3CULL, 0x002B2B2B002B2B2BULL, -0x00C1C1C100C1C1C1ULL, 0x00FFFFFF00FFFFFFULL, 0x00C8C8C800C8C8C8ULL, 0x00A5A5A500A5A5A5ULL, -0x0020202000202020ULL, 0x0089898900898989ULL, 0x0000000000000000ULL, 0x0090909000909090ULL, -0x0047474700474747ULL, 0x00EFEFEF00EFEFEFULL, 0x00EAEAEA00EAEAEAULL, 0x00B7B7B700B7B7B7ULL, -0x0015151500151515ULL, 0x0006060600060606ULL, 0x00CDCDCD00CDCDCDULL, 0x00B5B5B500B5B5B5ULL, -0x0012121200121212ULL, 0x007E7E7E007E7E7EULL, 0x00BBBBBB00BBBBBBULL, 0x0029292900292929ULL, -0x000F0F0F000F0F0FULL, 0x00B8B8B800B8B8B8ULL, 0x0007070700070707ULL, 0x0004040400040404ULL, -0x009B9B9B009B9B9BULL, 0x0094949400949494ULL, 0x0021212100212121ULL, 0x0066666600666666ULL, -0x00E6E6E600E6E6E6ULL, 0x00CECECE00CECECEULL, 0x00EDEDED00EDEDEDULL, 0x00E7E7E700E7E7E7ULL, -0x003B3B3B003B3B3BULL, 0x00FEFEFE00FEFEFEULL, 0x007F7F7F007F7F7FULL, 0x00C5C5C500C5C5C5ULL, -0x00A4A4A400A4A4A4ULL, 0x0037373700373737ULL, 0x00B1B1B100B1B1B1ULL, 0x004C4C4C004C4C4CULL, -0x0091919100919191ULL, 0x006E6E6E006E6E6EULL, 0x008D8D8D008D8D8DULL, 0x0076767600767676ULL, -0x0003030300030303ULL, 0x002D2D2D002D2D2DULL, 0x00DEDEDE00DEDEDEULL, 0x0096969600969696ULL, -0x0026262600262626ULL, 0x007D7D7D007D7D7DULL, 0x00C6C6C600C6C6C6ULL, 0x005C5C5C005C5C5CULL, -0x00D3D3D300D3D3D3ULL, 0x00F2F2F200F2F2F2ULL, 0x004F4F4F004F4F4FULL, 0x0019191900191919ULL, -0x003F3F3F003F3F3FULL, 0x00DCDCDC00DCDCDCULL, 0x0079797900797979ULL, 0x001D1D1D001D1D1DULL, -0x0052525200525252ULL, 0x00EBEBEB00EBEBEBULL, 0x00F3F3F300F3F3F3ULL, 0x006D6D6D006D6D6DULL, -0x005E5E5E005E5E5EULL, 0x00FBFBFB00FBFBFBULL, 0x0069696900696969ULL, 0x00B2B2B200B2B2B2ULL, -0x00F0F0F000F0F0F0ULL, 0x0031313100313131ULL, 0x000C0C0C000C0C0CULL, 0x00D4D4D400D4D4D4ULL, -0x00CFCFCF00CFCFCFULL, 0x008C8C8C008C8C8CULL, 0x00E2E2E200E2E2E2ULL, 0x0075757500757575ULL, -0x00A9A9A900A9A9A9ULL, 0x004A4A4A004A4A4AULL, 0x0057575700575757ULL, 0x0084848400848484ULL, -0x0011111100111111ULL, 0x0045454500454545ULL, 0x001B1B1B001B1B1BULL, 0x00F5F5F500F5F5F5ULL, -0x00E4E4E400E4E4E4ULL, 0x000E0E0E000E0E0EULL, 0x0073737300737373ULL, 0x00AAAAAA00AAAAAAULL, -0x00F1F1F100F1F1F1ULL, 0x00DDDDDD00DDDDDDULL, 0x0059595900595959ULL, 0x0014141400141414ULL, -0x006C6C6C006C6C6CULL, 0x0092929200929292ULL, 0x0054545400545454ULL, 0x00D0D0D000D0D0D0ULL, -0x0078787800787878ULL, 0x0070707000707070ULL, 0x00E3E3E300E3E3E3ULL, 0x0049494900494949ULL, -0x0080808000808080ULL, 0x0050505000505050ULL, 0x00A7A7A700A7A7A7ULL, 0x00F6F6F600F6F6F6ULL, -0x0077777700777777ULL, 0x0093939300939393ULL, 0x0086868600868686ULL, 0x0083838300838383ULL, -0x002A2A2A002A2A2AULL, 0x00C7C7C700C7C7C7ULL, 0x005B5B5B005B5B5BULL, 0x00E9E9E900E9E9E9ULL, -0x00EEEEEE00EEEEEEULL, 0x008F8F8F008F8F8FULL, 0x0001010100010101ULL, 0x003D3D3D003D3D3DULL }; - -const u64bit Camellia_SBOX6[256] = { -0x3800383838003838ULL, 0x4100414141004141ULL, 0x1600161616001616ULL, 0x7600767676007676ULL, -0xD900D9D9D900D9D9ULL, 0x9300939393009393ULL, 0x6000606060006060ULL, 0xF200F2F2F200F2F2ULL, -0x7200727272007272ULL, 0xC200C2C2C200C2C2ULL, 0xAB00ABABAB00ABABULL, 0x9A009A9A9A009A9AULL, -0x7500757575007575ULL, 0x0600060606000606ULL, 0x5700575757005757ULL, 0xA000A0A0A000A0A0ULL, -0x9100919191009191ULL, 0xF700F7F7F700F7F7ULL, 0xB500B5B5B500B5B5ULL, 0xC900C9C9C900C9C9ULL, -0xA200A2A2A200A2A2ULL, 0x8C008C8C8C008C8CULL, 0xD200D2D2D200D2D2ULL, 0x9000909090009090ULL, -0xF600F6F6F600F6F6ULL, 0x0700070707000707ULL, 0xA700A7A7A700A7A7ULL, 0x2700272727002727ULL, -0x8E008E8E8E008E8EULL, 0xB200B2B2B200B2B2ULL, 0x4900494949004949ULL, 0xDE00DEDEDE00DEDEULL, -0x4300434343004343ULL, 0x5C005C5C5C005C5CULL, 0xD700D7D7D700D7D7ULL, 0xC700C7C7C700C7C7ULL, -0x3E003E3E3E003E3EULL, 0xF500F5F5F500F5F5ULL, 0x8F008F8F8F008F8FULL, 0x6700676767006767ULL, -0x1F001F1F1F001F1FULL, 0x1800181818001818ULL, 0x6E006E6E6E006E6EULL, 0xAF00AFAFAF00AFAFULL, -0x2F002F2F2F002F2FULL, 0xE200E2E2E200E2E2ULL, 0x8500858585008585ULL, 0x0D000D0D0D000D0DULL, -0x5300535353005353ULL, 0xF000F0F0F000F0F0ULL, 0x9C009C9C9C009C9CULL, 0x6500656565006565ULL, -0xEA00EAEAEA00EAEAULL, 0xA300A3A3A300A3A3ULL, 0xAE00AEAEAE00AEAEULL, 0x9E009E9E9E009E9EULL, -0xEC00ECECEC00ECECULL, 0x8000808080008080ULL, 0x2D002D2D2D002D2DULL, 0x6B006B6B6B006B6BULL, -0xA800A8A8A800A8A8ULL, 0x2B002B2B2B002B2BULL, 0x3600363636003636ULL, 0xA600A6A6A600A6A6ULL, -0xC500C5C5C500C5C5ULL, 0x8600868686008686ULL, 0x4D004D4D4D004D4DULL, 0x3300333333003333ULL, -0xFD00FDFDFD00FDFDULL, 0x6600666666006666ULL, 0x5800585858005858ULL, 0x9600969696009696ULL, -0x3A003A3A3A003A3AULL, 0x0900090909000909ULL, 0x9500959595009595ULL, 0x1000101010001010ULL, -0x7800787878007878ULL, 0xD800D8D8D800D8D8ULL, 0x4200424242004242ULL, 0xCC00CCCCCC00CCCCULL, -0xEF00EFEFEF00EFEFULL, 0x2600262626002626ULL, 0xE500E5E5E500E5E5ULL, 0x6100616161006161ULL, -0x1A001A1A1A001A1AULL, 0x3F003F3F3F003F3FULL, 0x3B003B3B3B003B3BULL, 0x8200828282008282ULL, -0xB600B6B6B600B6B6ULL, 0xDB00DBDBDB00DBDBULL, 0xD400D4D4D400D4D4ULL, 0x9800989898009898ULL, -0xE800E8E8E800E8E8ULL, 0x8B008B8B8B008B8BULL, 0x0200020202000202ULL, 0xEB00EBEBEB00EBEBULL, -0x0A000A0A0A000A0AULL, 0x2C002C2C2C002C2CULL, 0x1D001D1D1D001D1DULL, 0xB000B0B0B000B0B0ULL, -0x6F006F6F6F006F6FULL, 0x8D008D8D8D008D8DULL, 0x8800888888008888ULL, 0x0E000E0E0E000E0EULL, -0x1900191919001919ULL, 0x8700878787008787ULL, 0x4E004E4E4E004E4EULL, 0x0B000B0B0B000B0BULL, -0xA900A9A9A900A9A9ULL, 0x0C000C0C0C000C0CULL, 0x7900797979007979ULL, 0x1100111111001111ULL, -0x7F007F7F7F007F7FULL, 0x2200222222002222ULL, 0xE700E7E7E700E7E7ULL, 0x5900595959005959ULL, -0xE100E1E1E100E1E1ULL, 0xDA00DADADA00DADAULL, 0x3D003D3D3D003D3DULL, 0xC800C8C8C800C8C8ULL, -0x1200121212001212ULL, 0x0400040404000404ULL, 0x7400747474007474ULL, 0x5400545454005454ULL, -0x3000303030003030ULL, 0x7E007E7E7E007E7EULL, 0xB400B4B4B400B4B4ULL, 0x2800282828002828ULL, -0x5500555555005555ULL, 0x6800686868006868ULL, 0x5000505050005050ULL, 0xBE00BEBEBE00BEBEULL, -0xD000D0D0D000D0D0ULL, 0xC400C4C4C400C4C4ULL, 0x3100313131003131ULL, 0xCB00CBCBCB00CBCBULL, -0x2A002A2A2A002A2AULL, 0xAD00ADADAD00ADADULL, 0x0F000F0F0F000F0FULL, 0xCA00CACACA00CACAULL, -0x7000707070007070ULL, 0xFF00FFFFFF00FFFFULL, 0x3200323232003232ULL, 0x6900696969006969ULL, -0x0800080808000808ULL, 0x6200626262006262ULL, 0x0000000000000000ULL, 0x2400242424002424ULL, -0xD100D1D1D100D1D1ULL, 0xFB00FBFBFB00FBFBULL, 0xBA00BABABA00BABAULL, 0xED00EDEDED00EDEDULL, -0x4500454545004545ULL, 0x8100818181008181ULL, 0x7300737373007373ULL, 0x6D006D6D6D006D6DULL, -0x8400848484008484ULL, 0x9F009F9F9F009F9FULL, 0xEE00EEEEEE00EEEEULL, 0x4A004A4A4A004A4AULL, -0xC300C3C3C300C3C3ULL, 0x2E002E2E2E002E2EULL, 0xC100C1C1C100C1C1ULL, 0x0100010101000101ULL, -0xE600E6E6E600E6E6ULL, 0x2500252525002525ULL, 0x4800484848004848ULL, 0x9900999999009999ULL, -0xB900B9B9B900B9B9ULL, 0xB300B3B3B300B3B3ULL, 0x7B007B7B7B007B7BULL, 0xF900F9F9F900F9F9ULL, -0xCE00CECECE00CECEULL, 0xBF00BFBFBF00BFBFULL, 0xDF00DFDFDF00DFDFULL, 0x7100717171007171ULL, -0x2900292929002929ULL, 0xCD00CDCDCD00CDCDULL, 0x6C006C6C6C006C6CULL, 0x1300131313001313ULL, -0x6400646464006464ULL, 0x9B009B9B9B009B9BULL, 0x6300636363006363ULL, 0x9D009D9D9D009D9DULL, -0xC000C0C0C000C0C0ULL, 0x4B004B4B4B004B4BULL, 0xB700B7B7B700B7B7ULL, 0xA500A5A5A500A5A5ULL, -0x8900898989008989ULL, 0x5F005F5F5F005F5FULL, 0xB100B1B1B100B1B1ULL, 0x1700171717001717ULL, -0xF400F4F4F400F4F4ULL, 0xBC00BCBCBC00BCBCULL, 0xD300D3D3D300D3D3ULL, 0x4600464646004646ULL, -0xCF00CFCFCF00CFCFULL, 0x3700373737003737ULL, 0x5E005E5E5E005E5EULL, 0x4700474747004747ULL, -0x9400949494009494ULL, 0xFA00FAFAFA00FAFAULL, 0xFC00FCFCFC00FCFCULL, 0x5B005B5B5B005B5BULL, -0x9700979797009797ULL, 0xFE00FEFEFE00FEFEULL, 0x5A005A5A5A005A5AULL, 0xAC00ACACAC00ACACULL, -0x3C003C3C3C003C3CULL, 0x4C004C4C4C004C4CULL, 0x0300030303000303ULL, 0x3500353535003535ULL, -0xF300F3F3F300F3F3ULL, 0x2300232323002323ULL, 0xB800B8B8B800B8B8ULL, 0x5D005D5D5D005D5DULL, -0x6A006A6A6A006A6AULL, 0x9200929292009292ULL, 0xD500D5D5D500D5D5ULL, 0x2100212121002121ULL, -0x4400444444004444ULL, 0x5100515151005151ULL, 0xC600C6C6C600C6C6ULL, 0x7D007D7D7D007D7DULL, -0x3900393939003939ULL, 0x8300838383008383ULL, 0xDC00DCDCDC00DCDCULL, 0xAA00AAAAAA00AAAAULL, -0x7C007C7C7C007C7CULL, 0x7700777777007777ULL, 0x5600565656005656ULL, 0x0500050505000505ULL, -0x1B001B1B1B001B1BULL, 0xA400A4A4A400A4A4ULL, 0x1500151515001515ULL, 0x3400343434003434ULL, -0x1E001E1E1E001E1EULL, 0x1C001C1C1C001C1CULL, 0xF800F8F8F800F8F8ULL, 0x5200525252005252ULL, -0x2000202020002020ULL, 0x1400141414001414ULL, 0xE900E9E9E900E9E9ULL, 0xBD00BDBDBD00BDBDULL, -0xDD00DDDDDD00DDDDULL, 0xE400E4E4E400E4E4ULL, 0xA100A1A1A100A1A1ULL, 0xE000E0E0E000E0E0ULL, -0x8A008A8A8A008A8AULL, 0xF100F1F1F100F1F1ULL, 0xD600D6D6D600D6D6ULL, 0x7A007A7A7A007A7AULL, -0xBB00BBBBBB00BBBBULL, 0xE300E3E3E300E3E3ULL, 0x4000404040004040ULL, 0x4F004F4F4F004F4FULL }; - -const u64bit Camellia_SBOX7[256] = { -0x7070007070700070ULL, 0x2C2C002C2C2C002CULL, 0xB3B300B3B3B300B3ULL, 0xC0C000C0C0C000C0ULL, -0xE4E400E4E4E400E4ULL, 0x5757005757570057ULL, 0xEAEA00EAEAEA00EAULL, 0xAEAE00AEAEAE00AEULL, -0x2323002323230023ULL, 0x6B6B006B6B6B006BULL, 0x4545004545450045ULL, 0xA5A500A5A5A500A5ULL, -0xEDED00EDEDED00EDULL, 0x4F4F004F4F4F004FULL, 0x1D1D001D1D1D001DULL, 0x9292009292920092ULL, -0x8686008686860086ULL, 0xAFAF00AFAFAF00AFULL, 0x7C7C007C7C7C007CULL, 0x1F1F001F1F1F001FULL, -0x3E3E003E3E3E003EULL, 0xDCDC00DCDCDC00DCULL, 0x5E5E005E5E5E005EULL, 0x0B0B000B0B0B000BULL, -0xA6A600A6A6A600A6ULL, 0x3939003939390039ULL, 0xD5D500D5D5D500D5ULL, 0x5D5D005D5D5D005DULL, -0xD9D900D9D9D900D9ULL, 0x5A5A005A5A5A005AULL, 0x5151005151510051ULL, 0x6C6C006C6C6C006CULL, -0x8B8B008B8B8B008BULL, 0x9A9A009A9A9A009AULL, 0xFBFB00FBFBFB00FBULL, 0xB0B000B0B0B000B0ULL, -0x7474007474740074ULL, 0x2B2B002B2B2B002BULL, 0xF0F000F0F0F000F0ULL, 0x8484008484840084ULL, -0xDFDF00DFDFDF00DFULL, 0xCBCB00CBCBCB00CBULL, 0x3434003434340034ULL, 0x7676007676760076ULL, -0x6D6D006D6D6D006DULL, 0xA9A900A9A9A900A9ULL, 0xD1D100D1D1D100D1ULL, 0x0404000404040004ULL, -0x1414001414140014ULL, 0x3A3A003A3A3A003AULL, 0xDEDE00DEDEDE00DEULL, 0x1111001111110011ULL, -0x3232003232320032ULL, 0x9C9C009C9C9C009CULL, 0x5353005353530053ULL, 0xF2F200F2F2F200F2ULL, -0xFEFE00FEFEFE00FEULL, 0xCFCF00CFCFCF00CFULL, 0xC3C300C3C3C300C3ULL, 0x7A7A007A7A7A007AULL, -0x2424002424240024ULL, 0xE8E800E8E8E800E8ULL, 0x6060006060600060ULL, 0x6969006969690069ULL, -0xAAAA00AAAAAA00AAULL, 0xA0A000A0A0A000A0ULL, 0xA1A100A1A1A100A1ULL, 0x6262006262620062ULL, -0x5454005454540054ULL, 0x1E1E001E1E1E001EULL, 0xE0E000E0E0E000E0ULL, 0x6464006464640064ULL, -0x1010001010100010ULL, 0x0000000000000000ULL, 0xA3A300A3A3A300A3ULL, 0x7575007575750075ULL, -0x8A8A008A8A8A008AULL, 0xE6E600E6E6E600E6ULL, 0x0909000909090009ULL, 0xDDDD00DDDDDD00DDULL, -0x8787008787870087ULL, 0x8383008383830083ULL, 0xCDCD00CDCDCD00CDULL, 0x9090009090900090ULL, -0x7373007373730073ULL, 0xF6F600F6F6F600F6ULL, 0x9D9D009D9D9D009DULL, 0xBFBF00BFBFBF00BFULL, -0x5252005252520052ULL, 0xD8D800D8D8D800D8ULL, 0xC8C800C8C8C800C8ULL, 0xC6C600C6C6C600C6ULL, -0x8181008181810081ULL, 0x6F6F006F6F6F006FULL, 0x1313001313130013ULL, 0x6363006363630063ULL, -0xE9E900E9E9E900E9ULL, 0xA7A700A7A7A700A7ULL, 0x9F9F009F9F9F009FULL, 0xBCBC00BCBCBC00BCULL, -0x2929002929290029ULL, 0xF9F900F9F9F900F9ULL, 0x2F2F002F2F2F002FULL, 0xB4B400B4B4B400B4ULL, -0x7878007878780078ULL, 0x0606000606060006ULL, 0xE7E700E7E7E700E7ULL, 0x7171007171710071ULL, -0xD4D400D4D4D400D4ULL, 0xABAB00ABABAB00ABULL, 0x8888008888880088ULL, 0x8D8D008D8D8D008DULL, -0x7272007272720072ULL, 0xB9B900B9B9B900B9ULL, 0xF8F800F8F8F800F8ULL, 0xACAC00ACACAC00ACULL, -0x3636003636360036ULL, 0x2A2A002A2A2A002AULL, 0x3C3C003C3C3C003CULL, 0xF1F100F1F1F100F1ULL, -0x4040004040400040ULL, 0xD3D300D3D3D300D3ULL, 0xBBBB00BBBBBB00BBULL, 0x4343004343430043ULL, -0x1515001515150015ULL, 0xADAD00ADADAD00ADULL, 0x7777007777770077ULL, 0x8080008080800080ULL, -0x8282008282820082ULL, 0xECEC00ECECEC00ECULL, 0x2727002727270027ULL, 0xE5E500E5E5E500E5ULL, -0x8585008585850085ULL, 0x3535003535350035ULL, 0x0C0C000C0C0C000CULL, 0x4141004141410041ULL, -0xEFEF00EFEFEF00EFULL, 0x9393009393930093ULL, 0x1919001919190019ULL, 0x2121002121210021ULL, -0x0E0E000E0E0E000EULL, 0x4E4E004E4E4E004EULL, 0x6565006565650065ULL, 0xBDBD00BDBDBD00BDULL, -0xB8B800B8B8B800B8ULL, 0x8F8F008F8F8F008FULL, 0xEBEB00EBEBEB00EBULL, 0xCECE00CECECE00CEULL, -0x3030003030300030ULL, 0x5F5F005F5F5F005FULL, 0xC5C500C5C5C500C5ULL, 0x1A1A001A1A1A001AULL, -0xE1E100E1E1E100E1ULL, 0xCACA00CACACA00CAULL, 0x4747004747470047ULL, 0x3D3D003D3D3D003DULL, -0x0101000101010001ULL, 0xD6D600D6D6D600D6ULL, 0x5656005656560056ULL, 0x4D4D004D4D4D004DULL, -0x0D0D000D0D0D000DULL, 0x6666006666660066ULL, 0xCCCC00CCCCCC00CCULL, 0x2D2D002D2D2D002DULL, -0x1212001212120012ULL, 0x2020002020200020ULL, 0xB1B100B1B1B100B1ULL, 0x9999009999990099ULL, -0x4C4C004C4C4C004CULL, 0xC2C200C2C2C200C2ULL, 0x7E7E007E7E7E007EULL, 0x0505000505050005ULL, -0xB7B700B7B7B700B7ULL, 0x3131003131310031ULL, 0x1717001717170017ULL, 0xD7D700D7D7D700D7ULL, -0x5858005858580058ULL, 0x6161006161610061ULL, 0x1B1B001B1B1B001BULL, 0x1C1C001C1C1C001CULL, -0x0F0F000F0F0F000FULL, 0x1616001616160016ULL, 0x1818001818180018ULL, 0x2222002222220022ULL, -0x4444004444440044ULL, 0xB2B200B2B2B200B2ULL, 0xB5B500B5B5B500B5ULL, 0x9191009191910091ULL, -0x0808000808080008ULL, 0xA8A800A8A8A800A8ULL, 0xFCFC00FCFCFC00FCULL, 0x5050005050500050ULL, -0xD0D000D0D0D000D0ULL, 0x7D7D007D7D7D007DULL, 0x8989008989890089ULL, 0x9797009797970097ULL, -0x5B5B005B5B5B005BULL, 0x9595009595950095ULL, 0xFFFF00FFFFFF00FFULL, 0xD2D200D2D2D200D2ULL, -0xC4C400C4C4C400C4ULL, 0x4848004848480048ULL, 0xF7F700F7F7F700F7ULL, 0xDBDB00DBDBDB00DBULL, -0x0303000303030003ULL, 0xDADA00DADADA00DAULL, 0x3F3F003F3F3F003FULL, 0x9494009494940094ULL, -0x5C5C005C5C5C005CULL, 0x0202000202020002ULL, 0x4A4A004A4A4A004AULL, 0x3333003333330033ULL, -0x6767006767670067ULL, 0xF3F300F3F3F300F3ULL, 0x7F7F007F7F7F007FULL, 0xE2E200E2E2E200E2ULL, -0x9B9B009B9B9B009BULL, 0x2626002626260026ULL, 0x3737003737370037ULL, 0x3B3B003B3B3B003BULL, -0x9696009696960096ULL, 0x4B4B004B4B4B004BULL, 0xBEBE00BEBEBE00BEULL, 0x2E2E002E2E2E002EULL, -0x7979007979790079ULL, 0x8C8C008C8C8C008CULL, 0x6E6E006E6E6E006EULL, 0x8E8E008E8E8E008EULL, -0xF5F500F5F5F500F5ULL, 0xB6B600B6B6B600B6ULL, 0xFDFD00FDFDFD00FDULL, 0x5959005959590059ULL, -0x9898009898980098ULL, 0x6A6A006A6A6A006AULL, 0x4646004646460046ULL, 0xBABA00BABABA00BAULL, -0x2525002525250025ULL, 0x4242004242420042ULL, 0xA2A200A2A2A200A2ULL, 0xFAFA00FAFAFA00FAULL, -0x0707000707070007ULL, 0x5555005555550055ULL, 0xEEEE00EEEEEE00EEULL, 0x0A0A000A0A0A000AULL, -0x4949004949490049ULL, 0x6868006868680068ULL, 0x3838003838380038ULL, 0xA4A400A4A4A400A4ULL, -0x2828002828280028ULL, 0x7B7B007B7B7B007BULL, 0xC9C900C9C9C900C9ULL, 0xC1C100C1C1C100C1ULL, -0xE3E300E3E3E300E3ULL, 0xF4F400F4F4F400F4ULL, 0xC7C700C7C7C700C7ULL, 0x9E9E009E9E9E009EULL }; - -const u64bit Camellia_SBOX8[256] = { -0x7070700070707000ULL, 0x8282820082828200ULL, 0x2C2C2C002C2C2C00ULL, 0xECECEC00ECECEC00ULL, -0xB3B3B300B3B3B300ULL, 0x2727270027272700ULL, 0xC0C0C000C0C0C000ULL, 0xE5E5E500E5E5E500ULL, -0xE4E4E400E4E4E400ULL, 0x8585850085858500ULL, 0x5757570057575700ULL, 0x3535350035353500ULL, -0xEAEAEA00EAEAEA00ULL, 0x0C0C0C000C0C0C00ULL, 0xAEAEAE00AEAEAE00ULL, 0x4141410041414100ULL, -0x2323230023232300ULL, 0xEFEFEF00EFEFEF00ULL, 0x6B6B6B006B6B6B00ULL, 0x9393930093939300ULL, -0x4545450045454500ULL, 0x1919190019191900ULL, 0xA5A5A500A5A5A500ULL, 0x2121210021212100ULL, -0xEDEDED00EDEDED00ULL, 0x0E0E0E000E0E0E00ULL, 0x4F4F4F004F4F4F00ULL, 0x4E4E4E004E4E4E00ULL, -0x1D1D1D001D1D1D00ULL, 0x6565650065656500ULL, 0x9292920092929200ULL, 0xBDBDBD00BDBDBD00ULL, -0x8686860086868600ULL, 0xB8B8B800B8B8B800ULL, 0xAFAFAF00AFAFAF00ULL, 0x8F8F8F008F8F8F00ULL, -0x7C7C7C007C7C7C00ULL, 0xEBEBEB00EBEBEB00ULL, 0x1F1F1F001F1F1F00ULL, 0xCECECE00CECECE00ULL, -0x3E3E3E003E3E3E00ULL, 0x3030300030303000ULL, 0xDCDCDC00DCDCDC00ULL, 0x5F5F5F005F5F5F00ULL, -0x5E5E5E005E5E5E00ULL, 0xC5C5C500C5C5C500ULL, 0x0B0B0B000B0B0B00ULL, 0x1A1A1A001A1A1A00ULL, -0xA6A6A600A6A6A600ULL, 0xE1E1E100E1E1E100ULL, 0x3939390039393900ULL, 0xCACACA00CACACA00ULL, -0xD5D5D500D5D5D500ULL, 0x4747470047474700ULL, 0x5D5D5D005D5D5D00ULL, 0x3D3D3D003D3D3D00ULL, -0xD9D9D900D9D9D900ULL, 0x0101010001010100ULL, 0x5A5A5A005A5A5A00ULL, 0xD6D6D600D6D6D600ULL, -0x5151510051515100ULL, 0x5656560056565600ULL, 0x6C6C6C006C6C6C00ULL, 0x4D4D4D004D4D4D00ULL, -0x8B8B8B008B8B8B00ULL, 0x0D0D0D000D0D0D00ULL, 0x9A9A9A009A9A9A00ULL, 0x6666660066666600ULL, -0xFBFBFB00FBFBFB00ULL, 0xCCCCCC00CCCCCC00ULL, 0xB0B0B000B0B0B000ULL, 0x2D2D2D002D2D2D00ULL, -0x7474740074747400ULL, 0x1212120012121200ULL, 0x2B2B2B002B2B2B00ULL, 0x2020200020202000ULL, -0xF0F0F000F0F0F000ULL, 0xB1B1B100B1B1B100ULL, 0x8484840084848400ULL, 0x9999990099999900ULL, -0xDFDFDF00DFDFDF00ULL, 0x4C4C4C004C4C4C00ULL, 0xCBCBCB00CBCBCB00ULL, 0xC2C2C200C2C2C200ULL, -0x3434340034343400ULL, 0x7E7E7E007E7E7E00ULL, 0x7676760076767600ULL, 0x0505050005050500ULL, -0x6D6D6D006D6D6D00ULL, 0xB7B7B700B7B7B700ULL, 0xA9A9A900A9A9A900ULL, 0x3131310031313100ULL, -0xD1D1D100D1D1D100ULL, 0x1717170017171700ULL, 0x0404040004040400ULL, 0xD7D7D700D7D7D700ULL, -0x1414140014141400ULL, 0x5858580058585800ULL, 0x3A3A3A003A3A3A00ULL, 0x6161610061616100ULL, -0xDEDEDE00DEDEDE00ULL, 0x1B1B1B001B1B1B00ULL, 0x1111110011111100ULL, 0x1C1C1C001C1C1C00ULL, -0x3232320032323200ULL, 0x0F0F0F000F0F0F00ULL, 0x9C9C9C009C9C9C00ULL, 0x1616160016161600ULL, -0x5353530053535300ULL, 0x1818180018181800ULL, 0xF2F2F200F2F2F200ULL, 0x2222220022222200ULL, -0xFEFEFE00FEFEFE00ULL, 0x4444440044444400ULL, 0xCFCFCF00CFCFCF00ULL, 0xB2B2B200B2B2B200ULL, -0xC3C3C300C3C3C300ULL, 0xB5B5B500B5B5B500ULL, 0x7A7A7A007A7A7A00ULL, 0x9191910091919100ULL, -0x2424240024242400ULL, 0x0808080008080800ULL, 0xE8E8E800E8E8E800ULL, 0xA8A8A800A8A8A800ULL, -0x6060600060606000ULL, 0xFCFCFC00FCFCFC00ULL, 0x6969690069696900ULL, 0x5050500050505000ULL, -0xAAAAAA00AAAAAA00ULL, 0xD0D0D000D0D0D000ULL, 0xA0A0A000A0A0A000ULL, 0x7D7D7D007D7D7D00ULL, -0xA1A1A100A1A1A100ULL, 0x8989890089898900ULL, 0x6262620062626200ULL, 0x9797970097979700ULL, -0x5454540054545400ULL, 0x5B5B5B005B5B5B00ULL, 0x1E1E1E001E1E1E00ULL, 0x9595950095959500ULL, -0xE0E0E000E0E0E000ULL, 0xFFFFFF00FFFFFF00ULL, 0x6464640064646400ULL, 0xD2D2D200D2D2D200ULL, -0x1010100010101000ULL, 0xC4C4C400C4C4C400ULL, 0x0000000000000000ULL, 0x4848480048484800ULL, -0xA3A3A300A3A3A300ULL, 0xF7F7F700F7F7F700ULL, 0x7575750075757500ULL, 0xDBDBDB00DBDBDB00ULL, -0x8A8A8A008A8A8A00ULL, 0x0303030003030300ULL, 0xE6E6E600E6E6E600ULL, 0xDADADA00DADADA00ULL, -0x0909090009090900ULL, 0x3F3F3F003F3F3F00ULL, 0xDDDDDD00DDDDDD00ULL, 0x9494940094949400ULL, -0x8787870087878700ULL, 0x5C5C5C005C5C5C00ULL, 0x8383830083838300ULL, 0x0202020002020200ULL, -0xCDCDCD00CDCDCD00ULL, 0x4A4A4A004A4A4A00ULL, 0x9090900090909000ULL, 0x3333330033333300ULL, -0x7373730073737300ULL, 0x6767670067676700ULL, 0xF6F6F600F6F6F600ULL, 0xF3F3F300F3F3F300ULL, -0x9D9D9D009D9D9D00ULL, 0x7F7F7F007F7F7F00ULL, 0xBFBFBF00BFBFBF00ULL, 0xE2E2E200E2E2E200ULL, -0x5252520052525200ULL, 0x9B9B9B009B9B9B00ULL, 0xD8D8D800D8D8D800ULL, 0x2626260026262600ULL, -0xC8C8C800C8C8C800ULL, 0x3737370037373700ULL, 0xC6C6C600C6C6C600ULL, 0x3B3B3B003B3B3B00ULL, -0x8181810081818100ULL, 0x9696960096969600ULL, 0x6F6F6F006F6F6F00ULL, 0x4B4B4B004B4B4B00ULL, -0x1313130013131300ULL, 0xBEBEBE00BEBEBE00ULL, 0x6363630063636300ULL, 0x2E2E2E002E2E2E00ULL, -0xE9E9E900E9E9E900ULL, 0x7979790079797900ULL, 0xA7A7A700A7A7A700ULL, 0x8C8C8C008C8C8C00ULL, -0x9F9F9F009F9F9F00ULL, 0x6E6E6E006E6E6E00ULL, 0xBCBCBC00BCBCBC00ULL, 0x8E8E8E008E8E8E00ULL, -0x2929290029292900ULL, 0xF5F5F500F5F5F500ULL, 0xF9F9F900F9F9F900ULL, 0xB6B6B600B6B6B600ULL, -0x2F2F2F002F2F2F00ULL, 0xFDFDFD00FDFDFD00ULL, 0xB4B4B400B4B4B400ULL, 0x5959590059595900ULL, -0x7878780078787800ULL, 0x9898980098989800ULL, 0x0606060006060600ULL, 0x6A6A6A006A6A6A00ULL, -0xE7E7E700E7E7E700ULL, 0x4646460046464600ULL, 0x7171710071717100ULL, 0xBABABA00BABABA00ULL, -0xD4D4D400D4D4D400ULL, 0x2525250025252500ULL, 0xABABAB00ABABAB00ULL, 0x4242420042424200ULL, -0x8888880088888800ULL, 0xA2A2A200A2A2A200ULL, 0x8D8D8D008D8D8D00ULL, 0xFAFAFA00FAFAFA00ULL, -0x7272720072727200ULL, 0x0707070007070700ULL, 0xB9B9B900B9B9B900ULL, 0x5555550055555500ULL, -0xF8F8F800F8F8F800ULL, 0xEEEEEE00EEEEEE00ULL, 0xACACAC00ACACAC00ULL, 0x0A0A0A000A0A0A00ULL, -0x3636360036363600ULL, 0x4949490049494900ULL, 0x2A2A2A002A2A2A00ULL, 0x6868680068686800ULL, -0x3C3C3C003C3C3C00ULL, 0x3838380038383800ULL, 0xF1F1F100F1F1F100ULL, 0xA4A4A400A4A4A400ULL, -0x4040400040404000ULL, 0x2828280028282800ULL, 0xD3D3D300D3D3D300ULL, 0x7B7B7B007B7B7B00ULL, -0xBBBBBB00BBBBBB00ULL, 0xC9C9C900C9C9C900ULL, 0x4343430043434300ULL, 0xC1C1C100C1C1C100ULL, -0x1515150015151500ULL, 0xE3E3E300E3E3E300ULL, 0xADADAD00ADADAD00ULL, 0xF4F4F400F4F4F400ULL, -0x7777770077777700ULL, 0xC7C7C700C7C7C700ULL, 0x8080800080808000ULL, 0x9E9E9E009E9E9E00ULL }; - -} - - -namespace Botan { - -extern "C" { - -#ifdef Q_OS_UNIX -/* -* Helper Macros for x86 Assembly -*/ -#ifndef ASM - #define ASM(x) x "\n\t" -#endif - -#define ADDSUB2_OP(OPERATION, INDEX) \ - ASM("movl 4*" #INDEX "(%[y]), %[carry]") \ - ASM(OPERATION " %[carry], 4*" #INDEX "(%[x])") \ - -#define ADDSUB3_OP(OPERATION, INDEX) \ - ASM("movl 4*" #INDEX "(%[x]), %[carry]") \ - ASM(OPERATION " 4*" #INDEX "(%[y]), %[carry]") \ - ASM("movl %[carry], 4*" #INDEX "(%[z])") \ - -#define LINMUL_OP(WRITE_TO, INDEX) \ - ASM("movl 4*" #INDEX "(%[x]),%%eax") \ - ASM("mull %[y]") \ - ASM("addl %[carry],%%eax") \ - ASM("adcl $0,%%edx") \ - ASM("movl %%edx,%[carry]") \ - ASM("movl %%eax, 4*" #INDEX "(%[" WRITE_TO "])") - -#define MULADD_OP(IGNORED, INDEX) \ - ASM("movl 4*" #INDEX "(%[x]),%%eax") \ - ASM("mull %[y]") \ - ASM("addl %[carry],%%eax") \ - ASM("adcl $0,%%edx") \ - ASM("addl 4*" #INDEX "(%[z]),%%eax") \ - ASM("adcl $0,%%edx") \ - ASM("movl %%edx,%[carry]") \ - ASM("movl %%eax, 4*" #INDEX " (%[z])") - -#define DO_8_TIMES(MACRO, ARG) \ - MACRO(ARG, 0) \ - MACRO(ARG, 1) \ - MACRO(ARG, 2) \ - MACRO(ARG, 3) \ - MACRO(ARG, 4) \ - MACRO(ARG, 5) \ - MACRO(ARG, 6) \ - MACRO(ARG, 7) - -#define ADD_OR_SUBTRACT(CORE_CODE) \ - ASM("rorl %[carry]") \ - CORE_CODE \ - ASM("sbbl %[carry],%[carry]") \ - ASM("negl %[carry]") - -/* -* Word Addition -*/ -inline word word_add(word x, word y, word* carry) - { - asm( - ADD_OR_SUBTRACT(ASM("adcl %[y],%[x]")) - : [x]"=r"(x), [carry]"=r"(*carry) - : "0"(x), [y]"rm"(y), "1"(*carry) - : "cc"); - return x; - } - -/* -* Eight Word Block Addition, Two Argument -*/ -inline word word8_add2(word x[8], const word y[8], word carry) - { - asm( - ADD_OR_SUBTRACT(DO_8_TIMES(ADDSUB2_OP, "adcl")) - : [carry]"=r"(carry) - : [x]"r"(x), [y]"r"(y), "0"(carry) - : "cc", "memory"); - return carry; - } - -/* -* Eight Word Block Addition, Three Argument -*/ -inline word word8_add3(word z[8], const word x[8], const word y[8], word carry) - { - asm( - ADD_OR_SUBTRACT(DO_8_TIMES(ADDSUB3_OP, "adcl")) - : [carry]"=r"(carry) - : [x]"r"(x), [y]"r"(y), [z]"r"(z), "0"(carry) - : "cc", "memory"); - return carry; - } - -/* -* Word Subtraction -*/ -inline word word_sub(word x, word y, word* carry) - { - asm( - ADD_OR_SUBTRACT(ASM("sbbl %[y],%[x]")) - : [x]"=r"(x), [carry]"=r"(*carry) - : "0"(x), [y]"rm"(y), "1"(*carry) - : "cc"); - return x; - } - -/* -* Eight Word Block Subtraction, Two Argument -*/ -inline word word8_sub2(word x[8], const word y[8], word carry) - { - asm( - ADD_OR_SUBTRACT(DO_8_TIMES(ADDSUB2_OP, "sbbl")) - : [carry]"=r"(carry) - : [x]"r"(x), [y]"r"(y), "0"(carry) - : "cc", "memory"); - return carry; - } - -/* -* Eight Word Block Subtraction, Two Argument -*/ -inline word word8_sub2_rev(word x[8], const word y[8], word carry) - { - asm( - ADD_OR_SUBTRACT(DO_8_TIMES(ADDSUB3_OP, "sbbl")) - : [carry]"=r"(carry) - : [x]"r"(y), [y]"r"(x), [z]"r"(x), "0"(carry) - : "cc", "memory"); - return carry; - } - -/* -* Eight Word Block Subtraction, Three Argument -*/ -inline word word8_sub3(word z[8], const word x[8], const word y[8], word carry) - { - asm( - ADD_OR_SUBTRACT(DO_8_TIMES(ADDSUB3_OP, "sbbl")) - : [carry]"=r"(carry) - : [x]"r"(x), [y]"r"(y), [z]"r"(z), "0"(carry) - : "cc", "memory"); - return carry; - } - -/* -* Eight Word Block Linear Multiplication -*/ -inline word word8_linmul2(word x[8], word y, word carry) - { - asm( - DO_8_TIMES(LINMUL_OP, "x") - : [carry]"=r"(carry) - : [x]"r"(x), [y]"rm"(y), "0"(carry) - : "cc", "%eax", "%edx"); - return carry; - } - -/* -* Eight Word Block Linear Multiplication -*/ -inline word word8_linmul3(word z[8], const word x[8], word y, word carry) - { - asm( - DO_8_TIMES(LINMUL_OP, "z") - : [carry]"=r"(carry) - : [z]"r"(z), [x]"r"(x), [y]"rm"(y), "0"(carry) - : "cc", "%eax", "%edx"); - return carry; - } - -/* -* Eight Word Block Multiply/Add -*/ -inline word word8_madd3(word z[8], const word x[8], word y, word carry) - { - asm( - DO_8_TIMES(MULADD_OP, "") - : [carry]"=r"(carry) - : [z]"r"(z), [x]"r"(x), [y]"rm"(y), "0"(carry) - : "cc", "%eax", "%edx"); - return carry; - } - -/* -* Multiply-Add Accumulator -*/ -inline void word3_muladd(word* w2, word* w1, word* w0, word x, word y) - { - asm( - ASM("mull %[y]") - - ASM("addl %[x],%[w0]") - ASM("adcl %[y],%[w1]") - ASM("adcl $0,%[w2]") - - : [w0]"=r"(*w0), [w1]"=r"(*w1), [w2]"=r"(*w2) - : [x]"a"(x), [y]"d"(y), "0"(*w0), "1"(*w1), "2"(*w2) - : "cc"); - } - -/* -* Multiply-Add Accumulator -*/ -inline void word3_muladd_2(word* w2, word* w1, word* w0, word x, word y) - { - asm( - ASM("mull %[y]") - - ASM("addl %[x],%[w0]") - ASM("adcl %[y],%[w1]") - ASM("adcl $0,%[w2]") - - ASM("addl %[x],%[w0]") - ASM("adcl %[y],%[w1]") - ASM("adcl $0,%[w2]") - - : [w0]"=r"(*w0), [w1]"=r"(*w1), [w2]"=r"(*w2) - : [x]"a"(x), [y]"d"(y), "0"(*w0), "1"(*w1), "2"(*w2) - : "cc"); - } -#else -/* -* Word Addition -*/ -inline word word_add(word x, word y, word* carry) - { - word z = x + y; - word c1 = (z < x); - z += *carry; - *carry = c1 | (z < *carry); - return z; - } - -/* -* Eight Word Block Addition, Two Argument -*/ -inline word word8_add2(word x[8], const word y[8], word carry) - { - x[0] = word_add(x[0], y[0], &carry); - x[1] = word_add(x[1], y[1], &carry); - x[2] = word_add(x[2], y[2], &carry); - x[3] = word_add(x[3], y[3], &carry); - x[4] = word_add(x[4], y[4], &carry); - x[5] = word_add(x[5], y[5], &carry); - x[6] = word_add(x[6], y[6], &carry); - x[7] = word_add(x[7], y[7], &carry); - return carry; - } - -/* -* Eight Word Block Addition, Three Argument -*/ -inline word word8_add3(word z[8], const word x[8], - const word y[8], word carry) - { - z[0] = word_add(x[0], y[0], &carry); - z[1] = word_add(x[1], y[1], &carry); - z[2] = word_add(x[2], y[2], &carry); - z[3] = word_add(x[3], y[3], &carry); - z[4] = word_add(x[4], y[4], &carry); - z[5] = word_add(x[5], y[5], &carry); - z[6] = word_add(x[6], y[6], &carry); - z[7] = word_add(x[7], y[7], &carry); - return carry; - } - -/* -* Word Subtraction -*/ -inline word word_sub(word x, word y, word* carry) - { - word t0 = x - y; - word c1 = (t0 > x); - word z = t0 - *carry; - *carry = c1 | (z > t0); - return z; - } - -/* -* Eight Word Block Subtraction, Two Argument -*/ -inline word word8_sub2(word x[8], const word y[8], word carry) - { - x[0] = word_sub(x[0], y[0], &carry); - x[1] = word_sub(x[1], y[1], &carry); - x[2] = word_sub(x[2], y[2], &carry); - x[3] = word_sub(x[3], y[3], &carry); - x[4] = word_sub(x[4], y[4], &carry); - x[5] = word_sub(x[5], y[5], &carry); - x[6] = word_sub(x[6], y[6], &carry); - x[7] = word_sub(x[7], y[7], &carry); - return carry; - } - -/* -* Eight Word Block Subtraction, Two Argument -*/ -inline word word8_sub2_rev(word x[8], const word y[8], word carry) - { - x[0] = word_sub(y[0], x[0], &carry); - x[1] = word_sub(y[1], x[1], &carry); - x[2] = word_sub(y[2], x[2], &carry); - x[3] = word_sub(y[3], x[3], &carry); - x[4] = word_sub(y[4], x[4], &carry); - x[5] = word_sub(y[5], x[5], &carry); - x[6] = word_sub(y[6], x[6], &carry); - x[7] = word_sub(y[7], x[7], &carry); - return carry; - } - -/* -* Eight Word Block Subtraction, Three Argument -*/ -inline word word8_sub3(word z[8], const word x[8], - const word y[8], word carry) - { - z[0] = word_sub(x[0], y[0], &carry); - z[1] = word_sub(x[1], y[1], &carry); - z[2] = word_sub(x[2], y[2], &carry); - z[3] = word_sub(x[3], y[3], &carry); - z[4] = word_sub(x[4], y[4], &carry); - z[5] = word_sub(x[5], y[5], &carry); - z[6] = word_sub(x[6], y[6], &carry); - z[7] = word_sub(x[7], y[7], &carry); - return carry; - } - -/* -* Eight Word Block Linear Multiplication -*/ -inline word word8_linmul2(word x[8], word y, word carry) - { - x[0] = word_madd2(x[0], y, &carry); - x[1] = word_madd2(x[1], y, &carry); - x[2] = word_madd2(x[2], y, &carry); - x[3] = word_madd2(x[3], y, &carry); - x[4] = word_madd2(x[4], y, &carry); - x[5] = word_madd2(x[5], y, &carry); - x[6] = word_madd2(x[6], y, &carry); - x[7] = word_madd2(x[7], y, &carry); - return carry; - } - -/* -* Eight Word Block Linear Multiplication -*/ -inline word word8_linmul3(word z[8], const word x[8], word y, word carry) - { - z[0] = word_madd2(x[0], y, &carry); - z[1] = word_madd2(x[1], y, &carry); - z[2] = word_madd2(x[2], y, &carry); - z[3] = word_madd2(x[3], y, &carry); - z[4] = word_madd2(x[4], y, &carry); - z[5] = word_madd2(x[5], y, &carry); - z[6] = word_madd2(x[6], y, &carry); - z[7] = word_madd2(x[7], y, &carry); - return carry; - } - -/* -* Eight Word Block Multiply/Add -*/ -inline word word8_madd3(word z[8], const word x[8], word y, word carry) - { - z[0] = word_madd3(x[0], y, z[0], &carry); - z[1] = word_madd3(x[1], y, z[1], &carry); - z[2] = word_madd3(x[2], y, z[2], &carry); - z[3] = word_madd3(x[3], y, z[3], &carry); - z[4] = word_madd3(x[4], y, z[4], &carry); - z[5] = word_madd3(x[5], y, z[5], &carry); - z[6] = word_madd3(x[6], y, z[6], &carry); - z[7] = word_madd3(x[7], y, z[7], &carry); - return carry; - } - -/* -* Multiply-Add Accumulator -*/ -inline void word3_muladd(word* w2, word* w1, word* w0, word a, word b) - { - word carry = *w0; - *w0 = word_madd2(a, b, &carry); - *w1 += carry; - *w2 += (*w1 < carry) ? 1 : 0; - } - -/* -* Multiply-Add Accumulator -*/ -inline void word3_muladd_2(word* w2, word* w1, word* w0, word a, word b) - { - word carry = 0; - a = word_madd2(a, b, &carry); - b = carry; - - word top = (b >> (BOTAN_MP_WORD_BITS-1)); - b <<= 1; - b |= (a >> (BOTAN_MP_WORD_BITS-1)); - a <<= 1; - - carry = 0; - *w0 = word_add(*w0, a, &carry); - *w1 = word_add(*w1, b, &carry); - *w2 = word_add(*w2, top, &carry); - } - -#endif - -} - -} - -/* -* OctetString -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include - -namespace Botan { - -/* -* Create an OctetString from RNG output -*/ -OctetString::OctetString(RandomNumberGenerator& rng, - size_t length) - { - bits = rng.random_vec(length); - } - -/* -* Create an OctetString from a hex string -*/ -void OctetString::change(const std::string& hex_string) - { - bits.resize(1 + hex_string.length() / 2); - bits.resize(hex_decode(&bits[0], hex_string)); - } - -/* -* Create an OctetString from a byte string -*/ -void OctetString::change(const byte in[], size_t n) - { - bits.resize(n); - bits.copy(in, n); - } - -/* -* Set the parity of each key byte to odd -*/ -void OctetString::set_odd_parity() - { - const byte ODD_PARITY[256] = { - 0x01, 0x01, 0x02, 0x02, 0x04, 0x04, 0x07, 0x07, 0x08, 0x08, 0x0B, 0x0B, - 0x0D, 0x0D, 0x0E, 0x0E, 0x10, 0x10, 0x13, 0x13, 0x15, 0x15, 0x16, 0x16, - 0x19, 0x19, 0x1A, 0x1A, 0x1C, 0x1C, 0x1F, 0x1F, 0x20, 0x20, 0x23, 0x23, - 0x25, 0x25, 0x26, 0x26, 0x29, 0x29, 0x2A, 0x2A, 0x2C, 0x2C, 0x2F, 0x2F, - 0x31, 0x31, 0x32, 0x32, 0x34, 0x34, 0x37, 0x37, 0x38, 0x38, 0x3B, 0x3B, - 0x3D, 0x3D, 0x3E, 0x3E, 0x40, 0x40, 0x43, 0x43, 0x45, 0x45, 0x46, 0x46, - 0x49, 0x49, 0x4A, 0x4A, 0x4C, 0x4C, 0x4F, 0x4F, 0x51, 0x51, 0x52, 0x52, - 0x54, 0x54, 0x57, 0x57, 0x58, 0x58, 0x5B, 0x5B, 0x5D, 0x5D, 0x5E, 0x5E, - 0x61, 0x61, 0x62, 0x62, 0x64, 0x64, 0x67, 0x67, 0x68, 0x68, 0x6B, 0x6B, - 0x6D, 0x6D, 0x6E, 0x6E, 0x70, 0x70, 0x73, 0x73, 0x75, 0x75, 0x76, 0x76, - 0x79, 0x79, 0x7A, 0x7A, 0x7C, 0x7C, 0x7F, 0x7F, 0x80, 0x80, 0x83, 0x83, - 0x85, 0x85, 0x86, 0x86, 0x89, 0x89, 0x8A, 0x8A, 0x8C, 0x8C, 0x8F, 0x8F, - 0x91, 0x91, 0x92, 0x92, 0x94, 0x94, 0x97, 0x97, 0x98, 0x98, 0x9B, 0x9B, - 0x9D, 0x9D, 0x9E, 0x9E, 0xA1, 0xA1, 0xA2, 0xA2, 0xA4, 0xA4, 0xA7, 0xA7, - 0xA8, 0xA8, 0xAB, 0xAB, 0xAD, 0xAD, 0xAE, 0xAE, 0xB0, 0xB0, 0xB3, 0xB3, - 0xB5, 0xB5, 0xB6, 0xB6, 0xB9, 0xB9, 0xBA, 0xBA, 0xBC, 0xBC, 0xBF, 0xBF, - 0xC1, 0xC1, 0xC2, 0xC2, 0xC4, 0xC4, 0xC7, 0xC7, 0xC8, 0xC8, 0xCB, 0xCB, - 0xCD, 0xCD, 0xCE, 0xCE, 0xD0, 0xD0, 0xD3, 0xD3, 0xD5, 0xD5, 0xD6, 0xD6, - 0xD9, 0xD9, 0xDA, 0xDA, 0xDC, 0xDC, 0xDF, 0xDF, 0xE0, 0xE0, 0xE3, 0xE3, - 0xE5, 0xE5, 0xE6, 0xE6, 0xE9, 0xE9, 0xEA, 0xEA, 0xEC, 0xEC, 0xEF, 0xEF, - 0xF1, 0xF1, 0xF2, 0xF2, 0xF4, 0xF4, 0xF7, 0xF7, 0xF8, 0xF8, 0xFB, 0xFB, - 0xFD, 0xFD, 0xFE, 0xFE }; - - for(size_t j = 0; j != bits.size(); ++j) - bits[j] = ODD_PARITY[bits[j]]; - } - -/* -* Hex encode an OctetString -*/ -std::string OctetString::as_string() const - { - return hex_encode(&bits[0], bits.size()); - } - -/* -* XOR Operation for OctetStrings -*/ -OctetString& OctetString::operator^=(const OctetString& k) - { - if(&k == this) { zeroise(bits); return (*this); } - xor_buf(&bits[0], k.begin(), std::min(length(), k.length())); - return (*this); - } - -/* -* Equality Operation for OctetStrings -*/ -bool operator==(const OctetString& s1, const OctetString& s2) - { - return (s1.bits_of() == s2.bits_of()); - } - -/* -* Unequality Operation for OctetStrings -*/ -bool operator!=(const OctetString& s1, const OctetString& s2) - { - return !(s1 == s2); - } - -/* -* Append Operation for OctetStrings -*/ -OctetString operator+(const OctetString& k1, const OctetString& k2) - { - SecureVector out; - out += k1.bits_of(); - out += k2.bits_of(); - return OctetString(out); - } - -/* -* XOR Operation for OctetStrings -*/ -OctetString operator^(const OctetString& k1, const OctetString& k2) - { - SecureVector ret(std::max(k1.length(), k2.length())); - ret.copy(k1.begin(), k1.length()); - xor_buf(ret, k2.begin(), k2.length()); - return OctetString(ret); - } - -} -/* -* Algorithm Factory -* (C) 2008-2010 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - - -#include - -namespace Botan { - -namespace { - -/* -* Template functions for the factory prototype/search algorithm -*/ -template -T* engine_get_algo(Engine*, - const SCAN_Name&, - Algorithm_Factory&) - { return 0; } - -template<> -BlockCipher* engine_get_algo(Engine* engine, - const SCAN_Name& request, - Algorithm_Factory& af) - { return engine->find_block_cipher(request, af); } - -template<> -StreamCipher* engine_get_algo(Engine* engine, - const SCAN_Name& request, - Algorithm_Factory& af) - { return engine->find_stream_cipher(request, af); } - -template<> -HashFunction* engine_get_algo(Engine* engine, - const SCAN_Name& request, - Algorithm_Factory& af) - { return engine->find_hash(request, af); } - -template<> -MessageAuthenticationCode* engine_get_algo(Engine* engine, - const SCAN_Name& request, - Algorithm_Factory& af) - { return engine->find_mac(request, af); } - -template<> -PBKDF* engine_get_algo(Engine* engine, - const SCAN_Name& request, - Algorithm_Factory& af) - { return engine->find_pbkdf(request, af); } - -template -const T* factory_prototype(const std::string& algo_spec, - const std::string& provider, - const std::vector& engines, - Algorithm_Factory& af, - Algorithm_Cache* cache) - { - if(const T* cache_hit = cache->get(algo_spec, provider)) - return cache_hit; - - SCAN_Name scan_name(algo_spec); - - if(scan_name.cipher_mode() != "") - return 0; - - for(size_t i = 0; i != engines.size(); ++i) - { - if(provider == "" || engines[i]->provider_name() == provider) - { - if(T* impl = engine_get_algo(engines[i], scan_name, af)) - cache->add(impl, algo_spec, engines[i]->provider_name()); - } - } - - return cache->get(algo_spec, provider); - } - -} - -/* -* Setup caches -*/ -Algorithm_Factory::Algorithm_Factory(Mutex_Factory& mf) - { - block_cipher_cache = new Algorithm_Cache(mf.make()); - stream_cipher_cache = new Algorithm_Cache(mf.make()); - hash_cache = new Algorithm_Cache(mf.make()); - mac_cache = new Algorithm_Cache(mf.make()); - pbkdf_cache = new Algorithm_Cache(mf.make()); - } - -/* -* Delete all engines -*/ -Algorithm_Factory::~Algorithm_Factory() - { - delete block_cipher_cache; - delete stream_cipher_cache; - delete hash_cache; - delete mac_cache; - delete pbkdf_cache; - - std::for_each(engines.begin(), engines.end(), del_fun()); - } - -void Algorithm_Factory::clear_caches() - { - block_cipher_cache->clear_cache(); - stream_cipher_cache->clear_cache(); - hash_cache->clear_cache(); - mac_cache->clear_cache(); - pbkdf_cache->clear_cache(); - } - -void Algorithm_Factory::add_engine(Engine* engine) - { - clear_caches(); - engines.push_back(engine); - } - -/* -* Set the preferred provider for an algorithm -*/ -void Algorithm_Factory::set_preferred_provider(const std::string& algo_spec, - const std::string& provider) - { - if(prototype_block_cipher(algo_spec)) - block_cipher_cache->set_preferred_provider(algo_spec, provider); - else if(prototype_stream_cipher(algo_spec)) - stream_cipher_cache->set_preferred_provider(algo_spec, provider); - else if(prototype_hash_function(algo_spec)) - hash_cache->set_preferred_provider(algo_spec, provider); - else if(prototype_mac(algo_spec)) - mac_cache->set_preferred_provider(algo_spec, provider); - else if(prototype_pbkdf(algo_spec)) - pbkdf_cache->set_preferred_provider(algo_spec, provider); - } - -/* -* Get an engine out of the list -*/ -Engine* Algorithm_Factory::get_engine_n(size_t n) const - { - if(n >= engines.size()) - return 0; - return engines[n]; - } - -/* -* Return the possible providers of a request -* Note: assumes you don't have different types by the same name -*/ -std::vector -Algorithm_Factory::providers_of(const std::string& algo_spec) - { - /* The checks with if(prototype_X(algo_spec)) have the effect of - forcing a full search, since otherwise there might not be any - providers at all in the cache. - */ - - if(prototype_block_cipher(algo_spec)) - return block_cipher_cache->providers_of(algo_spec); - else if(prototype_stream_cipher(algo_spec)) - return stream_cipher_cache->providers_of(algo_spec); - else if(prototype_hash_function(algo_spec)) - return hash_cache->providers_of(algo_spec); - else if(prototype_mac(algo_spec)) - return mac_cache->providers_of(algo_spec); - else if(prototype_pbkdf(algo_spec)) - return pbkdf_cache->providers_of(algo_spec); - else - return std::vector(); - } - -/* -* Return the prototypical block cipher corresponding to this request -*/ -const BlockCipher* -Algorithm_Factory::prototype_block_cipher(const std::string& algo_spec, - const std::string& provider) - { - return factory_prototype(algo_spec, provider, engines, - *this, block_cipher_cache); - } - -/* -* Return the prototypical stream cipher corresponding to this request -*/ -const StreamCipher* -Algorithm_Factory::prototype_stream_cipher(const std::string& algo_spec, - const std::string& provider) - { - return factory_prototype(algo_spec, provider, engines, - *this, stream_cipher_cache); - } - -/* -* Return the prototypical object corresponding to this request (if found) -*/ -const HashFunction* -Algorithm_Factory::prototype_hash_function(const std::string& algo_spec, - const std::string& provider) - { - return factory_prototype(algo_spec, provider, engines, - *this, hash_cache); - } - -/* -* Return the prototypical object corresponding to this request -*/ -const MessageAuthenticationCode* -Algorithm_Factory::prototype_mac(const std::string& algo_spec, - const std::string& provider) - { - return factory_prototype(algo_spec, provider, - engines, - *this, mac_cache); - } - -/* -* Return the prototypical object corresponding to this request -*/ -const PBKDF* -Algorithm_Factory::prototype_pbkdf(const std::string& algo_spec, - const std::string& provider) - { - return factory_prototype(algo_spec, provider, - engines, - *this, pbkdf_cache); - } - -/* -* Return a new block cipher corresponding to this request -*/ -BlockCipher* -Algorithm_Factory::make_block_cipher(const std::string& algo_spec, - const std::string& provider) - { - if(const BlockCipher* proto = prototype_block_cipher(algo_spec, provider)) - return proto->clone(); - throw Algorithm_Not_Found(algo_spec); - } - -/* -* Return a new stream cipher corresponding to this request -*/ -StreamCipher* -Algorithm_Factory::make_stream_cipher(const std::string& algo_spec, - const std::string& provider) - { - if(const StreamCipher* proto = prototype_stream_cipher(algo_spec, provider)) - return proto->clone(); - throw Algorithm_Not_Found(algo_spec); - } - -/* -* Return a new object corresponding to this request -*/ -HashFunction* -Algorithm_Factory::make_hash_function(const std::string& algo_spec, - const std::string& provider) - { - if(const HashFunction* proto = prototype_hash_function(algo_spec, provider)) - return proto->clone(); - throw Algorithm_Not_Found(algo_spec); - } - -/* -* Return a new object corresponding to this request -*/ -MessageAuthenticationCode* -Algorithm_Factory::make_mac(const std::string& algo_spec, - const std::string& provider) - { - if(const MessageAuthenticationCode* proto = prototype_mac(algo_spec, provider)) - return proto->clone(); - throw Algorithm_Not_Found(algo_spec); - } - -/* -* Return a new object corresponding to this request -*/ -PBKDF* -Algorithm_Factory::make_pbkdf(const std::string& algo_spec, - const std::string& provider) - { - if(const PBKDF* proto = prototype_pbkdf(algo_spec, provider)) - return proto->clone(); - throw Algorithm_Not_Found(algo_spec); - } - -/* -* Add a new block cipher -*/ -void Algorithm_Factory::add_block_cipher(BlockCipher* block_cipher, - const std::string& provider) - { - block_cipher_cache->add(block_cipher, block_cipher->name(), provider); - } - -/* -* Add a new stream cipher -*/ -void Algorithm_Factory::add_stream_cipher(StreamCipher* stream_cipher, - const std::string& provider) - { - stream_cipher_cache->add(stream_cipher, stream_cipher->name(), provider); - } - -/* -* Add a new hash -*/ -void Algorithm_Factory::add_hash_function(HashFunction* hash, - const std::string& provider) - { - hash_cache->add(hash, hash->name(), provider); - } - -/* -* Add a new mac -*/ -void Algorithm_Factory::add_mac(MessageAuthenticationCode* mac, - const std::string& provider) - { - mac_cache->add(mac, mac->name(), provider); - } - -/* -* Add a new PBKDF -*/ -void Algorithm_Factory::add_pbkdf(PBKDF* pbkdf, - const std::string& provider) - { - pbkdf_cache->add(pbkdf, pbkdf->name(), provider); - } - -} -/* -* Default provider weights for Algorithm_Cache -* (C) 2008 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -/** -* Return a static provider weighing -*/ -size_t static_provider_weight(const std::string& prov_name) - { - /* - * Prefer asm over C++, but prefer anything over OpenSSL or GNU MP; to use - * them, set the provider explicitly for the algorithms you want - */ - - if(prov_name == "aes_isa") return 9; - if(prov_name == "simd") return 8; - if(prov_name == "asm") return 7; - - if(prov_name == "core") return 5; - - if(prov_name == "openssl") return 2; - if(prov_name == "gmp") return 1; - - return 0; // other/unknown - } - -} - -#ifdef Q_OS_UNIX -/* -* Memory Mapping Allocator -* (C) 1999-2010 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#ifndef MAP_FAILED - #define MAP_FAILED -1 -#endif - -namespace Botan { - -namespace { - -/* -* MemoryMapping_Allocator Exception -*/ -class BOTAN_DLL MemoryMapping_Failed : public Exception - { - public: - MemoryMapping_Failed(const std::string& msg) : - Exception("MemoryMapping_Allocator: " + msg) {} - }; - -} - -/* -* Memory Map a File into Memory -*/ -void* MemoryMapping_Allocator::alloc_block(size_t n) - { - class TemporaryFile - { - public: - int get_fd() const { return fd; } - - TemporaryFile(const std::string& base) - { - const std::string mkstemp_template = base + "XXXXXX"; - - std::vector filepath(mkstemp_template.begin(), - mkstemp_template.end()); - filepath.push_back(0); // add terminating NULL - - mode_t old_umask = ::umask(077); - fd = ::mkstemp(&filepath[0]); - ::umask(old_umask); - - if(fd == -1) - throw MemoryMapping_Failed("Temporary file allocation failed"); - - if(::unlink(&filepath[0]) != 0) - throw MemoryMapping_Failed("Could not unlink temporary file"); - } - - ~TemporaryFile() Q_DECL_NOEXCEPT_EXPR(false) - { - /* - * We can safely close here, because post-mmap the file - * will continue to exist until the mmap is unmapped from - * our address space upon deallocation (or process exit). - */ - if(fd != -1 && ::close(fd) == -1) - throw MemoryMapping_Failed("Could not close file"); - } - private: - int fd; - }; - - TemporaryFile file("/tmp/botan_"); - - if(file.get_fd() == -1) - throw MemoryMapping_Failed("Could not create file"); - - std::vector zeros(4096); - - size_t remaining = n; - - while(remaining) - { - const size_t write_try = std::min(zeros.size(), remaining); - - ssize_t wrote_got = ::write(file.get_fd(), - &zeros[0], - write_try); - - if(wrote_got == -1 && errno != EINTR) - throw MemoryMapping_Failed("Could not write to file"); - - remaining -= wrote_got; - } - -#ifndef MAP_NOSYNC - #define MAP_NOSYNC 0 -#endif - - void* ptr = ::mmap(0, n, - PROT_READ | PROT_WRITE, - MAP_SHARED | MAP_NOSYNC, - file.get_fd(), 0); - - if(ptr == static_cast(MAP_FAILED)) - throw MemoryMapping_Failed("Could not map file"); - - return ptr; - } - -/* -* Remove a Memory Mapping -*/ -void MemoryMapping_Allocator::dealloc_block(void* ptr, size_t n) - { - if(ptr == 0) - return; - - const byte PATTERNS[] = { 0x00, 0xF5, 0x5A, 0xAF, 0x00 }; - - // The char* casts are for Solaris, args are void* on most other systems - - for(size_t i = 0; i != sizeof(PATTERNS); ++i) - { - std::memset(ptr, PATTERNS[i], n); - - if(::msync(static_cast(ptr), n, MS_SYNC)) - throw MemoryMapping_Failed("Sync operation failed"); - } - - if(::munmap(static_cast(ptr), n)) - throw MemoryMapping_Failed("Could not unmap file"); - } - -} -#endif - -/* -* Pooling Allocator -* (C) 1999-2008 Jack Lloyd -* 2005 Matthew Gregan -* 2005-2006 Matt Johnston -* -* Distributed under the terms of the Botan license -*/ - -#include -#include - -namespace Botan { - -/* -* Memory_Block Constructor -*/ -Pooling_Allocator::Memory_Block::Memory_Block(void* buf) - { - buffer = static_cast(buf); - bitmap = 0; - buffer_end = buffer + (BLOCK_SIZE * BITMAP_SIZE); - } - -/* -* See if ptr is contained by this block -*/ -bool Pooling_Allocator::Memory_Block::contains(void* ptr, - size_t length) const - { - return ((buffer <= ptr) && - (buffer_end >= static_cast(ptr) + length * BLOCK_SIZE)); - } - -/* -* Allocate some memory, if possible -*/ -byte* Pooling_Allocator::Memory_Block::alloc(size_t n) - { - if(n == 0 || n > BITMAP_SIZE) - return 0; - - if(n == BITMAP_SIZE) - { - if(bitmap) - return 0; - else - { - bitmap = ~bitmap; - return buffer; - } - } - - bitmap_type mask = (static_cast(1) << n) - 1; - size_t offset = 0; - - while(bitmap & mask) - { - mask <<= 1; - ++offset; - - if((bitmap & mask) == 0) - break; - if(mask >> 63) - break; - } - - if(bitmap & mask) - return 0; - - bitmap |= mask; - return buffer + offset * BLOCK_SIZE; - } - -/* -* Mark this memory as free, if we own it -*/ -void Pooling_Allocator::Memory_Block::free(void* ptr, size_t blocks) - { - clear_mem(static_cast(ptr), blocks * BLOCK_SIZE); - - const size_t offset = (static_cast(ptr) - buffer) / BLOCK_SIZE; - - if(offset == 0 && blocks == BITMAP_SIZE) - bitmap = ~bitmap; - else - { - for(size_t j = 0; j != blocks; ++j) - bitmap &= ~(static_cast(1) << (j+offset)); - } - } - -/* -* Pooling_Allocator Constructor -*/ -Pooling_Allocator::Pooling_Allocator(Mutex* m) : mutex(m) - { - last_used = blocks.begin(); - } - -/* -* Pooling_Allocator Destructor -*/ -Pooling_Allocator::~Pooling_Allocator() - { - delete mutex; - if(blocks.size()) - throw Invalid_State("Pooling_Allocator: Never released memory"); - } - -/* -* Free all remaining memory -*/ -void Pooling_Allocator::destroy() - { - Mutex_Holder lock(mutex); - - blocks.clear(); - - for(size_t j = 0; j != allocated.size(); ++j) - dealloc_block(allocated[j].first, allocated[j].second); - allocated.clear(); - } - -/* -* Allocation -*/ -void* Pooling_Allocator::allocate(size_t n) - { - const size_t BITMAP_SIZE = Memory_Block::bitmap_size(); - const size_t BLOCK_SIZE = Memory_Block::block_size(); - - Mutex_Holder lock(mutex); - - if(n <= BITMAP_SIZE * BLOCK_SIZE) - { - const size_t block_no = round_up(n, BLOCK_SIZE) / BLOCK_SIZE; - - byte* mem = allocate_blocks(block_no); - if(mem) - return mem; - - get_more_core(BOTAN_MEM_POOL_CHUNK_SIZE); - - mem = allocate_blocks(block_no); - if(mem) - return mem; - - throw Memory_Exhaustion(); - } - - void* new_buf = alloc_block(n); - if(new_buf) - return new_buf; - - throw Memory_Exhaustion(); - } - -/* -* Deallocation -*/ -void Pooling_Allocator::deallocate(void* ptr, size_t n) - { - const size_t BITMAP_SIZE = Memory_Block::bitmap_size(); - const size_t BLOCK_SIZE = Memory_Block::block_size(); - - if(ptr == 0 || n == 0) - return; - - Mutex_Holder lock(mutex); - - if(n > BITMAP_SIZE * BLOCK_SIZE) - dealloc_block(ptr, n); - else - { - const size_t block_no = round_up(n, BLOCK_SIZE) / BLOCK_SIZE; - - std::vector::iterator i = - std::lower_bound(blocks.begin(), blocks.end(), Memory_Block(ptr)); - - if(i == blocks.end() || !i->contains(ptr, block_no)) - throw Invalid_State("Pointer released to the wrong allocator"); - - i->free(ptr, block_no); - } - } - -/* -* Try to get some memory from an existing block -*/ -byte* Pooling_Allocator::allocate_blocks(size_t n) - { - if(blocks.empty()) - return 0; - - std::vector::iterator i = last_used; - - do - { - byte* mem = i->alloc(n); - if(mem) - { - last_used = i; - return mem; - } - - ++i; - if(i == blocks.end()) - i = blocks.begin(); - } - while(i != last_used); - - return 0; - } - -/* -* Allocate more memory for the pool -*/ -void Pooling_Allocator::get_more_core(size_t in_bytes) - { - const size_t BITMAP_SIZE = Memory_Block::bitmap_size(); - const size_t BLOCK_SIZE = Memory_Block::block_size(); - - const size_t TOTAL_BLOCK_SIZE = BLOCK_SIZE * BITMAP_SIZE; - - // upper bound on allocation is 1 MiB - in_bytes = std::min(in_bytes, 1024 * 1024); - - const size_t in_blocks = round_up(in_bytes, BLOCK_SIZE) / TOTAL_BLOCK_SIZE; - const size_t to_allocate = in_blocks * TOTAL_BLOCK_SIZE; - - void* ptr = alloc_block(to_allocate); - if(ptr == 0) - throw Memory_Exhaustion(); - - allocated.push_back(std::make_pair(ptr, to_allocate)); - - for(size_t j = 0; j != in_blocks; ++j) - { - byte* byte_ptr = static_cast(ptr); - blocks.push_back(Memory_Block(byte_ptr + j * TOTAL_BLOCK_SIZE)); - } - - std::sort(blocks.begin(), blocks.end()); - last_used = std::lower_bound(blocks.begin(), blocks.end(), - Memory_Block(ptr)); - } - -} -/* -* Basic Allocators -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include -#include - -namespace Botan { - -namespace { - -/* -* Perform Memory Allocation -*/ -void* do_malloc(size_t n, bool do_lock) - { - void* ptr = std::malloc(n); - - if(!ptr) - return 0; - - if(do_lock) - lock_mem(ptr, n); - - std::memset(ptr, 0, n); - return ptr; - } - -/* -* Perform Memory Deallocation -*/ -void do_free(void* ptr, size_t n, bool do_lock) - { - if(!ptr) - return; - - std::memset(ptr, 0, n); - if(do_lock) - unlock_mem(ptr, n); - - std::free(ptr); - } - -} - -/* -* Malloc_Allocator's Allocation -*/ -void* Malloc_Allocator::allocate(size_t n) - { - void* ptr = do_malloc(n, false); - if(!ptr) - throw Memory_Exhaustion(); - return ptr; - } - -/* -* Malloc_Allocator's Deallocation -*/ -void Malloc_Allocator::deallocate(void* ptr, size_t n) - { - do_free(ptr, n, false); - } - -/* -* Locking_Allocator's Allocation -*/ -void* Locking_Allocator::alloc_block(size_t n) - { - return do_malloc(n, true); - } - -/* -* Locking_Allocator's Deallocation -*/ -void Locking_Allocator::dealloc_block(void* ptr, size_t n) - { - do_free(ptr, n, true); - } - -/* -* Get an allocator -*/ -Allocator* Allocator::get(bool locking) - { - std::string type = ""; - if(!locking) - type = "malloc"; - - Allocator* alloc = global_state().get_allocator(type); - if(alloc) - return alloc; - - throw Internal_Error("Couldn't find an allocator to use in get_allocator"); - } - -} -/* -* Algorithm Identifier -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -/* -* Create an AlgorithmIdentifier -*/ -AlgorithmIdentifier::AlgorithmIdentifier(const OID& alg_id, - const MemoryRegion& param) - { - oid = alg_id; - parameters = param; - } - -/* -* Create an AlgorithmIdentifier -*/ -AlgorithmIdentifier::AlgorithmIdentifier(const std::string& alg_id, - const MemoryRegion& param) - { - oid = OIDS::lookup(alg_id); - parameters = param; - } - -/* -* Create an AlgorithmIdentifier -*/ -AlgorithmIdentifier::AlgorithmIdentifier(const OID& alg_id, - Encoding_Option option) - { - const byte DER_NULL[] = { 0x05, 0x00 }; - - oid = alg_id; - - if(option == USE_NULL_PARAM) - { - parameters += std::pair(DER_NULL, sizeof(DER_NULL)); - } - } - -/* -* Create an AlgorithmIdentifier -*/ -AlgorithmIdentifier::AlgorithmIdentifier(const std::string& alg_id, - Encoding_Option option) - { - const byte DER_NULL[] = { 0x05, 0x00 }; - - oid = OIDS::lookup(alg_id); - - if(option == USE_NULL_PARAM) - { - parameters += std::pair(DER_NULL, sizeof(DER_NULL)); - } - } - -/* -* Compare two AlgorithmIdentifiers -*/ -bool operator==(const AlgorithmIdentifier& a1, const AlgorithmIdentifier& a2) - { - if(a1.oid != a2.oid) - return false; - if(a1.parameters != a2.parameters) - return false; - return true; - } - -/* -* Compare two AlgorithmIdentifiers -*/ -bool operator!=(const AlgorithmIdentifier& a1, const AlgorithmIdentifier& a2) - { - return !(a1 == a2); - } - -/* -* DER encode an AlgorithmIdentifier -*/ -void AlgorithmIdentifier::encode_into(DER_Encoder& codec) const - { - codec.start_cons(SEQUENCE) - .encode(oid) - .raw_bytes(parameters) - .end_cons(); - } - -/* -* Decode a BER encoded AlgorithmIdentifier -*/ -void AlgorithmIdentifier::decode_from(BER_Decoder& codec) - { - codec.start_cons(SEQUENCE) - .decode(oid) - .raw_bytes(parameters) - .end_cons(); - } - -} -/* -* AlternativeName -* (C) 1999-2007 Jack Lloyd -* 2007 Yves Jerschow -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -namespace { - -/* -* Check if type is a known ASN.1 string type -*/ -bool is_string_type(ASN1_Tag tag) - { - return (tag == NUMERIC_STRING || - tag == PRINTABLE_STRING || - tag == VISIBLE_STRING || - tag == T61_STRING || - tag == IA5_STRING || - tag == UTF8_STRING || - tag == BMP_STRING); - } - -} - -/* -* Create an AlternativeName -*/ -AlternativeName::AlternativeName(const std::string& email_addr, - const std::string& uri, - const std::string& dns, - const std::string& ip) - { - add_attribute("RFC822", email_addr); - add_attribute("DNS", dns); - add_attribute("URI", uri); - add_attribute("IP", ip); - } - -/* -* Add an attribute to an alternative name -*/ -void AlternativeName::add_attribute(const std::string& type, - const std::string& str) - { - if(type == "" || str == "") - return; - - typedef std::multimap::iterator iter; - std::pair range = alt_info.equal_range(type); - for(iter j = range.first; j != range.second; ++j) - if(j->second == str) - return; - - multimap_insert(alt_info, type, str); - } - -/* -* Add an OtherName field -*/ -void AlternativeName::add_othername(const OID& oid, const std::string& value, - ASN1_Tag type) - { - if(value == "") - return; - multimap_insert(othernames, oid, ASN1_String(value, type)); - } - -/* -* Get the attributes of this alternative name -*/ -std::multimap AlternativeName::get_attributes() const - { - return alt_info; - } - -/* -* Get the otherNames -*/ -std::multimap AlternativeName::get_othernames() const - { - return othernames; - } - -/* -* Return all of the alternative names -*/ -std::multimap AlternativeName::contents() const - { - std::multimap names; - - typedef std::multimap::const_iterator rdn_iter; - for(rdn_iter j = alt_info.begin(); j != alt_info.end(); ++j) - multimap_insert(names, j->first, j->second); - - typedef std::multimap::const_iterator on_iter; - for(on_iter j = othernames.begin(); j != othernames.end(); ++j) - multimap_insert(names, OIDS::lookup(j->first), j->second.value()); - - return names; - } - -/* -* Return if this object has anything useful -*/ -bool AlternativeName::has_items() const - { - return (alt_info.size() > 0 || othernames.size() > 0); - } - -namespace { - -/* -* DER encode an AlternativeName entry -*/ -void encode_entries(DER_Encoder& encoder, - const std::multimap& attr, - const std::string& type, ASN1_Tag tagging) - { - typedef std::multimap::const_iterator iter; - - std::pair range = attr.equal_range(type); - for(iter j = range.first; j != range.second; ++j) - { - if(type == "RFC822" || type == "DNS" || type == "URI") - { - ASN1_String asn1_string(j->second, IA5_STRING); - encoder.add_object(tagging, CONTEXT_SPECIFIC, asn1_string.iso_8859()); - } - else if(type == "IP") - { - const u32bit ip = string_to_ipv4(j->second); - byte ip_buf[4] = { 0 }; - store_be(ip, ip_buf); - encoder.add_object(tagging, CONTEXT_SPECIFIC, ip_buf, 4); - } - } - } - -} - -/* -* DER encode an AlternativeName extension -*/ -void AlternativeName::encode_into(DER_Encoder& der) const - { - der.start_cons(SEQUENCE); - - encode_entries(der, alt_info, "RFC822", ASN1_Tag(1)); - encode_entries(der, alt_info, "DNS", ASN1_Tag(2)); - encode_entries(der, alt_info, "URI", ASN1_Tag(6)); - encode_entries(der, alt_info, "IP", ASN1_Tag(7)); - - std::multimap::const_iterator i; - for(i = othernames.begin(); i != othernames.end(); ++i) - { - der.start_explicit(0) - .encode(i->first) - .start_explicit(0) - .encode(i->second) - .end_explicit() - .end_explicit(); - } - - der.end_cons(); - } - -/* -* Decode a BER encoded AlternativeName -*/ -void AlternativeName::decode_from(BER_Decoder& source) - { - BER_Decoder names = source.start_cons(SEQUENCE); - - while(names.more_items()) - { - BER_Object obj = names.get_next_object(); - if((obj.class_tag != CONTEXT_SPECIFIC) && - (obj.class_tag != (CONTEXT_SPECIFIC | CONSTRUCTED))) - continue; - - const ASN1_Tag tag = obj.type_tag; - - if(tag == 0) - { - BER_Decoder othername(obj.value); - - OID oid; - othername.decode(oid); - if(othername.more_items()) - { - BER_Object othername_value_outer = othername.get_next_object(); - othername.verify_end(); - - if(othername_value_outer.type_tag != ASN1_Tag(0) || - othername_value_outer.class_tag != - (CONTEXT_SPECIFIC | CONSTRUCTED) - ) - throw Decoding_Error("Invalid tags on otherName value"); - - BER_Decoder othername_value_inner(othername_value_outer.value); - - BER_Object value = othername_value_inner.get_next_object(); - othername_value_inner.verify_end(); - - const ASN1_Tag value_type = value.type_tag; - - if(is_string_type(value_type) && value.class_tag == UNIVERSAL) - add_othername(oid, ASN1::to_string(value), value_type); - } - } - else if(tag == 1 || tag == 2 || tag == 6) - { - const std::string value = Charset::transcode(ASN1::to_string(obj), - LATIN1_CHARSET, - LOCAL_CHARSET); - - if(tag == 1) add_attribute("RFC822", value); - if(tag == 2) add_attribute("DNS", value); - if(tag == 6) add_attribute("URI", value); - } - else if(tag == 7) - { - if(obj.value.size() == 4) - { - const u32bit ip = load_be(&obj.value[0], 0); - add_attribute("IP", ipv4_to_string(ip)); - } - } - - } - } - -} -/* -* Attribute -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -/* -* Create an Attribute -*/ -Attribute::Attribute(const OID& attr_oid, const MemoryRegion& attr_value) - { - oid = attr_oid; - parameters = attr_value; - } - -/* -* Create an Attribute -*/ -Attribute::Attribute(const std::string& attr_oid, - const MemoryRegion& attr_value) - { - oid = OIDS::lookup(attr_oid); - parameters = attr_value; - } - -/* -* DER encode a Attribute -*/ -void Attribute::encode_into(DER_Encoder& codec) const - { - codec.start_cons(SEQUENCE) - .encode(oid) - .start_cons(SET) - .raw_bytes(parameters) - .end_cons() - .end_cons(); - } - -/* -* Decode a BER encoded Attribute -*/ -void Attribute::decode_from(BER_Decoder& codec) - { - codec.start_cons(SEQUENCE) - .decode(oid) - .start_cons(SET) - .raw_bytes(parameters) - .end_cons() - .end_cons(); - } - -} -/* -* ASN.1 Internals -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -/* -* BER Decoding Exceptions -*/ -BER_Decoding_Error::BER_Decoding_Error(const std::string& str) : - Decoding_Error("BER: " + str) {} - -BER_Bad_Tag::BER_Bad_Tag(const std::string& str, ASN1_Tag tag) : - BER_Decoding_Error(str + ": " + to_string(tag)) {} - -BER_Bad_Tag::BER_Bad_Tag(const std::string& str, - ASN1_Tag tag1, ASN1_Tag tag2) : - BER_Decoding_Error(str + ": " + to_string(tag1) + "/" + to_string(tag2)) {} - -namespace ASN1 { - -/* -* Put some arbitrary bytes into a SEQUENCE -*/ -SecureVector put_in_sequence(const MemoryRegion& contents) - { - return DER_Encoder() - .start_cons(SEQUENCE) - .raw_bytes(contents) - .end_cons() - .get_contents(); - } - -/* -* Convert a BER object into a string object -*/ -std::string to_string(const BER_Object& obj) - { - return std::string(reinterpret_cast(&obj.value[0]), - obj.value.size()); - } - -/* -* Do heuristic tests for BER data -*/ -bool maybe_BER(DataSource& source) - { - byte first_byte; - if(!source.peek_byte(first_byte)) - throw Stream_IO_Error("ASN1::maybe_BER: Source was empty"); - - if(first_byte == (SEQUENCE | CONSTRUCTED)) - return true; - return false; - } - -} - -} -/* -* ASN.1 OID -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -/* -* ASN.1 OID Constructor -*/ -OID::OID(const std::string& oid_str) - { - if(oid_str != "") - { - try - { - id = parse_asn1_oid(oid_str); - } - catch(...) - { - throw Invalid_OID(oid_str); - } - - if(id.size() < 2 || id[0] > 2) - throw Invalid_OID(oid_str); - if((id[0] == 0 || id[0] == 1) && id[1] > 39) - throw Invalid_OID(oid_str); - } - } - -/* -* Clear the current OID -*/ -void OID::clear() - { - id.clear(); - } - -/* -* Return this OID as a string -*/ -std::string OID::as_string() const - { - std::string oid_str; - for(size_t i = 0; i != id.size(); ++i) - { - oid_str += to_string(id[i]); - if(i != id.size() - 1) - oid_str += '.'; - } - return oid_str; - } - -/* -* OID equality comparison -*/ -bool OID::operator==(const OID& oid) const - { - if(id.size() != oid.id.size()) - return false; - for(size_t i = 0; i != id.size(); ++i) - if(id[i] != oid.id[i]) - return false; - return true; - } - -/* -* Append another component to the OID -*/ -OID& OID::operator+=(u32bit component) - { - id.push_back(component); - return (*this); - } - -/* -* Append another component to the OID -*/ -OID operator+(const OID& oid, u32bit component) - { - OID new_oid(oid); - new_oid += component; - return new_oid; - } - -/* -* OID inequality comparison -*/ -bool operator!=(const OID& a, const OID& b) - { - return !(a == b); - } - -/* -* Compare two OIDs -*/ -bool operator<(const OID& a, const OID& b) - { - std::vector oid1 = a.get_id(); - std::vector oid2 = b.get_id(); - - if(oid1.size() < oid2.size()) - return true; - if(oid1.size() > oid2.size()) - return false; - for(size_t i = 0; i != oid1.size(); ++i) - { - if(oid1[i] < oid2[i]) - return true; - if(oid1[i] > oid2[i]) - return false; - } - return false; - } - -/* -* DER encode an OBJECT IDENTIFIER -*/ -void OID::encode_into(DER_Encoder& der) const - { - if(id.size() < 2) - throw Invalid_Argument("OID::encode_into: OID is invalid"); - - MemoryVector encoding; - encoding.push_back(40 * id[0] + id[1]); - - for(size_t i = 2; i != id.size(); ++i) - { - if(id[i] == 0) - encoding.push_back(0); - else - { - size_t blocks = high_bit(id[i]) + 6; - blocks = (blocks - (blocks % 7)) / 7; - - for(size_t j = 0; j != blocks - 1; ++j) - encoding.push_back(0x80 | ((id[i] >> 7*(blocks-j-1)) & 0x7F)); - encoding.push_back(id[i] & 0x7F); - } - } - der.add_object(OBJECT_ID, UNIVERSAL, encoding); - } - -/* -* Decode a BER encoded OBJECT IDENTIFIER -*/ -void OID::decode_from(BER_Decoder& decoder) - { - BER_Object obj = decoder.get_next_object(); - if(obj.type_tag != OBJECT_ID || obj.class_tag != UNIVERSAL) - throw BER_Bad_Tag("Error decoding OID, unknown tag", - obj.type_tag, obj.class_tag); - if(obj.value.size() < 2) - throw BER_Decoding_Error("OID encoding is too short"); - - - clear(); - id.push_back(obj.value[0] / 40); - id.push_back(obj.value[0] % 40); - - size_t i = 0; - while(i != obj.value.size() - 1) - { - u32bit component = 0; - while(i != obj.value.size() - 1) - { - ++i; - component = (component << 7) + (obj.value[i] & 0x7F); - if(!(obj.value[i] & 0x80)) - break; - } - id.push_back(component); - } - } - -} -/* -* Simple ASN.1 String Types -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -namespace { - -/* -* Choose an encoding for the string -*/ -ASN1_Tag choose_encoding(const std::string& str, - const std::string& type) - { - static const byte IS_PRINTABLE[256] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, - 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 }; - - for(size_t i = 0; i != str.size(); ++i) - { - if(!IS_PRINTABLE[static_cast(str[i])]) - { - if(type == "utf8") return UTF8_STRING; - if(type == "latin1") return T61_STRING; - throw Invalid_Argument("choose_encoding: Bad string type " + type); - } - } - return PRINTABLE_STRING; - } - -} - -/* -* Create an ASN1_String -*/ -ASN1_String::ASN1_String(const std::string& str, ASN1_Tag t) : tag(t) - { - iso_8859_str = Charset::transcode(str, LOCAL_CHARSET, LATIN1_CHARSET); - - if(tag == DIRECTORY_STRING) - tag = choose_encoding(iso_8859_str, "latin1"); - - if(tag != NUMERIC_STRING && - tag != PRINTABLE_STRING && - tag != VISIBLE_STRING && - tag != T61_STRING && - tag != IA5_STRING && - tag != UTF8_STRING && - tag != BMP_STRING) - throw Invalid_Argument("ASN1_String: Unknown string type " + - to_string(tag)); - } - -/* -* Create an ASN1_String -*/ -ASN1_String::ASN1_String(const std::string& str) - { - iso_8859_str = Charset::transcode(str, LOCAL_CHARSET, LATIN1_CHARSET); - tag = choose_encoding(iso_8859_str, "latin1"); - } - -/* -* Return this string in ISO 8859-1 encoding -*/ -std::string ASN1_String::iso_8859() const - { - return iso_8859_str; - } - -/* -* Return this string in local encoding -*/ -std::string ASN1_String::value() const - { - return Charset::transcode(iso_8859_str, LATIN1_CHARSET, LOCAL_CHARSET); - } - -/* -* Return the type of this string object -*/ -ASN1_Tag ASN1_String::tagging() const - { - return tag; - } - -/* -* DER encode an ASN1_String -*/ -void ASN1_String::encode_into(DER_Encoder& encoder) const - { - std::string value = iso_8859(); - if(tagging() == UTF8_STRING) - value = Charset::transcode(value, LATIN1_CHARSET, UTF8_CHARSET); - encoder.add_object(tagging(), UNIVERSAL, value); - } - -/* -* Decode a BER encoded ASN1_String -*/ -void ASN1_String::decode_from(BER_Decoder& source) - { - BER_Object obj = source.get_next_object(); - - Character_Set charset_is; - - if(obj.type_tag == BMP_STRING) - charset_is = UCS2_CHARSET; - else if(obj.type_tag == UTF8_STRING) - charset_is = UTF8_CHARSET; - else - charset_is = LATIN1_CHARSET; - - *this = ASN1_String( - Charset::transcode(ASN1::to_string(obj), charset_is, LOCAL_CHARSET), - obj.type_tag); - } - -} -/* -* X.509 Time Types -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -/* -* Create an X509_Time -*/ -X509_Time::X509_Time(const std::string& time_str) - { - set_to(time_str); - } - -/* -* Create an X509_Time -*/ -X509_Time::X509_Time(u64bit timer) - { - calendar_point cal = calendar_value(timer); - - year = cal.year; - month = cal.month; - day = cal.day; - hour = cal.hour; - minute = cal.minutes; - second = cal.seconds; - - tag = (year >= 2050) ? GENERALIZED_TIME : UTC_TIME; - } - -/* -* Create an X509_Time -*/ -X509_Time::X509_Time(const std::string& t_spec, ASN1_Tag t) : tag(t) - { - set_to(t_spec, tag); - } - -/* -* Set the time with a human readable string -*/ -void X509_Time::set_to(const std::string& time_str) - { - if(time_str == "") - { - year = month = day = hour = minute = second = 0; - tag = NO_OBJECT; - return; - } - - std::vector params; - std::string current; - - for(size_t j = 0; j != time_str.size(); ++j) - { - if(Charset::is_digit(time_str[j])) - current += time_str[j]; - else - { - if(current != "") - params.push_back(current); - current.clear(); - } - } - if(current != "") - params.push_back(current); - - if(params.size() < 3 || params.size() > 6) - throw Invalid_Argument("Invalid time specification " + time_str); - - year = to_u32bit(params[0]); - month = to_u32bit(params[1]); - day = to_u32bit(params[2]); - hour = (params.size() >= 4) ? to_u32bit(params[3]) : 0; - minute = (params.size() >= 5) ? to_u32bit(params[4]) : 0; - second = (params.size() == 6) ? to_u32bit(params[5]) : 0; - - tag = (year >= 2050) ? GENERALIZED_TIME : UTC_TIME; - - if(!passes_sanity_check()) - throw Invalid_Argument("Invalid time specification " + time_str); - } - -/* -* Set the time with an ISO time format string -*/ -void X509_Time::set_to(const std::string& t_spec, ASN1_Tag spec_tag) - { - if(spec_tag != GENERALIZED_TIME && spec_tag != UTC_TIME) - throw Invalid_Argument("X509_Time: Invalid tag " + to_string(spec_tag)); - - if(spec_tag == GENERALIZED_TIME && t_spec.size() != 13 && t_spec.size() != 15) - throw Invalid_Argument("Invalid GeneralizedTime: " + t_spec); - - if(spec_tag == UTC_TIME && t_spec.size() != 11 && t_spec.size() != 13) - throw Invalid_Argument("Invalid UTCTime: " + t_spec); - - if(t_spec[t_spec.size()-1] != 'Z') - throw Invalid_Argument("Invalid time encoding: " + t_spec); - - const size_t YEAR_SIZE = (spec_tag == UTC_TIME) ? 2 : 4; - - std::vector params; - std::string current; - - for(size_t j = 0; j != YEAR_SIZE; ++j) - current += t_spec[j]; - params.push_back(current); - current.clear(); - - for(size_t j = YEAR_SIZE; j != t_spec.size() - 1; ++j) - { - current += t_spec[j]; - if(current.size() == 2) - { - params.push_back(current); - current.clear(); - } - } - - year = to_u32bit(params[0]); - month = to_u32bit(params[1]); - day = to_u32bit(params[2]); - hour = to_u32bit(params[3]); - minute = to_u32bit(params[4]); - second = (params.size() == 6) ? to_u32bit(params[5]) : 0; - tag = spec_tag; - - if(spec_tag == UTC_TIME) - { - if(year >= 50) year += 1900; - else year += 2000; - } - - if(!passes_sanity_check()) - throw Invalid_Argument("Invalid time specification " + t_spec); - } - -/* -* DER encode a X509_Time -*/ -void X509_Time::encode_into(DER_Encoder& der) const - { - if(tag != GENERALIZED_TIME && tag != UTC_TIME) - throw Invalid_Argument("X509_Time: Bad encoding tag"); - - der.add_object(tag, UNIVERSAL, - Charset::transcode(as_string(), - LOCAL_CHARSET, - LATIN1_CHARSET)); - } - -/* -* Decode a BER encoded X509_Time -*/ -void X509_Time::decode_from(BER_Decoder& source) - { - BER_Object ber_time = source.get_next_object(); - - set_to(Charset::transcode(ASN1::to_string(ber_time), - LATIN1_CHARSET, - LOCAL_CHARSET), - ber_time.type_tag); - } - -/* -* Return a string representation of the time -*/ -std::string X509_Time::as_string() const - { - if(time_is_set() == false) - throw Invalid_State("X509_Time::as_string: No time set"); - - std::string asn1rep; - if(tag == GENERALIZED_TIME) - asn1rep = to_string(year, 4); - else if(tag == UTC_TIME) - { - if(year < 1950 || year >= 2050) - throw Encoding_Error("X509_Time: The time " + readable_string() + - " cannot be encoded as a UTCTime"); - u32bit asn1year = (year >= 2000) ? (year - 2000) : (year - 1900); - asn1rep = to_string(asn1year, 2); - } - else - throw Invalid_Argument("X509_Time: Invalid tag " + to_string(tag)); - - asn1rep += to_string(month, 2) + to_string(day, 2); - asn1rep += to_string(hour, 2) + to_string(minute, 2) + to_string(second, 2); - asn1rep += "Z"; - return asn1rep; - } - -/* -* Return if the time has been set somehow -*/ -bool X509_Time::time_is_set() const - { - return (year != 0); - } - -/* -* Return a human readable string representation -*/ -std::string X509_Time::readable_string() const - { - if(time_is_set() == false) - throw Invalid_State("X509_Time::readable_string: No time set"); - - std::string readable; - readable += to_string(year, 4) + "/"; - readable += to_string(month ) + "/"; - readable += to_string(day ) + " "; - readable += to_string(hour ) + ":"; - readable += to_string(minute, 2) + ":"; - readable += to_string(second, 2) + " UTC"; - return readable; - } - -/* -* Do a general sanity check on the time -*/ -bool X509_Time::passes_sanity_check() const - { - if(year < 1950 || year > 2100) - return false; - if(month == 0 || month > 12) - return false; - if(day == 0 || day > 31) - return false; - if(hour >= 24 || minute > 60 || second > 60) - return false; - return true; - } - -/* -* Compare this time against another -*/ -s32bit X509_Time::cmp(const X509_Time& other) const - { - if(time_is_set() == false) - throw Invalid_State("X509_Time::cmp: No time set"); - - const s32bit EARLIER = -1, LATER = 1, SAME_TIME = 0; - - if(year < other.year) return EARLIER; - if(year > other.year) return LATER; - if(month < other.month) return EARLIER; - if(month > other.month) return LATER; - if(day < other.day) return EARLIER; - if(day > other.day) return LATER; - if(hour < other.hour) return EARLIER; - if(hour > other.hour) return LATER; - if(minute < other.minute) return EARLIER; - if(minute > other.minute) return LATER; - if(second < other.second) return EARLIER; - if(second > other.second) return LATER; - - return SAME_TIME; - } - -/* -* Compare two X509_Times for in various ways -*/ -bool operator==(const X509_Time& t1, const X509_Time& t2) - { return (t1.cmp(t2) == 0); } -bool operator!=(const X509_Time& t1, const X509_Time& t2) - { return (t1.cmp(t2) != 0); } - -bool operator<=(const X509_Time& t1, const X509_Time& t2) - { return (t1.cmp(t2) <= 0); } -bool operator>=(const X509_Time& t1, const X509_Time& t2) - { return (t1.cmp(t2) >= 0); } - -bool operator<(const X509_Time& t1, const X509_Time& t2) - { return (t1.cmp(t2) < 0); } -bool operator>(const X509_Time& t1, const X509_Time& t2) - { return (t1.cmp(t2) > 0); } - -} -/* -* BER Decoder -* (C) 1999-2008 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -namespace { - -/* -* BER decode an ASN.1 type tag -*/ -size_t decode_tag(DataSource* ber, ASN1_Tag& type_tag, ASN1_Tag& class_tag) - { - byte b; - if(!ber->read_byte(b)) - { - class_tag = type_tag = NO_OBJECT; - return 0; - } - - if((b & 0x1F) != 0x1F) - { - type_tag = ASN1_Tag(b & 0x1F); - class_tag = ASN1_Tag(b & 0xE0); - return 1; - } - - size_t tag_bytes = 1; - class_tag = ASN1_Tag(b & 0xE0); - - size_t tag_buf = 0; - while(true) - { - if(!ber->read_byte(b)) - throw BER_Decoding_Error("Long-form tag truncated"); - if(tag_buf & 0xFF000000) - throw BER_Decoding_Error("Long-form tag overflowed 32 bits"); - ++tag_bytes; - tag_buf = (tag_buf << 7) | (b & 0x7F); - if((b & 0x80) == 0) break; - } - type_tag = ASN1_Tag(tag_buf); - return tag_bytes; - } - -/* -* Find the EOC marker -*/ -size_t find_eoc(DataSource*); - -/* -* BER decode an ASN.1 length field -*/ -size_t decode_length(DataSource* ber, size_t& field_size) - { - byte b; - if(!ber->read_byte(b)) - throw BER_Decoding_Error("Length field not found"); - field_size = 1; - if((b & 0x80) == 0) - return b; - - field_size += (b & 0x7F); - if(field_size == 1) return find_eoc(ber); - if(field_size > 5) - throw BER_Decoding_Error("Length field is too large"); - - size_t length = 0; - - for(size_t i = 0; i != field_size - 1; ++i) - { - if(get_byte(0, length) != 0) - throw BER_Decoding_Error("Field length overflow"); - if(!ber->read_byte(b)) - throw BER_Decoding_Error("Corrupted length field"); - length = (length << 8) | b; - } - return length; - } - -/* -* BER decode an ASN.1 length field -*/ -size_t decode_length(DataSource* ber) - { - size_t dummy; - return decode_length(ber, dummy); - } - -/* -* Find the EOC marker -*/ -size_t find_eoc(DataSource* ber) - { - SecureVector buffer(DEFAULT_BUFFERSIZE), data; - - while(true) - { - const size_t got = ber->peek(&buffer[0], buffer.size(), data.size()); - if(got == 0) - break; - - data += std::make_pair(&buffer[0], got); - } - - DataSource_Memory source(data); - data.clear(); - - size_t length = 0; - while(true) - { - ASN1_Tag type_tag, class_tag; - size_t tag_size = decode_tag(&source, type_tag, class_tag); - if(type_tag == NO_OBJECT) - break; - - size_t length_size = 0; - size_t item_size = decode_length(&source, length_size); - source.discard_next(item_size); - - length += item_size + length_size + tag_size; - - if(type_tag == EOC) - break; - } - return length; - } - -} - -/* -* Check a type invariant on BER data -*/ -void BER_Object::assert_is_a(ASN1_Tag type_tag, ASN1_Tag class_tag) - { - if(this->type_tag != type_tag || this->class_tag != class_tag) - throw BER_Decoding_Error("Tag mismatch when decoding"); - } - -/* -* Check if more objects are there -*/ -bool BER_Decoder::more_items() const - { - if(source->end_of_data() && (pushed.type_tag == NO_OBJECT)) - return false; - return true; - } - -/* -* Verify that no bytes remain in the source -*/ -BER_Decoder& BER_Decoder::verify_end() - { - if(!source->end_of_data() || (pushed.type_tag != NO_OBJECT)) - throw Invalid_State("BER_Decoder::verify_end called, but data remains"); - return (*this); - } - -/* -* Save all the bytes remaining in the source -*/ -BER_Decoder& BER_Decoder::raw_bytes(MemoryRegion& out) - { - out.clear(); - byte buf; - while(source->read_byte(buf)) - out.push_back(buf); - return (*this); - } - -/* -* Discard all the bytes remaining in the source -*/ -BER_Decoder& BER_Decoder::discard_remaining() - { - byte buf; - while(source->read_byte(buf)) - ; - return (*this); - } - -/* -* Return the BER encoding of the next object -*/ -BER_Object BER_Decoder::get_next_object() - { - BER_Object next; - - if(pushed.type_tag != NO_OBJECT) - { - next = pushed; - pushed.class_tag = pushed.type_tag = NO_OBJECT; - return next; - } - - decode_tag(source, next.type_tag, next.class_tag); - if(next.type_tag == NO_OBJECT) - return next; - - size_t length = decode_length(source); - next.value.resize(length); - if(source->read(&next.value[0], length) != length) - throw BER_Decoding_Error("Value truncated"); - - if(next.type_tag == EOC && next.class_tag == UNIVERSAL) - return get_next_object(); - - return next; - } - -/* -* Push a object back into the stream -*/ -void BER_Decoder::push_back(const BER_Object& obj) - { - if(pushed.type_tag != NO_OBJECT) - throw Invalid_State("BER_Decoder: Only one push back is allowed"); - pushed = obj; - } - -/* -* Begin decoding a CONSTRUCTED type -*/ -BER_Decoder BER_Decoder::start_cons(ASN1_Tag type_tag, - ASN1_Tag class_tag) - { - BER_Object obj = get_next_object(); - obj.assert_is_a(type_tag, ASN1_Tag(class_tag | CONSTRUCTED)); - - BER_Decoder result(&obj.value[0], obj.value.size()); - result.parent = this; - return result; - } - -/* -* Finish decoding a CONSTRUCTED type -*/ -BER_Decoder& BER_Decoder::end_cons() - { - if(!parent) - throw Invalid_State("BER_Decoder::end_cons called with NULL parent"); - if(!source->end_of_data()) - throw Decoding_Error("BER_Decoder::end_cons called with data left"); - return (*parent); - } - -/* -* BER_Decoder Constructor -*/ -BER_Decoder::BER_Decoder(DataSource& src) - { - source = &src; - owns = false; - pushed.type_tag = pushed.class_tag = NO_OBJECT; - parent = 0; - } - -/* -* BER_Decoder Constructor - */ -BER_Decoder::BER_Decoder(const byte data[], size_t length) - { - source = new DataSource_Memory(data, length); - owns = true; - pushed.type_tag = pushed.class_tag = NO_OBJECT; - parent = 0; - } - -/* -* BER_Decoder Constructor -*/ -BER_Decoder::BER_Decoder(const MemoryRegion& data) - { - source = new DataSource_Memory(data); - owns = true; - pushed.type_tag = pushed.class_tag = NO_OBJECT; - parent = 0; - } - -/* -* BER_Decoder Copy Constructor -*/ -BER_Decoder::BER_Decoder(const BER_Decoder& other) - { - source = other.source; - owns = false; - if(other.owns) - { - other.owns = false; - owns = true; - } - pushed.type_tag = pushed.class_tag = NO_OBJECT; - parent = other.parent; - } - -/* -* BER_Decoder Destructor -*/ -BER_Decoder::~BER_Decoder() - { - if(owns) - delete source; - source = 0; - } - -/* -* Request for an object to decode itself -*/ -BER_Decoder& BER_Decoder::decode(ASN1_Object& obj) - { - obj.decode_from(*this); - return (*this); - } - -/* -* Decode a BER encoded NULL -*/ -BER_Decoder& BER_Decoder::decode_null() - { - BER_Object obj = get_next_object(); - obj.assert_is_a(NULL_TAG, UNIVERSAL); - if(obj.value.size()) - throw BER_Decoding_Error("NULL object had nonzero size"); - return (*this); - } - -/* -* Decode a BER encoded BOOLEAN -*/ -BER_Decoder& BER_Decoder::decode(bool& out) - { - return decode(out, BOOLEAN, UNIVERSAL); - } - -/* -* Decode a small BER encoded INTEGER -*/ -BER_Decoder& BER_Decoder::decode(size_t& out) - { - return decode(out, INTEGER, UNIVERSAL); - } - -/* -* Decode a BER encoded INTEGER -*/ -BER_Decoder& BER_Decoder::decode(BigInt& out) - { - return decode(out, INTEGER, UNIVERSAL); - } - -BER_Decoder& BER_Decoder::decode_octet_string_bigint(BigInt& out) - { - SecureVector out_vec; - decode(out_vec, OCTET_STRING); - out = BigInt::decode(&out_vec[0], out_vec.size()); - return (*this); - } - -/* -* Decode a BER encoded BOOLEAN -*/ -BER_Decoder& BER_Decoder::decode(bool& out, - ASN1_Tag type_tag, ASN1_Tag class_tag) - { - BER_Object obj = get_next_object(); - obj.assert_is_a(type_tag, class_tag); - - if(obj.value.size() != 1) - throw BER_Decoding_Error("BER boolean value had invalid size"); - - out = (obj.value[0]) ? true : false; - return (*this); - } - -/* -* Decode a small BER encoded INTEGER -*/ -BER_Decoder& BER_Decoder::decode(size_t& out, - ASN1_Tag type_tag, ASN1_Tag class_tag) - { - BigInt integer; - decode(integer, type_tag, class_tag); - - if(integer.bits() > 32) - throw BER_Decoding_Error("Decoded integer value larger than expected"); - - out = 0; - for(size_t i = 0; i != 4; ++i) - out = (out << 8) | integer.byte_at(3-i); - - return (*this); - } - -/* -* Decode a BER encoded INTEGER -*/ -BER_Decoder& BER_Decoder::decode(BigInt& out, - ASN1_Tag type_tag, ASN1_Tag class_tag) - { - BER_Object obj = get_next_object(); - obj.assert_is_a(type_tag, class_tag); - - if(obj.value.empty()) - out = 0; - else - { - const bool negative = (obj.value[0] & 0x80) ? true : false; - - if(negative) - { - for(size_t i = obj.value.size(); i > 0; --i) - if(obj.value[i-1]--) - break; - for(size_t i = 0; i != obj.value.size(); ++i) - obj.value[i] = ~obj.value[i]; - } - - out = BigInt(&obj.value[0], obj.value.size()); - - if(negative) - out.flip_sign(); - } - - return (*this); - } - -/* -* BER decode a BIT STRING or OCTET STRING -*/ -BER_Decoder& BER_Decoder::decode(MemoryRegion& out, ASN1_Tag real_type) - { - return decode(out, real_type, real_type, UNIVERSAL); - } - -/* -* BER decode a BIT STRING or OCTET STRING -*/ -BER_Decoder& BER_Decoder::decode(MemoryRegion& buffer, - ASN1_Tag real_type, - ASN1_Tag type_tag, ASN1_Tag class_tag) - { - if(real_type != OCTET_STRING && real_type != BIT_STRING) - throw BER_Bad_Tag("Bad tag for {BIT,OCTET} STRING", real_type); - - BER_Object obj = get_next_object(); - obj.assert_is_a(type_tag, class_tag); - - if(real_type == OCTET_STRING) - buffer = obj.value; - else - { - if(obj.value[0] >= 8) - throw BER_Decoding_Error("Bad number of unused bits in BIT STRING"); - - buffer.resize(obj.value.size() - 1); - copy_mem(&buffer[0], &obj.value[1], obj.value.size() - 1); - } - return (*this); - } - -/* -* Decode an OPTIONAL string type -*/ -BER_Decoder& BER_Decoder::decode_optional_string(MemoryRegion& out, - ASN1_Tag real_type, - u16bit type_no) - { - BER_Object obj = get_next_object(); - - ASN1_Tag type_tag = static_cast(type_no); - - out.clear(); - push_back(obj); - - if(obj.type_tag == type_tag && obj.class_tag == CONTEXT_SPECIFIC) - decode(out, real_type, type_tag, CONTEXT_SPECIFIC); - - return (*this); - } - -} -/* -* DER Encoder -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include - -namespace Botan { - -namespace { - -/* -* DER encode an ASN.1 type tag -*/ -SecureVector encode_tag(ASN1_Tag type_tag, ASN1_Tag class_tag) - { - if((class_tag | 0xE0) != 0xE0) - throw Encoding_Error("DER_Encoder: Invalid class tag " + - to_string(class_tag)); - - SecureVector encoded_tag; - if(type_tag <= 30) - encoded_tag.push_back(static_cast(type_tag | class_tag)); - else - { - size_t blocks = high_bit(type_tag) + 6; - blocks = (blocks - (blocks % 7)) / 7; - - encoded_tag.push_back(class_tag | 0x1F); - for(size_t i = 0; i != blocks - 1; ++i) - encoded_tag.push_back(0x80 | ((type_tag >> 7*(blocks-i-1)) & 0x7F)); - encoded_tag.push_back(type_tag & 0x7F); - } - - return encoded_tag; - } - -/* -* DER encode an ASN.1 length field -*/ -SecureVector encode_length(size_t length) - { - SecureVector encoded_length; - if(length <= 127) - encoded_length.push_back(static_cast(length)); - else - { - const size_t top_byte = significant_bytes(length); - - encoded_length.push_back(static_cast(0x80 | top_byte)); - - for(size_t i = sizeof(length) - top_byte; i != sizeof(length); ++i) - encoded_length.push_back(get_byte(i, length)); - } - return encoded_length; - } - -} - -/* -* Return the encoded SEQUENCE/SET -*/ -SecureVector DER_Encoder::DER_Sequence::get_contents() - { - const ASN1_Tag real_class_tag = ASN1_Tag(class_tag | CONSTRUCTED); - - if(type_tag == SET) - { - std::sort(set_contents.begin(), set_contents.end()); - for(size_t i = 0; i != set_contents.size(); ++i) - contents += set_contents[i]; - set_contents.clear(); - } - - SecureVector result; - result += encode_tag(type_tag, real_class_tag); - result += encode_length(contents.size()); - result += contents; - contents.clear(); - - return result; - } - -/* -* Add an encoded value to the SEQUENCE/SET -*/ -void DER_Encoder::DER_Sequence::add_bytes(const byte data[], size_t length) - { - if(type_tag == SET) - set_contents.push_back(SecureVector(data, length)); - else - contents += std::make_pair(data, length); - } - -/* -* Return the type and class taggings -*/ -ASN1_Tag DER_Encoder::DER_Sequence::tag_of() const - { - return ASN1_Tag(type_tag | class_tag); - } - -/* -* DER_Sequence Constructor -*/ -DER_Encoder::DER_Sequence::DER_Sequence(ASN1_Tag t1, ASN1_Tag t2) : - type_tag(t1), class_tag(t2) - { - } - -/* -* Return the encoded contents -*/ -SecureVector DER_Encoder::get_contents() - { - if(subsequences.size() != 0) - throw Invalid_State("DER_Encoder: Sequence hasn't been marked done"); - - SecureVector output; - std::swap(output, contents); - return output; - } - -/* -* Start a new ASN.1 SEQUENCE/SET/EXPLICIT -*/ -DER_Encoder& DER_Encoder::start_cons(ASN1_Tag type_tag, - ASN1_Tag class_tag) - { - subsequences.push_back(DER_Sequence(type_tag, class_tag)); - return (*this); - } - -/* -* Finish the current ASN.1 SEQUENCE/SET/EXPLICIT -*/ -DER_Encoder& DER_Encoder::end_cons() - { - if(subsequences.empty()) - throw Invalid_State("DER_Encoder::end_cons: No such sequence"); - - SecureVector seq = subsequences[subsequences.size()-1].get_contents(); - subsequences.pop_back(); - raw_bytes(seq); - return (*this); - } - -/* -* Start a new ASN.1 EXPLICIT encoding -*/ -DER_Encoder& DER_Encoder::start_explicit(u16bit type_no) - { - ASN1_Tag type_tag = static_cast(type_no); - - if(type_tag == SET) - throw Internal_Error("DER_Encoder.start_explicit(SET); cannot perform"); - - return start_cons(type_tag, CONTEXT_SPECIFIC); - } - -/* -* Finish the current ASN.1 EXPLICIT encoding -*/ -DER_Encoder& DER_Encoder::end_explicit() - { - return end_cons(); - } - -/* -* Write raw bytes into the stream -*/ -DER_Encoder& DER_Encoder::raw_bytes(const MemoryRegion& val) - { - return raw_bytes(&val[0], val.size()); - } - -/* -* Write raw bytes into the stream -*/ -DER_Encoder& DER_Encoder::raw_bytes(const byte bytes[], size_t length) - { - if(subsequences.size()) - subsequences[subsequences.size()-1].add_bytes(bytes, length); - else - contents += std::make_pair(bytes, length); - - return (*this); - } - -/* -* Encode a NULL object -*/ -DER_Encoder& DER_Encoder::encode_null() - { - return add_object(NULL_TAG, UNIVERSAL, 0, 0); - } - -/* -* DER encode a BOOLEAN -*/ -DER_Encoder& DER_Encoder::encode(bool is_true) - { - return encode(is_true, BOOLEAN, UNIVERSAL); - } - -/* -* DER encode a small INTEGER -*/ -DER_Encoder& DER_Encoder::encode(size_t n) - { - return encode(BigInt(n), INTEGER, UNIVERSAL); - } - -/* -* DER encode a small INTEGER -*/ -DER_Encoder& DER_Encoder::encode(const BigInt& n) - { - return encode(n, INTEGER, UNIVERSAL); - } - -/* -* DER encode an OCTET STRING or BIT STRING -*/ -DER_Encoder& DER_Encoder::encode(const MemoryRegion& bytes, - ASN1_Tag real_type) - { - return encode(&bytes[0], bytes.size(), - real_type, real_type, UNIVERSAL); - } - -/* -* Encode this object -*/ -DER_Encoder& DER_Encoder::encode(const byte bytes[], size_t length, - ASN1_Tag real_type) - { - return encode(bytes, length, real_type, real_type, UNIVERSAL); - } - -/* -* DER encode a BOOLEAN -*/ -DER_Encoder& DER_Encoder::encode(bool is_true, - ASN1_Tag type_tag, ASN1_Tag class_tag) - { - byte val = is_true ? 0xFF : 0x00; - return add_object(type_tag, class_tag, &val, 1); - } - -/* -* DER encode a small INTEGER -*/ -DER_Encoder& DER_Encoder::encode(size_t n, - ASN1_Tag type_tag, ASN1_Tag class_tag) - { - return encode(BigInt(n), type_tag, class_tag); - } - -/* -* DER encode an INTEGER -*/ -DER_Encoder& DER_Encoder::encode(const BigInt& n, - ASN1_Tag type_tag, ASN1_Tag class_tag) - { - if(n == 0) - return add_object(type_tag, class_tag, 0); - - bool extra_zero = (n.bits() % 8 == 0); - SecureVector contents(extra_zero + n.bytes()); - BigInt::encode(&contents[extra_zero], n); - if(n < 0) - { - for(size_t i = 0; i != contents.size(); ++i) - contents[i] = ~contents[i]; - for(size_t i = contents.size(); i > 0; --i) - if(++contents[i-1]) - break; - } - - return add_object(type_tag, class_tag, contents); - } - -/* -* DER encode an OCTET STRING or BIT STRING -*/ -DER_Encoder& DER_Encoder::encode(const MemoryRegion& bytes, - ASN1_Tag real_type, - ASN1_Tag type_tag, ASN1_Tag class_tag) - { - return encode(&bytes[0], bytes.size(), - real_type, type_tag, class_tag); - } - -/* -* DER encode an OCTET STRING or BIT STRING -*/ -DER_Encoder& DER_Encoder::encode(const byte bytes[], size_t length, - ASN1_Tag real_type, - ASN1_Tag type_tag, ASN1_Tag class_tag) - { - if(real_type != OCTET_STRING && real_type != BIT_STRING) - throw Invalid_Argument("DER_Encoder: Invalid tag for byte/bit string"); - - if(real_type == BIT_STRING) - { - SecureVector encoded; - encoded.push_back(0); - encoded += std::make_pair(bytes, length); - return add_object(type_tag, class_tag, encoded); - } - else - return add_object(type_tag, class_tag, bytes, length); - } - -/* -* Conditionally write some values to the stream -*/ -DER_Encoder& DER_Encoder::encode_if(bool cond, DER_Encoder& codec) - { - if(cond) - return raw_bytes(codec.get_contents()); - return (*this); - } - -/* -* Request for an object to encode itself -*/ -DER_Encoder& DER_Encoder::encode(const ASN1_Object& obj) - { - obj.encode_into(*this); - return (*this); - } - -/* -* Write the encoding of the byte(s) -*/ -DER_Encoder& DER_Encoder::add_object(ASN1_Tag type_tag, ASN1_Tag class_tag, - const byte rep[], size_t length) - { - SecureVector buffer; - buffer += encode_tag(type_tag, class_tag); - buffer += encode_length(length); - buffer += std::make_pair(rep, length); - - return raw_bytes(buffer); - } - -/* -* Write the encoding of the byte(s) -*/ -DER_Encoder& DER_Encoder::add_object(ASN1_Tag type_tag, ASN1_Tag class_tag, - const MemoryRegion& rep_buf) - { - const byte* rep = &rep_buf[0]; - const size_t rep_len = rep_buf.size(); - return add_object(type_tag, class_tag, rep, rep_len); - } - -/* -* Write the encoding of the byte(s) -*/ -DER_Encoder& DER_Encoder::add_object(ASN1_Tag type_tag, ASN1_Tag class_tag, - const std::string& rep_str) - { - const byte* rep = reinterpret_cast(rep_str.data()); - const size_t rep_len = rep_str.size(); - return add_object(type_tag, class_tag, rep, rep_len); - } - -/* -* Write the encoding of the byte -*/ -DER_Encoder& DER_Encoder::add_object(ASN1_Tag type_tag, - ASN1_Tag class_tag, byte rep) - { - return add_object(type_tag, class_tag, &rep, 1); - } - -} -/* -* X509_DN -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -/* -* Create an empty X509_DN -*/ -X509_DN::X509_DN() - { - } - -/* -* Create an X509_DN -*/ -X509_DN::X509_DN(const std::multimap& args) - { - std::multimap::const_iterator j; - for(j = args.begin(); j != args.end(); ++j) - add_attribute(j->first, j->second); - } - -/* -* Create an X509_DN -*/ -X509_DN::X509_DN(const std::multimap& args) - { - std::multimap::const_iterator j; - for(j = args.begin(); j != args.end(); ++j) - add_attribute(OIDS::lookup(j->first), j->second); - } - -/* -* Add an attribute to a X509_DN -*/ -void X509_DN::add_attribute(const std::string& type, - const std::string& str) - { - OID oid = OIDS::lookup(type); - add_attribute(oid, str); - } - -/* -* Add an attribute to a X509_DN -*/ -void X509_DN::add_attribute(const OID& oid, const std::string& str) - { - if(str == "") - return; - - typedef std::multimap::iterator rdn_iter; - - std::pair range = dn_info.equal_range(oid); - for(rdn_iter j = range.first; j != range.second; ++j) - if(j->second.value() == str) - return; - - multimap_insert(dn_info, oid, ASN1_String(str)); - dn_bits.clear(); - } - -/* -* Get the attributes of this X509_DN -*/ -std::multimap X509_DN::get_attributes() const - { - typedef std::multimap::const_iterator rdn_iter; - - std::multimap retval; - for(rdn_iter j = dn_info.begin(); j != dn_info.end(); ++j) - multimap_insert(retval, j->first, j->second.value()); - return retval; - } - -/* -* Get the contents of this X.500 Name -*/ -std::multimap X509_DN::contents() const - { - typedef std::multimap::const_iterator rdn_iter; - - std::multimap retval; - for(rdn_iter j = dn_info.begin(); j != dn_info.end(); ++j) - multimap_insert(retval, OIDS::lookup(j->first), j->second.value()); - return retval; - } - -/* -* Get a single attribute type -*/ -std::vector X509_DN::get_attribute(const std::string& attr) const - { - typedef std::multimap::const_iterator rdn_iter; - - const OID oid = OIDS::lookup(deref_info_field(attr)); - std::pair range = dn_info.equal_range(oid); - - std::vector values; - for(rdn_iter j = range.first; j != range.second; ++j) - values.push_back(j->second.value()); - return values; - } - -/* -* Return the BER encoded data, if any -*/ -MemoryVector X509_DN::get_bits() const - { - return dn_bits; - } - -/* -* Deref aliases in a subject/issuer info request -*/ -std::string X509_DN::deref_info_field(const std::string& info) - { - if(info == "Name" || info == "CommonName") return "X520.CommonName"; - if(info == "SerialNumber") return "X520.SerialNumber"; - if(info == "Country") return "X520.Country"; - if(info == "Organization") return "X520.Organization"; - if(info == "Organizational Unit" || info == "OrgUnit") - return "X520.OrganizationalUnit"; - if(info == "Locality") return "X520.Locality"; - if(info == "State" || info == "Province") return "X520.State"; - if(info == "Email") return "RFC822"; - return info; - } - -/* -* Compare two X509_DNs for equality -*/ -bool operator==(const X509_DN& dn1, const X509_DN& dn2) - { - typedef std::multimap::const_iterator rdn_iter; - - std::multimap attr1 = dn1.get_attributes(); - std::multimap attr2 = dn2.get_attributes(); - - if(attr1.size() != attr2.size()) return false; - - rdn_iter p1 = attr1.begin(); - rdn_iter p2 = attr2.begin(); - - while(true) - { - if(p1 == attr1.end() && p2 == attr2.end()) - break; - if(p1 == attr1.end()) return false; - if(p2 == attr2.end()) return false; - if(p1->first != p2->first) return false; - if(!x500_name_cmp(p1->second, p2->second)) - return false; - ++p1; - ++p2; - } - return true; - } - -/* -* Compare two X509_DNs for inequality -*/ -bool operator!=(const X509_DN& dn1, const X509_DN& dn2) - { - return !(dn1 == dn2); - } - -/* -* Compare two X509_DNs -*/ -bool operator<(const X509_DN& dn1, const X509_DN& dn2) - { - typedef std::multimap::const_iterator rdn_iter; - - std::multimap attr1 = dn1.get_attributes(); - std::multimap attr2 = dn2.get_attributes(); - - if(attr1.size() < attr2.size()) return true; - if(attr1.size() > attr2.size()) return false; - - for(rdn_iter p1 = attr1.begin(); p1 != attr1.end(); ++p1) - { - std::multimap::const_iterator p2; - p2 = attr2.find(p1->first); - if(p2 == attr2.end()) return false; - if(p1->second > p2->second) return false; - if(p1->second < p2->second) return true; - } - return false; - } - -namespace { - -/* -* DER encode a RelativeDistinguishedName -*/ -void do_ava(DER_Encoder& encoder, - const std::multimap& dn_info, - ASN1_Tag string_type, const std::string& oid_str, - bool must_exist = false) - { - typedef std::multimap::const_iterator rdn_iter; - - const OID oid = OIDS::lookup(oid_str); - const bool exists = (dn_info.find(oid) != dn_info.end()); - - if(!exists && must_exist) - throw Encoding_Error("X509_DN: No entry for " + oid_str); - if(!exists) return; - - std::pair range = dn_info.equal_range(oid); - - for(rdn_iter j = range.first; j != range.second; ++j) - { - encoder.start_cons(SET) - .start_cons(SEQUENCE) - .encode(oid) - .encode(ASN1_String(j->second, string_type)) - .end_cons() - .end_cons(); - } - } - -} - -/* -* DER encode a DistinguishedName -*/ -void X509_DN::encode_into(DER_Encoder& der) const - { - std::multimap dn_info = get_attributes(); - - der.start_cons(SEQUENCE); - - if(!dn_bits.empty()) - der.raw_bytes(dn_bits); - else - { - do_ava(der, dn_info, PRINTABLE_STRING, "X520.Country"); - do_ava(der, dn_info, DIRECTORY_STRING, "X520.State"); - do_ava(der, dn_info, DIRECTORY_STRING, "X520.Locality"); - do_ava(der, dn_info, DIRECTORY_STRING, "X520.Organization"); - do_ava(der, dn_info, DIRECTORY_STRING, "X520.OrganizationalUnit"); - do_ava(der, dn_info, DIRECTORY_STRING, "X520.CommonName"); - do_ava(der, dn_info, PRINTABLE_STRING, "X520.SerialNumber"); - } - - der.end_cons(); - } - -/* -* Decode a BER encoded DistinguishedName -*/ -void X509_DN::decode_from(BER_Decoder& source) - { - MemoryVector bits; - - source.start_cons(SEQUENCE) - .raw_bytes(bits) - .end_cons(); - - BER_Decoder sequence(bits); - - while(sequence.more_items()) - { - BER_Decoder rdn = sequence.start_cons(SET); - - while(rdn.more_items()) - { - OID oid; - ASN1_String str; - - rdn.start_cons(SEQUENCE) - .decode(oid) - .decode(str) - .verify_end() - .end_cons(); - - add_attribute(oid, str.value()); - } - } - - dn_bits = bits; - } - -} -/* -* Runtime benchmarking -* (C) 2008 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include - -namespace Botan { - -namespace { - -/** -* Benchmark Buffered_Computation (hash or MAC) -*/ -std::pair bench_buf_comp(Buffered_Computation* buf_comp, - u64bit nanoseconds_max, - const byte buf[], size_t buf_len) - { - u64bit reps = 0; - u64bit nanoseconds_used = 0; - - while(nanoseconds_used < nanoseconds_max) - { - const u64bit start = get_nanoseconds_clock(); - buf_comp->update(buf, buf_len); - nanoseconds_used += get_nanoseconds_clock() - start; - - ++reps; - } - - return std::make_pair(reps * buf_len, nanoseconds_used); - } - -/** -* Benchmark block cipher -*/ -std::pair -bench_block_cipher(BlockCipher* block_cipher, - u64bit nanoseconds_max, - byte buf[], size_t buf_len) - { - const size_t in_blocks = buf_len / block_cipher->block_size(); - - u64bit reps = 0; - u64bit nanoseconds_used = 0; - - block_cipher->set_key(buf, block_cipher->maximum_keylength()); - - while(nanoseconds_used < nanoseconds_max) - { - const u64bit start = get_nanoseconds_clock(); - block_cipher->encrypt_n(buf, buf, in_blocks); - nanoseconds_used += get_nanoseconds_clock() - start; - - ++reps; - } - - return std::make_pair(reps * in_blocks * block_cipher->block_size(), - nanoseconds_used); - } - -/** -* Benchmark stream -*/ -std::pair -bench_stream_cipher(StreamCipher* stream_cipher, - u64bit nanoseconds_max, - byte buf[], size_t buf_len) - { - u64bit reps = 0; - u64bit nanoseconds_used = 0; - - stream_cipher->set_key(buf, stream_cipher->maximum_keylength()); - - while(nanoseconds_used < nanoseconds_max) - { - const u64bit start = get_nanoseconds_clock(); - stream_cipher->cipher1(buf, buf_len); - nanoseconds_used += get_nanoseconds_clock() - start; - - ++reps; - } - - return std::make_pair(reps * buf_len, nanoseconds_used); - } - -/** -* Benchmark hash -*/ -std::pair -bench_hash(HashFunction* hash, - u64bit nanoseconds_max, - const byte buf[], size_t buf_len) - { - return bench_buf_comp(hash, nanoseconds_max, buf, buf_len); - } - -/** -* Benchmark MAC -*/ -std::pair -bench_mac(MessageAuthenticationCode* mac, - u64bit nanoseconds_max, - const byte buf[], size_t buf_len) - { - mac->set_key(buf, mac->maximum_keylength()); - return bench_buf_comp(mac, nanoseconds_max, buf, buf_len); - } - -} - -std::map -algorithm_benchmark(const std::string& name, - Algorithm_Factory& af, - RandomNumberGenerator& rng, - u32bit milliseconds, - size_t buf_size) - { - std::vector providers = af.providers_of(name); - std::map all_results; - - if(providers.empty()) // no providers, nothing to do - return all_results; - - const u64bit ns_per_provider = - (static_cast(milliseconds) * 1000 * 1000) / providers.size(); - - std::vector buf(buf_size * 1024); - rng.randomize(&buf[0], buf.size()); - - for(size_t i = 0; i != providers.size(); ++i) - { - const std::string provider = providers[i]; - - std::pair results(0, 0); - - if(const BlockCipher* proto = - af.prototype_block_cipher(name, provider)) - { - std::unique_ptr block_cipher(proto->clone()); - results = bench_block_cipher(block_cipher.get(), - ns_per_provider, - &buf[0], buf.size()); - } - else if(const StreamCipher* proto = - af.prototype_stream_cipher(name, provider)) - { - std::unique_ptr stream_cipher(proto->clone()); - results = bench_stream_cipher(stream_cipher.get(), - ns_per_provider, - &buf[0], buf.size()); - } - else if(const HashFunction* proto = - af.prototype_hash_function(name, provider)) - { - std::unique_ptr hash(proto->clone()); - results = bench_hash(hash.get(), ns_per_provider, - &buf[0], buf.size()); - } - else if(const MessageAuthenticationCode* proto = - af.prototype_mac(name, provider)) - { - std::unique_ptr mac(proto->clone()); - results = bench_mac(mac.get(), ns_per_provider, - &buf[0], buf.size()); - } - - if(results.first && results.second) - { - /* 953.67 == 1000 * 1000 * 1000 / 1024 / 1024 - the conversion - factor from bytes per nanosecond to mebibytes per second. - */ - double speed = (953.67 * results.first) / results.second; - all_results[provider] = speed; - } - } - - return all_results; - } - -} -/* -* AES -* (C) 1999-2010 Jack Lloyd -* -* Based on the public domain reference implemenation -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -namespace { - -const byte SE[256] = { - 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, - 0xFE, 0xD7, 0xAB, 0x76, 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, - 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, 0xB7, 0xFD, 0x93, 0x26, - 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, - 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, - 0xEB, 0x27, 0xB2, 0x75, 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, - 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, 0x53, 0xD1, 0x00, 0xED, - 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, - 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, - 0x50, 0x3C, 0x9F, 0xA8, 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, - 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, 0xCD, 0x0C, 0x13, 0xEC, - 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73, - 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, - 0xDE, 0x5E, 0x0B, 0xDB, 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, - 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, 0xE7, 0xC8, 0x37, 0x6D, - 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08, - 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, - 0x4B, 0xBD, 0x8B, 0x8A, 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, - 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, 0xE1, 0xF8, 0x98, 0x11, - 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF, - 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, - 0xB0, 0x54, 0xBB, 0x16 }; - -const byte SD[256] = { - 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, - 0x81, 0xF3, 0xD7, 0xFB, 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, - 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB, 0x54, 0x7B, 0x94, 0x32, - 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E, - 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, - 0x6D, 0x8B, 0xD1, 0x25, 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, - 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92, 0x6C, 0x70, 0x48, 0x50, - 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84, - 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, - 0xB8, 0xB3, 0x45, 0x06, 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, - 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B, 0x3A, 0x91, 0x11, 0x41, - 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73, - 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, - 0x1C, 0x75, 0xDF, 0x6E, 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, - 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B, 0xFC, 0x56, 0x3E, 0x4B, - 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4, - 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, - 0x27, 0x80, 0xEC, 0x5F, 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, - 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF, 0xA0, 0xE0, 0x3B, 0x4D, - 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61, - 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, - 0x55, 0x21, 0x0C, 0x7D }; - -const u32bit TE[1024] = { - 0xC66363A5, 0xF87C7C84, 0xEE777799, 0xF67B7B8D, 0xFFF2F20D, 0xD66B6BBD, - 0xDE6F6FB1, 0x91C5C554, 0x60303050, 0x02010103, 0xCE6767A9, 0x562B2B7D, - 0xE7FEFE19, 0xB5D7D762, 0x4DABABE6, 0xEC76769A, 0x8FCACA45, 0x1F82829D, - 0x89C9C940, 0xFA7D7D87, 0xEFFAFA15, 0xB25959EB, 0x8E4747C9, 0xFBF0F00B, - 0x41ADADEC, 0xB3D4D467, 0x5FA2A2FD, 0x45AFAFEA, 0x239C9CBF, 0x53A4A4F7, - 0xE4727296, 0x9BC0C05B, 0x75B7B7C2, 0xE1FDFD1C, 0x3D9393AE, 0x4C26266A, - 0x6C36365A, 0x7E3F3F41, 0xF5F7F702, 0x83CCCC4F, 0x6834345C, 0x51A5A5F4, - 0xD1E5E534, 0xF9F1F108, 0xE2717193, 0xABD8D873, 0x62313153, 0x2A15153F, - 0x0804040C, 0x95C7C752, 0x46232365, 0x9DC3C35E, 0x30181828, 0x379696A1, - 0x0A05050F, 0x2F9A9AB5, 0x0E070709, 0x24121236, 0x1B80809B, 0xDFE2E23D, - 0xCDEBEB26, 0x4E272769, 0x7FB2B2CD, 0xEA75759F, 0x1209091B, 0x1D83839E, - 0x582C2C74, 0x341A1A2E, 0x361B1B2D, 0xDC6E6EB2, 0xB45A5AEE, 0x5BA0A0FB, - 0xA45252F6, 0x763B3B4D, 0xB7D6D661, 0x7DB3B3CE, 0x5229297B, 0xDDE3E33E, - 0x5E2F2F71, 0x13848497, 0xA65353F5, 0xB9D1D168, 0x00000000, 0xC1EDED2C, - 0x40202060, 0xE3FCFC1F, 0x79B1B1C8, 0xB65B5BED, 0xD46A6ABE, 0x8DCBCB46, - 0x67BEBED9, 0x7239394B, 0x944A4ADE, 0x984C4CD4, 0xB05858E8, 0x85CFCF4A, - 0xBBD0D06B, 0xC5EFEF2A, 0x4FAAAAE5, 0xEDFBFB16, 0x864343C5, 0x9A4D4DD7, - 0x66333355, 0x11858594, 0x8A4545CF, 0xE9F9F910, 0x04020206, 0xFE7F7F81, - 0xA05050F0, 0x783C3C44, 0x259F9FBA, 0x4BA8A8E3, 0xA25151F3, 0x5DA3A3FE, - 0x804040C0, 0x058F8F8A, 0x3F9292AD, 0x219D9DBC, 0x70383848, 0xF1F5F504, - 0x63BCBCDF, 0x77B6B6C1, 0xAFDADA75, 0x42212163, 0x20101030, 0xE5FFFF1A, - 0xFDF3F30E, 0xBFD2D26D, 0x81CDCD4C, 0x180C0C14, 0x26131335, 0xC3ECEC2F, - 0xBE5F5FE1, 0x359797A2, 0x884444CC, 0x2E171739, 0x93C4C457, 0x55A7A7F2, - 0xFC7E7E82, 0x7A3D3D47, 0xC86464AC, 0xBA5D5DE7, 0x3219192B, 0xE6737395, - 0xC06060A0, 0x19818198, 0x9E4F4FD1, 0xA3DCDC7F, 0x44222266, 0x542A2A7E, - 0x3B9090AB, 0x0B888883, 0x8C4646CA, 0xC7EEEE29, 0x6BB8B8D3, 0x2814143C, - 0xA7DEDE79, 0xBC5E5EE2, 0x160B0B1D, 0xADDBDB76, 0xDBE0E03B, 0x64323256, - 0x743A3A4E, 0x140A0A1E, 0x924949DB, 0x0C06060A, 0x4824246C, 0xB85C5CE4, - 0x9FC2C25D, 0xBDD3D36E, 0x43ACACEF, 0xC46262A6, 0x399191A8, 0x319595A4, - 0xD3E4E437, 0xF279798B, 0xD5E7E732, 0x8BC8C843, 0x6E373759, 0xDA6D6DB7, - 0x018D8D8C, 0xB1D5D564, 0x9C4E4ED2, 0x49A9A9E0, 0xD86C6CB4, 0xAC5656FA, - 0xF3F4F407, 0xCFEAEA25, 0xCA6565AF, 0xF47A7A8E, 0x47AEAEE9, 0x10080818, - 0x6FBABAD5, 0xF0787888, 0x4A25256F, 0x5C2E2E72, 0x381C1C24, 0x57A6A6F1, - 0x73B4B4C7, 0x97C6C651, 0xCBE8E823, 0xA1DDDD7C, 0xE874749C, 0x3E1F1F21, - 0x964B4BDD, 0x61BDBDDC, 0x0D8B8B86, 0x0F8A8A85, 0xE0707090, 0x7C3E3E42, - 0x71B5B5C4, 0xCC6666AA, 0x904848D8, 0x06030305, 0xF7F6F601, 0x1C0E0E12, - 0xC26161A3, 0x6A35355F, 0xAE5757F9, 0x69B9B9D0, 0x17868691, 0x99C1C158, - 0x3A1D1D27, 0x279E9EB9, 0xD9E1E138, 0xEBF8F813, 0x2B9898B3, 0x22111133, - 0xD26969BB, 0xA9D9D970, 0x078E8E89, 0x339494A7, 0x2D9B9BB6, 0x3C1E1E22, - 0x15878792, 0xC9E9E920, 0x87CECE49, 0xAA5555FF, 0x50282878, 0xA5DFDF7A, - 0x038C8C8F, 0x59A1A1F8, 0x09898980, 0x1A0D0D17, 0x65BFBFDA, 0xD7E6E631, - 0x844242C6, 0xD06868B8, 0x824141C3, 0x299999B0, 0x5A2D2D77, 0x1E0F0F11, - 0x7BB0B0CB, 0xA85454FC, 0x6DBBBBD6, 0x2C16163A, 0xA5C66363, 0x84F87C7C, - 0x99EE7777, 0x8DF67B7B, 0x0DFFF2F2, 0xBDD66B6B, 0xB1DE6F6F, 0x5491C5C5, - 0x50603030, 0x03020101, 0xA9CE6767, 0x7D562B2B, 0x19E7FEFE, 0x62B5D7D7, - 0xE64DABAB, 0x9AEC7676, 0x458FCACA, 0x9D1F8282, 0x4089C9C9, 0x87FA7D7D, - 0x15EFFAFA, 0xEBB25959, 0xC98E4747, 0x0BFBF0F0, 0xEC41ADAD, 0x67B3D4D4, - 0xFD5FA2A2, 0xEA45AFAF, 0xBF239C9C, 0xF753A4A4, 0x96E47272, 0x5B9BC0C0, - 0xC275B7B7, 0x1CE1FDFD, 0xAE3D9393, 0x6A4C2626, 0x5A6C3636, 0x417E3F3F, - 0x02F5F7F7, 0x4F83CCCC, 0x5C683434, 0xF451A5A5, 0x34D1E5E5, 0x08F9F1F1, - 0x93E27171, 0x73ABD8D8, 0x53623131, 0x3F2A1515, 0x0C080404, 0x5295C7C7, - 0x65462323, 0x5E9DC3C3, 0x28301818, 0xA1379696, 0x0F0A0505, 0xB52F9A9A, - 0x090E0707, 0x36241212, 0x9B1B8080, 0x3DDFE2E2, 0x26CDEBEB, 0x694E2727, - 0xCD7FB2B2, 0x9FEA7575, 0x1B120909, 0x9E1D8383, 0x74582C2C, 0x2E341A1A, - 0x2D361B1B, 0xB2DC6E6E, 0xEEB45A5A, 0xFB5BA0A0, 0xF6A45252, 0x4D763B3B, - 0x61B7D6D6, 0xCE7DB3B3, 0x7B522929, 0x3EDDE3E3, 0x715E2F2F, 0x97138484, - 0xF5A65353, 0x68B9D1D1, 0x00000000, 0x2CC1EDED, 0x60402020, 0x1FE3FCFC, - 0xC879B1B1, 0xEDB65B5B, 0xBED46A6A, 0x468DCBCB, 0xD967BEBE, 0x4B723939, - 0xDE944A4A, 0xD4984C4C, 0xE8B05858, 0x4A85CFCF, 0x6BBBD0D0, 0x2AC5EFEF, - 0xE54FAAAA, 0x16EDFBFB, 0xC5864343, 0xD79A4D4D, 0x55663333, 0x94118585, - 0xCF8A4545, 0x10E9F9F9, 0x06040202, 0x81FE7F7F, 0xF0A05050, 0x44783C3C, - 0xBA259F9F, 0xE34BA8A8, 0xF3A25151, 0xFE5DA3A3, 0xC0804040, 0x8A058F8F, - 0xAD3F9292, 0xBC219D9D, 0x48703838, 0x04F1F5F5, 0xDF63BCBC, 0xC177B6B6, - 0x75AFDADA, 0x63422121, 0x30201010, 0x1AE5FFFF, 0x0EFDF3F3, 0x6DBFD2D2, - 0x4C81CDCD, 0x14180C0C, 0x35261313, 0x2FC3ECEC, 0xE1BE5F5F, 0xA2359797, - 0xCC884444, 0x392E1717, 0x5793C4C4, 0xF255A7A7, 0x82FC7E7E, 0x477A3D3D, - 0xACC86464, 0xE7BA5D5D, 0x2B321919, 0x95E67373, 0xA0C06060, 0x98198181, - 0xD19E4F4F, 0x7FA3DCDC, 0x66442222, 0x7E542A2A, 0xAB3B9090, 0x830B8888, - 0xCA8C4646, 0x29C7EEEE, 0xD36BB8B8, 0x3C281414, 0x79A7DEDE, 0xE2BC5E5E, - 0x1D160B0B, 0x76ADDBDB, 0x3BDBE0E0, 0x56643232, 0x4E743A3A, 0x1E140A0A, - 0xDB924949, 0x0A0C0606, 0x6C482424, 0xE4B85C5C, 0x5D9FC2C2, 0x6EBDD3D3, - 0xEF43ACAC, 0xA6C46262, 0xA8399191, 0xA4319595, 0x37D3E4E4, 0x8BF27979, - 0x32D5E7E7, 0x438BC8C8, 0x596E3737, 0xB7DA6D6D, 0x8C018D8D, 0x64B1D5D5, - 0xD29C4E4E, 0xE049A9A9, 0xB4D86C6C, 0xFAAC5656, 0x07F3F4F4, 0x25CFEAEA, - 0xAFCA6565, 0x8EF47A7A, 0xE947AEAE, 0x18100808, 0xD56FBABA, 0x88F07878, - 0x6F4A2525, 0x725C2E2E, 0x24381C1C, 0xF157A6A6, 0xC773B4B4, 0x5197C6C6, - 0x23CBE8E8, 0x7CA1DDDD, 0x9CE87474, 0x213E1F1F, 0xDD964B4B, 0xDC61BDBD, - 0x860D8B8B, 0x850F8A8A, 0x90E07070, 0x427C3E3E, 0xC471B5B5, 0xAACC6666, - 0xD8904848, 0x05060303, 0x01F7F6F6, 0x121C0E0E, 0xA3C26161, 0x5F6A3535, - 0xF9AE5757, 0xD069B9B9, 0x91178686, 0x5899C1C1, 0x273A1D1D, 0xB9279E9E, - 0x38D9E1E1, 0x13EBF8F8, 0xB32B9898, 0x33221111, 0xBBD26969, 0x70A9D9D9, - 0x89078E8E, 0xA7339494, 0xB62D9B9B, 0x223C1E1E, 0x92158787, 0x20C9E9E9, - 0x4987CECE, 0xFFAA5555, 0x78502828, 0x7AA5DFDF, 0x8F038C8C, 0xF859A1A1, - 0x80098989, 0x171A0D0D, 0xDA65BFBF, 0x31D7E6E6, 0xC6844242, 0xB8D06868, - 0xC3824141, 0xB0299999, 0x775A2D2D, 0x111E0F0F, 0xCB7BB0B0, 0xFCA85454, - 0xD66DBBBB, 0x3A2C1616, 0x63A5C663, 0x7C84F87C, 0x7799EE77, 0x7B8DF67B, - 0xF20DFFF2, 0x6BBDD66B, 0x6FB1DE6F, 0xC55491C5, 0x30506030, 0x01030201, - 0x67A9CE67, 0x2B7D562B, 0xFE19E7FE, 0xD762B5D7, 0xABE64DAB, 0x769AEC76, - 0xCA458FCA, 0x829D1F82, 0xC94089C9, 0x7D87FA7D, 0xFA15EFFA, 0x59EBB259, - 0x47C98E47, 0xF00BFBF0, 0xADEC41AD, 0xD467B3D4, 0xA2FD5FA2, 0xAFEA45AF, - 0x9CBF239C, 0xA4F753A4, 0x7296E472, 0xC05B9BC0, 0xB7C275B7, 0xFD1CE1FD, - 0x93AE3D93, 0x266A4C26, 0x365A6C36, 0x3F417E3F, 0xF702F5F7, 0xCC4F83CC, - 0x345C6834, 0xA5F451A5, 0xE534D1E5, 0xF108F9F1, 0x7193E271, 0xD873ABD8, - 0x31536231, 0x153F2A15, 0x040C0804, 0xC75295C7, 0x23654623, 0xC35E9DC3, - 0x18283018, 0x96A13796, 0x050F0A05, 0x9AB52F9A, 0x07090E07, 0x12362412, - 0x809B1B80, 0xE23DDFE2, 0xEB26CDEB, 0x27694E27, 0xB2CD7FB2, 0x759FEA75, - 0x091B1209, 0x839E1D83, 0x2C74582C, 0x1A2E341A, 0x1B2D361B, 0x6EB2DC6E, - 0x5AEEB45A, 0xA0FB5BA0, 0x52F6A452, 0x3B4D763B, 0xD661B7D6, 0xB3CE7DB3, - 0x297B5229, 0xE33EDDE3, 0x2F715E2F, 0x84971384, 0x53F5A653, 0xD168B9D1, - 0x00000000, 0xED2CC1ED, 0x20604020, 0xFC1FE3FC, 0xB1C879B1, 0x5BEDB65B, - 0x6ABED46A, 0xCB468DCB, 0xBED967BE, 0x394B7239, 0x4ADE944A, 0x4CD4984C, - 0x58E8B058, 0xCF4A85CF, 0xD06BBBD0, 0xEF2AC5EF, 0xAAE54FAA, 0xFB16EDFB, - 0x43C58643, 0x4DD79A4D, 0x33556633, 0x85941185, 0x45CF8A45, 0xF910E9F9, - 0x02060402, 0x7F81FE7F, 0x50F0A050, 0x3C44783C, 0x9FBA259F, 0xA8E34BA8, - 0x51F3A251, 0xA3FE5DA3, 0x40C08040, 0x8F8A058F, 0x92AD3F92, 0x9DBC219D, - 0x38487038, 0xF504F1F5, 0xBCDF63BC, 0xB6C177B6, 0xDA75AFDA, 0x21634221, - 0x10302010, 0xFF1AE5FF, 0xF30EFDF3, 0xD26DBFD2, 0xCD4C81CD, 0x0C14180C, - 0x13352613, 0xEC2FC3EC, 0x5FE1BE5F, 0x97A23597, 0x44CC8844, 0x17392E17, - 0xC45793C4, 0xA7F255A7, 0x7E82FC7E, 0x3D477A3D, 0x64ACC864, 0x5DE7BA5D, - 0x192B3219, 0x7395E673, 0x60A0C060, 0x81981981, 0x4FD19E4F, 0xDC7FA3DC, - 0x22664422, 0x2A7E542A, 0x90AB3B90, 0x88830B88, 0x46CA8C46, 0xEE29C7EE, - 0xB8D36BB8, 0x143C2814, 0xDE79A7DE, 0x5EE2BC5E, 0x0B1D160B, 0xDB76ADDB, - 0xE03BDBE0, 0x32566432, 0x3A4E743A, 0x0A1E140A, 0x49DB9249, 0x060A0C06, - 0x246C4824, 0x5CE4B85C, 0xC25D9FC2, 0xD36EBDD3, 0xACEF43AC, 0x62A6C462, - 0x91A83991, 0x95A43195, 0xE437D3E4, 0x798BF279, 0xE732D5E7, 0xC8438BC8, - 0x37596E37, 0x6DB7DA6D, 0x8D8C018D, 0xD564B1D5, 0x4ED29C4E, 0xA9E049A9, - 0x6CB4D86C, 0x56FAAC56, 0xF407F3F4, 0xEA25CFEA, 0x65AFCA65, 0x7A8EF47A, - 0xAEE947AE, 0x08181008, 0xBAD56FBA, 0x7888F078, 0x256F4A25, 0x2E725C2E, - 0x1C24381C, 0xA6F157A6, 0xB4C773B4, 0xC65197C6, 0xE823CBE8, 0xDD7CA1DD, - 0x749CE874, 0x1F213E1F, 0x4BDD964B, 0xBDDC61BD, 0x8B860D8B, 0x8A850F8A, - 0x7090E070, 0x3E427C3E, 0xB5C471B5, 0x66AACC66, 0x48D89048, 0x03050603, - 0xF601F7F6, 0x0E121C0E, 0x61A3C261, 0x355F6A35, 0x57F9AE57, 0xB9D069B9, - 0x86911786, 0xC15899C1, 0x1D273A1D, 0x9EB9279E, 0xE138D9E1, 0xF813EBF8, - 0x98B32B98, 0x11332211, 0x69BBD269, 0xD970A9D9, 0x8E89078E, 0x94A73394, - 0x9BB62D9B, 0x1E223C1E, 0x87921587, 0xE920C9E9, 0xCE4987CE, 0x55FFAA55, - 0x28785028, 0xDF7AA5DF, 0x8C8F038C, 0xA1F859A1, 0x89800989, 0x0D171A0D, - 0xBFDA65BF, 0xE631D7E6, 0x42C68442, 0x68B8D068, 0x41C38241, 0x99B02999, - 0x2D775A2D, 0x0F111E0F, 0xB0CB7BB0, 0x54FCA854, 0xBBD66DBB, 0x163A2C16, - 0x6363A5C6, 0x7C7C84F8, 0x777799EE, 0x7B7B8DF6, 0xF2F20DFF, 0x6B6BBDD6, - 0x6F6FB1DE, 0xC5C55491, 0x30305060, 0x01010302, 0x6767A9CE, 0x2B2B7D56, - 0xFEFE19E7, 0xD7D762B5, 0xABABE64D, 0x76769AEC, 0xCACA458F, 0x82829D1F, - 0xC9C94089, 0x7D7D87FA, 0xFAFA15EF, 0x5959EBB2, 0x4747C98E, 0xF0F00BFB, - 0xADADEC41, 0xD4D467B3, 0xA2A2FD5F, 0xAFAFEA45, 0x9C9CBF23, 0xA4A4F753, - 0x727296E4, 0xC0C05B9B, 0xB7B7C275, 0xFDFD1CE1, 0x9393AE3D, 0x26266A4C, - 0x36365A6C, 0x3F3F417E, 0xF7F702F5, 0xCCCC4F83, 0x34345C68, 0xA5A5F451, - 0xE5E534D1, 0xF1F108F9, 0x717193E2, 0xD8D873AB, 0x31315362, 0x15153F2A, - 0x04040C08, 0xC7C75295, 0x23236546, 0xC3C35E9D, 0x18182830, 0x9696A137, - 0x05050F0A, 0x9A9AB52F, 0x0707090E, 0x12123624, 0x80809B1B, 0xE2E23DDF, - 0xEBEB26CD, 0x2727694E, 0xB2B2CD7F, 0x75759FEA, 0x09091B12, 0x83839E1D, - 0x2C2C7458, 0x1A1A2E34, 0x1B1B2D36, 0x6E6EB2DC, 0x5A5AEEB4, 0xA0A0FB5B, - 0x5252F6A4, 0x3B3B4D76, 0xD6D661B7, 0xB3B3CE7D, 0x29297B52, 0xE3E33EDD, - 0x2F2F715E, 0x84849713, 0x5353F5A6, 0xD1D168B9, 0x00000000, 0xEDED2CC1, - 0x20206040, 0xFCFC1FE3, 0xB1B1C879, 0x5B5BEDB6, 0x6A6ABED4, 0xCBCB468D, - 0xBEBED967, 0x39394B72, 0x4A4ADE94, 0x4C4CD498, 0x5858E8B0, 0xCFCF4A85, - 0xD0D06BBB, 0xEFEF2AC5, 0xAAAAE54F, 0xFBFB16ED, 0x4343C586, 0x4D4DD79A, - 0x33335566, 0x85859411, 0x4545CF8A, 0xF9F910E9, 0x02020604, 0x7F7F81FE, - 0x5050F0A0, 0x3C3C4478, 0x9F9FBA25, 0xA8A8E34B, 0x5151F3A2, 0xA3A3FE5D, - 0x4040C080, 0x8F8F8A05, 0x9292AD3F, 0x9D9DBC21, 0x38384870, 0xF5F504F1, - 0xBCBCDF63, 0xB6B6C177, 0xDADA75AF, 0x21216342, 0x10103020, 0xFFFF1AE5, - 0xF3F30EFD, 0xD2D26DBF, 0xCDCD4C81, 0x0C0C1418, 0x13133526, 0xECEC2FC3, - 0x5F5FE1BE, 0x9797A235, 0x4444CC88, 0x1717392E, 0xC4C45793, 0xA7A7F255, - 0x7E7E82FC, 0x3D3D477A, 0x6464ACC8, 0x5D5DE7BA, 0x19192B32, 0x737395E6, - 0x6060A0C0, 0x81819819, 0x4F4FD19E, 0xDCDC7FA3, 0x22226644, 0x2A2A7E54, - 0x9090AB3B, 0x8888830B, 0x4646CA8C, 0xEEEE29C7, 0xB8B8D36B, 0x14143C28, - 0xDEDE79A7, 0x5E5EE2BC, 0x0B0B1D16, 0xDBDB76AD, 0xE0E03BDB, 0x32325664, - 0x3A3A4E74, 0x0A0A1E14, 0x4949DB92, 0x06060A0C, 0x24246C48, 0x5C5CE4B8, - 0xC2C25D9F, 0xD3D36EBD, 0xACACEF43, 0x6262A6C4, 0x9191A839, 0x9595A431, - 0xE4E437D3, 0x79798BF2, 0xE7E732D5, 0xC8C8438B, 0x3737596E, 0x6D6DB7DA, - 0x8D8D8C01, 0xD5D564B1, 0x4E4ED29C, 0xA9A9E049, 0x6C6CB4D8, 0x5656FAAC, - 0xF4F407F3, 0xEAEA25CF, 0x6565AFCA, 0x7A7A8EF4, 0xAEAEE947, 0x08081810, - 0xBABAD56F, 0x787888F0, 0x25256F4A, 0x2E2E725C, 0x1C1C2438, 0xA6A6F157, - 0xB4B4C773, 0xC6C65197, 0xE8E823CB, 0xDDDD7CA1, 0x74749CE8, 0x1F1F213E, - 0x4B4BDD96, 0xBDBDDC61, 0x8B8B860D, 0x8A8A850F, 0x707090E0, 0x3E3E427C, - 0xB5B5C471, 0x6666AACC, 0x4848D890, 0x03030506, 0xF6F601F7, 0x0E0E121C, - 0x6161A3C2, 0x35355F6A, 0x5757F9AE, 0xB9B9D069, 0x86869117, 0xC1C15899, - 0x1D1D273A, 0x9E9EB927, 0xE1E138D9, 0xF8F813EB, 0x9898B32B, 0x11113322, - 0x6969BBD2, 0xD9D970A9, 0x8E8E8907, 0x9494A733, 0x9B9BB62D, 0x1E1E223C, - 0x87879215, 0xE9E920C9, 0xCECE4987, 0x5555FFAA, 0x28287850, 0xDFDF7AA5, - 0x8C8C8F03, 0xA1A1F859, 0x89898009, 0x0D0D171A, 0xBFBFDA65, 0xE6E631D7, - 0x4242C684, 0x6868B8D0, 0x4141C382, 0x9999B029, 0x2D2D775A, 0x0F0F111E, - 0xB0B0CB7B, 0x5454FCA8, 0xBBBBD66D, 0x16163A2C }; - -const u32bit TD[1024] = { - 0x51F4A750, 0x7E416553, 0x1A17A4C3, 0x3A275E96, 0x3BAB6BCB, 0x1F9D45F1, - 0xACFA58AB, 0x4BE30393, 0x2030FA55, 0xAD766DF6, 0x88CC7691, 0xF5024C25, - 0x4FE5D7FC, 0xC52ACBD7, 0x26354480, 0xB562A38F, 0xDEB15A49, 0x25BA1B67, - 0x45EA0E98, 0x5DFEC0E1, 0xC32F7502, 0x814CF012, 0x8D4697A3, 0x6BD3F9C6, - 0x038F5FE7, 0x15929C95, 0xBF6D7AEB, 0x955259DA, 0xD4BE832D, 0x587421D3, - 0x49E06929, 0x8EC9C844, 0x75C2896A, 0xF48E7978, 0x99583E6B, 0x27B971DD, - 0xBEE14FB6, 0xF088AD17, 0xC920AC66, 0x7DCE3AB4, 0x63DF4A18, 0xE51A3182, - 0x97513360, 0x62537F45, 0xB16477E0, 0xBB6BAE84, 0xFE81A01C, 0xF9082B94, - 0x70486858, 0x8F45FD19, 0x94DE6C87, 0x527BF8B7, 0xAB73D323, 0x724B02E2, - 0xE31F8F57, 0x6655AB2A, 0xB2EB2807, 0x2FB5C203, 0x86C57B9A, 0xD33708A5, - 0x302887F2, 0x23BFA5B2, 0x02036ABA, 0xED16825C, 0x8ACF1C2B, 0xA779B492, - 0xF307F2F0, 0x4E69E2A1, 0x65DAF4CD, 0x0605BED5, 0xD134621F, 0xC4A6FE8A, - 0x342E539D, 0xA2F355A0, 0x058AE132, 0xA4F6EB75, 0x0B83EC39, 0x4060EFAA, - 0x5E719F06, 0xBD6E1051, 0x3E218AF9, 0x96DD063D, 0xDD3E05AE, 0x4DE6BD46, - 0x91548DB5, 0x71C45D05, 0x0406D46F, 0x605015FF, 0x1998FB24, 0xD6BDE997, - 0x894043CC, 0x67D99E77, 0xB0E842BD, 0x07898B88, 0xE7195B38, 0x79C8EEDB, - 0xA17C0A47, 0x7C420FE9, 0xF8841EC9, 0x00000000, 0x09808683, 0x322BED48, - 0x1E1170AC, 0x6C5A724E, 0xFD0EFFFB, 0x0F853856, 0x3DAED51E, 0x362D3927, - 0x0A0FD964, 0x685CA621, 0x9B5B54D1, 0x24362E3A, 0x0C0A67B1, 0x9357E70F, - 0xB4EE96D2, 0x1B9B919E, 0x80C0C54F, 0x61DC20A2, 0x5A774B69, 0x1C121A16, - 0xE293BA0A, 0xC0A02AE5, 0x3C22E043, 0x121B171D, 0x0E090D0B, 0xF28BC7AD, - 0x2DB6A8B9, 0x141EA9C8, 0x57F11985, 0xAF75074C, 0xEE99DDBB, 0xA37F60FD, - 0xF701269F, 0x5C72F5BC, 0x44663BC5, 0x5BFB7E34, 0x8B432976, 0xCB23C6DC, - 0xB6EDFC68, 0xB8E4F163, 0xD731DCCA, 0x42638510, 0x13972240, 0x84C61120, - 0x854A247D, 0xD2BB3DF8, 0xAEF93211, 0xC729A16D, 0x1D9E2F4B, 0xDCB230F3, - 0x0D8652EC, 0x77C1E3D0, 0x2BB3166C, 0xA970B999, 0x119448FA, 0x47E96422, - 0xA8FC8CC4, 0xA0F03F1A, 0x567D2CD8, 0x223390EF, 0x87494EC7, 0xD938D1C1, - 0x8CCAA2FE, 0x98D40B36, 0xA6F581CF, 0xA57ADE28, 0xDAB78E26, 0x3FADBFA4, - 0x2C3A9DE4, 0x5078920D, 0x6A5FCC9B, 0x547E4662, 0xF68D13C2, 0x90D8B8E8, - 0x2E39F75E, 0x82C3AFF5, 0x9F5D80BE, 0x69D0937C, 0x6FD52DA9, 0xCF2512B3, - 0xC8AC993B, 0x10187DA7, 0xE89C636E, 0xDB3BBB7B, 0xCD267809, 0x6E5918F4, - 0xEC9AB701, 0x834F9AA8, 0xE6956E65, 0xAAFFE67E, 0x21BCCF08, 0xEF15E8E6, - 0xBAE79BD9, 0x4A6F36CE, 0xEA9F09D4, 0x29B07CD6, 0x31A4B2AF, 0x2A3F2331, - 0xC6A59430, 0x35A266C0, 0x744EBC37, 0xFC82CAA6, 0xE090D0B0, 0x33A7D815, - 0xF104984A, 0x41ECDAF7, 0x7FCD500E, 0x1791F62F, 0x764DD68D, 0x43EFB04D, - 0xCCAA4D54, 0xE49604DF, 0x9ED1B5E3, 0x4C6A881B, 0xC12C1FB8, 0x4665517F, - 0x9D5EEA04, 0x018C355D, 0xFA877473, 0xFB0B412E, 0xB3671D5A, 0x92DBD252, - 0xE9105633, 0x6DD64713, 0x9AD7618C, 0x37A10C7A, 0x59F8148E, 0xEB133C89, - 0xCEA927EE, 0xB761C935, 0xE11CE5ED, 0x7A47B13C, 0x9CD2DF59, 0x55F2733F, - 0x1814CE79, 0x73C737BF, 0x53F7CDEA, 0x5FFDAA5B, 0xDF3D6F14, 0x7844DB86, - 0xCAAFF381, 0xB968C43E, 0x3824342C, 0xC2A3405F, 0x161DC372, 0xBCE2250C, - 0x283C498B, 0xFF0D9541, 0x39A80171, 0x080CB3DE, 0xD8B4E49C, 0x6456C190, - 0x7BCB8461, 0xD532B670, 0x486C5C74, 0xD0B85742, 0x5051F4A7, 0x537E4165, - 0xC31A17A4, 0x963A275E, 0xCB3BAB6B, 0xF11F9D45, 0xABACFA58, 0x934BE303, - 0x552030FA, 0xF6AD766D, 0x9188CC76, 0x25F5024C, 0xFC4FE5D7, 0xD7C52ACB, - 0x80263544, 0x8FB562A3, 0x49DEB15A, 0x6725BA1B, 0x9845EA0E, 0xE15DFEC0, - 0x02C32F75, 0x12814CF0, 0xA38D4697, 0xC66BD3F9, 0xE7038F5F, 0x9515929C, - 0xEBBF6D7A, 0xDA955259, 0x2DD4BE83, 0xD3587421, 0x2949E069, 0x448EC9C8, - 0x6A75C289, 0x78F48E79, 0x6B99583E, 0xDD27B971, 0xB6BEE14F, 0x17F088AD, - 0x66C920AC, 0xB47DCE3A, 0x1863DF4A, 0x82E51A31, 0x60975133, 0x4562537F, - 0xE0B16477, 0x84BB6BAE, 0x1CFE81A0, 0x94F9082B, 0x58704868, 0x198F45FD, - 0x8794DE6C, 0xB7527BF8, 0x23AB73D3, 0xE2724B02, 0x57E31F8F, 0x2A6655AB, - 0x07B2EB28, 0x032FB5C2, 0x9A86C57B, 0xA5D33708, 0xF2302887, 0xB223BFA5, - 0xBA02036A, 0x5CED1682, 0x2B8ACF1C, 0x92A779B4, 0xF0F307F2, 0xA14E69E2, - 0xCD65DAF4, 0xD50605BE, 0x1FD13462, 0x8AC4A6FE, 0x9D342E53, 0xA0A2F355, - 0x32058AE1, 0x75A4F6EB, 0x390B83EC, 0xAA4060EF, 0x065E719F, 0x51BD6E10, - 0xF93E218A, 0x3D96DD06, 0xAEDD3E05, 0x464DE6BD, 0xB591548D, 0x0571C45D, - 0x6F0406D4, 0xFF605015, 0x241998FB, 0x97D6BDE9, 0xCC894043, 0x7767D99E, - 0xBDB0E842, 0x8807898B, 0x38E7195B, 0xDB79C8EE, 0x47A17C0A, 0xE97C420F, - 0xC9F8841E, 0x00000000, 0x83098086, 0x48322BED, 0xAC1E1170, 0x4E6C5A72, - 0xFBFD0EFF, 0x560F8538, 0x1E3DAED5, 0x27362D39, 0x640A0FD9, 0x21685CA6, - 0xD19B5B54, 0x3A24362E, 0xB10C0A67, 0x0F9357E7, 0xD2B4EE96, 0x9E1B9B91, - 0x4F80C0C5, 0xA261DC20, 0x695A774B, 0x161C121A, 0x0AE293BA, 0xE5C0A02A, - 0x433C22E0, 0x1D121B17, 0x0B0E090D, 0xADF28BC7, 0xB92DB6A8, 0xC8141EA9, - 0x8557F119, 0x4CAF7507, 0xBBEE99DD, 0xFDA37F60, 0x9FF70126, 0xBC5C72F5, - 0xC544663B, 0x345BFB7E, 0x768B4329, 0xDCCB23C6, 0x68B6EDFC, 0x63B8E4F1, - 0xCAD731DC, 0x10426385, 0x40139722, 0x2084C611, 0x7D854A24, 0xF8D2BB3D, - 0x11AEF932, 0x6DC729A1, 0x4B1D9E2F, 0xF3DCB230, 0xEC0D8652, 0xD077C1E3, - 0x6C2BB316, 0x99A970B9, 0xFA119448, 0x2247E964, 0xC4A8FC8C, 0x1AA0F03F, - 0xD8567D2C, 0xEF223390, 0xC787494E, 0xC1D938D1, 0xFE8CCAA2, 0x3698D40B, - 0xCFA6F581, 0x28A57ADE, 0x26DAB78E, 0xA43FADBF, 0xE42C3A9D, 0x0D507892, - 0x9B6A5FCC, 0x62547E46, 0xC2F68D13, 0xE890D8B8, 0x5E2E39F7, 0xF582C3AF, - 0xBE9F5D80, 0x7C69D093, 0xA96FD52D, 0xB3CF2512, 0x3BC8AC99, 0xA710187D, - 0x6EE89C63, 0x7BDB3BBB, 0x09CD2678, 0xF46E5918, 0x01EC9AB7, 0xA8834F9A, - 0x65E6956E, 0x7EAAFFE6, 0x0821BCCF, 0xE6EF15E8, 0xD9BAE79B, 0xCE4A6F36, - 0xD4EA9F09, 0xD629B07C, 0xAF31A4B2, 0x312A3F23, 0x30C6A594, 0xC035A266, - 0x37744EBC, 0xA6FC82CA, 0xB0E090D0, 0x1533A7D8, 0x4AF10498, 0xF741ECDA, - 0x0E7FCD50, 0x2F1791F6, 0x8D764DD6, 0x4D43EFB0, 0x54CCAA4D, 0xDFE49604, - 0xE39ED1B5, 0x1B4C6A88, 0xB8C12C1F, 0x7F466551, 0x049D5EEA, 0x5D018C35, - 0x73FA8774, 0x2EFB0B41, 0x5AB3671D, 0x5292DBD2, 0x33E91056, 0x136DD647, - 0x8C9AD761, 0x7A37A10C, 0x8E59F814, 0x89EB133C, 0xEECEA927, 0x35B761C9, - 0xEDE11CE5, 0x3C7A47B1, 0x599CD2DF, 0x3F55F273, 0x791814CE, 0xBF73C737, - 0xEA53F7CD, 0x5B5FFDAA, 0x14DF3D6F, 0x867844DB, 0x81CAAFF3, 0x3EB968C4, - 0x2C382434, 0x5FC2A340, 0x72161DC3, 0x0CBCE225, 0x8B283C49, 0x41FF0D95, - 0x7139A801, 0xDE080CB3, 0x9CD8B4E4, 0x906456C1, 0x617BCB84, 0x70D532B6, - 0x74486C5C, 0x42D0B857, 0xA75051F4, 0x65537E41, 0xA4C31A17, 0x5E963A27, - 0x6BCB3BAB, 0x45F11F9D, 0x58ABACFA, 0x03934BE3, 0xFA552030, 0x6DF6AD76, - 0x769188CC, 0x4C25F502, 0xD7FC4FE5, 0xCBD7C52A, 0x44802635, 0xA38FB562, - 0x5A49DEB1, 0x1B6725BA, 0x0E9845EA, 0xC0E15DFE, 0x7502C32F, 0xF012814C, - 0x97A38D46, 0xF9C66BD3, 0x5FE7038F, 0x9C951592, 0x7AEBBF6D, 0x59DA9552, - 0x832DD4BE, 0x21D35874, 0x692949E0, 0xC8448EC9, 0x896A75C2, 0x7978F48E, - 0x3E6B9958, 0x71DD27B9, 0x4FB6BEE1, 0xAD17F088, 0xAC66C920, 0x3AB47DCE, - 0x4A1863DF, 0x3182E51A, 0x33609751, 0x7F456253, 0x77E0B164, 0xAE84BB6B, - 0xA01CFE81, 0x2B94F908, 0x68587048, 0xFD198F45, 0x6C8794DE, 0xF8B7527B, - 0xD323AB73, 0x02E2724B, 0x8F57E31F, 0xAB2A6655, 0x2807B2EB, 0xC2032FB5, - 0x7B9A86C5, 0x08A5D337, 0x87F23028, 0xA5B223BF, 0x6ABA0203, 0x825CED16, - 0x1C2B8ACF, 0xB492A779, 0xF2F0F307, 0xE2A14E69, 0xF4CD65DA, 0xBED50605, - 0x621FD134, 0xFE8AC4A6, 0x539D342E, 0x55A0A2F3, 0xE132058A, 0xEB75A4F6, - 0xEC390B83, 0xEFAA4060, 0x9F065E71, 0x1051BD6E, 0x8AF93E21, 0x063D96DD, - 0x05AEDD3E, 0xBD464DE6, 0x8DB59154, 0x5D0571C4, 0xD46F0406, 0x15FF6050, - 0xFB241998, 0xE997D6BD, 0x43CC8940, 0x9E7767D9, 0x42BDB0E8, 0x8B880789, - 0x5B38E719, 0xEEDB79C8, 0x0A47A17C, 0x0FE97C42, 0x1EC9F884, 0x00000000, - 0x86830980, 0xED48322B, 0x70AC1E11, 0x724E6C5A, 0xFFFBFD0E, 0x38560F85, - 0xD51E3DAE, 0x3927362D, 0xD9640A0F, 0xA621685C, 0x54D19B5B, 0x2E3A2436, - 0x67B10C0A, 0xE70F9357, 0x96D2B4EE, 0x919E1B9B, 0xC54F80C0, 0x20A261DC, - 0x4B695A77, 0x1A161C12, 0xBA0AE293, 0x2AE5C0A0, 0xE0433C22, 0x171D121B, - 0x0D0B0E09, 0xC7ADF28B, 0xA8B92DB6, 0xA9C8141E, 0x198557F1, 0x074CAF75, - 0xDDBBEE99, 0x60FDA37F, 0x269FF701, 0xF5BC5C72, 0x3BC54466, 0x7E345BFB, - 0x29768B43, 0xC6DCCB23, 0xFC68B6ED, 0xF163B8E4, 0xDCCAD731, 0x85104263, - 0x22401397, 0x112084C6, 0x247D854A, 0x3DF8D2BB, 0x3211AEF9, 0xA16DC729, - 0x2F4B1D9E, 0x30F3DCB2, 0x52EC0D86, 0xE3D077C1, 0x166C2BB3, 0xB999A970, - 0x48FA1194, 0x642247E9, 0x8CC4A8FC, 0x3F1AA0F0, 0x2CD8567D, 0x90EF2233, - 0x4EC78749, 0xD1C1D938, 0xA2FE8CCA, 0x0B3698D4, 0x81CFA6F5, 0xDE28A57A, - 0x8E26DAB7, 0xBFA43FAD, 0x9DE42C3A, 0x920D5078, 0xCC9B6A5F, 0x4662547E, - 0x13C2F68D, 0xB8E890D8, 0xF75E2E39, 0xAFF582C3, 0x80BE9F5D, 0x937C69D0, - 0x2DA96FD5, 0x12B3CF25, 0x993BC8AC, 0x7DA71018, 0x636EE89C, 0xBB7BDB3B, - 0x7809CD26, 0x18F46E59, 0xB701EC9A, 0x9AA8834F, 0x6E65E695, 0xE67EAAFF, - 0xCF0821BC, 0xE8E6EF15, 0x9BD9BAE7, 0x36CE4A6F, 0x09D4EA9F, 0x7CD629B0, - 0xB2AF31A4, 0x23312A3F, 0x9430C6A5, 0x66C035A2, 0xBC37744E, 0xCAA6FC82, - 0xD0B0E090, 0xD81533A7, 0x984AF104, 0xDAF741EC, 0x500E7FCD, 0xF62F1791, - 0xD68D764D, 0xB04D43EF, 0x4D54CCAA, 0x04DFE496, 0xB5E39ED1, 0x881B4C6A, - 0x1FB8C12C, 0x517F4665, 0xEA049D5E, 0x355D018C, 0x7473FA87, 0x412EFB0B, - 0x1D5AB367, 0xD25292DB, 0x5633E910, 0x47136DD6, 0x618C9AD7, 0x0C7A37A1, - 0x148E59F8, 0x3C89EB13, 0x27EECEA9, 0xC935B761, 0xE5EDE11C, 0xB13C7A47, - 0xDF599CD2, 0x733F55F2, 0xCE791814, 0x37BF73C7, 0xCDEA53F7, 0xAA5B5FFD, - 0x6F14DF3D, 0xDB867844, 0xF381CAAF, 0xC43EB968, 0x342C3824, 0x405FC2A3, - 0xC372161D, 0x250CBCE2, 0x498B283C, 0x9541FF0D, 0x017139A8, 0xB3DE080C, - 0xE49CD8B4, 0xC1906456, 0x84617BCB, 0xB670D532, 0x5C74486C, 0x5742D0B8, - 0xF4A75051, 0x4165537E, 0x17A4C31A, 0x275E963A, 0xAB6BCB3B, 0x9D45F11F, - 0xFA58ABAC, 0xE303934B, 0x30FA5520, 0x766DF6AD, 0xCC769188, 0x024C25F5, - 0xE5D7FC4F, 0x2ACBD7C5, 0x35448026, 0x62A38FB5, 0xB15A49DE, 0xBA1B6725, - 0xEA0E9845, 0xFEC0E15D, 0x2F7502C3, 0x4CF01281, 0x4697A38D, 0xD3F9C66B, - 0x8F5FE703, 0x929C9515, 0x6D7AEBBF, 0x5259DA95, 0xBE832DD4, 0x7421D358, - 0xE0692949, 0xC9C8448E, 0xC2896A75, 0x8E7978F4, 0x583E6B99, 0xB971DD27, - 0xE14FB6BE, 0x88AD17F0, 0x20AC66C9, 0xCE3AB47D, 0xDF4A1863, 0x1A3182E5, - 0x51336097, 0x537F4562, 0x6477E0B1, 0x6BAE84BB, 0x81A01CFE, 0x082B94F9, - 0x48685870, 0x45FD198F, 0xDE6C8794, 0x7BF8B752, 0x73D323AB, 0x4B02E272, - 0x1F8F57E3, 0x55AB2A66, 0xEB2807B2, 0xB5C2032F, 0xC57B9A86, 0x3708A5D3, - 0x2887F230, 0xBFA5B223, 0x036ABA02, 0x16825CED, 0xCF1C2B8A, 0x79B492A7, - 0x07F2F0F3, 0x69E2A14E, 0xDAF4CD65, 0x05BED506, 0x34621FD1, 0xA6FE8AC4, - 0x2E539D34, 0xF355A0A2, 0x8AE13205, 0xF6EB75A4, 0x83EC390B, 0x60EFAA40, - 0x719F065E, 0x6E1051BD, 0x218AF93E, 0xDD063D96, 0x3E05AEDD, 0xE6BD464D, - 0x548DB591, 0xC45D0571, 0x06D46F04, 0x5015FF60, 0x98FB2419, 0xBDE997D6, - 0x4043CC89, 0xD99E7767, 0xE842BDB0, 0x898B8807, 0x195B38E7, 0xC8EEDB79, - 0x7C0A47A1, 0x420FE97C, 0x841EC9F8, 0x00000000, 0x80868309, 0x2BED4832, - 0x1170AC1E, 0x5A724E6C, 0x0EFFFBFD, 0x8538560F, 0xAED51E3D, 0x2D392736, - 0x0FD9640A, 0x5CA62168, 0x5B54D19B, 0x362E3A24, 0x0A67B10C, 0x57E70F93, - 0xEE96D2B4, 0x9B919E1B, 0xC0C54F80, 0xDC20A261, 0x774B695A, 0x121A161C, - 0x93BA0AE2, 0xA02AE5C0, 0x22E0433C, 0x1B171D12, 0x090D0B0E, 0x8BC7ADF2, - 0xB6A8B92D, 0x1EA9C814, 0xF1198557, 0x75074CAF, 0x99DDBBEE, 0x7F60FDA3, - 0x01269FF7, 0x72F5BC5C, 0x663BC544, 0xFB7E345B, 0x4329768B, 0x23C6DCCB, - 0xEDFC68B6, 0xE4F163B8, 0x31DCCAD7, 0x63851042, 0x97224013, 0xC6112084, - 0x4A247D85, 0xBB3DF8D2, 0xF93211AE, 0x29A16DC7, 0x9E2F4B1D, 0xB230F3DC, - 0x8652EC0D, 0xC1E3D077, 0xB3166C2B, 0x70B999A9, 0x9448FA11, 0xE9642247, - 0xFC8CC4A8, 0xF03F1AA0, 0x7D2CD856, 0x3390EF22, 0x494EC787, 0x38D1C1D9, - 0xCAA2FE8C, 0xD40B3698, 0xF581CFA6, 0x7ADE28A5, 0xB78E26DA, 0xADBFA43F, - 0x3A9DE42C, 0x78920D50, 0x5FCC9B6A, 0x7E466254, 0x8D13C2F6, 0xD8B8E890, - 0x39F75E2E, 0xC3AFF582, 0x5D80BE9F, 0xD0937C69, 0xD52DA96F, 0x2512B3CF, - 0xAC993BC8, 0x187DA710, 0x9C636EE8, 0x3BBB7BDB, 0x267809CD, 0x5918F46E, - 0x9AB701EC, 0x4F9AA883, 0x956E65E6, 0xFFE67EAA, 0xBCCF0821, 0x15E8E6EF, - 0xE79BD9BA, 0x6F36CE4A, 0x9F09D4EA, 0xB07CD629, 0xA4B2AF31, 0x3F23312A, - 0xA59430C6, 0xA266C035, 0x4EBC3774, 0x82CAA6FC, 0x90D0B0E0, 0xA7D81533, - 0x04984AF1, 0xECDAF741, 0xCD500E7F, 0x91F62F17, 0x4DD68D76, 0xEFB04D43, - 0xAA4D54CC, 0x9604DFE4, 0xD1B5E39E, 0x6A881B4C, 0x2C1FB8C1, 0x65517F46, - 0x5EEA049D, 0x8C355D01, 0x877473FA, 0x0B412EFB, 0x671D5AB3, 0xDBD25292, - 0x105633E9, 0xD647136D, 0xD7618C9A, 0xA10C7A37, 0xF8148E59, 0x133C89EB, - 0xA927EECE, 0x61C935B7, 0x1CE5EDE1, 0x47B13C7A, 0xD2DF599C, 0xF2733F55, - 0x14CE7918, 0xC737BF73, 0xF7CDEA53, 0xFDAA5B5F, 0x3D6F14DF, 0x44DB8678, - 0xAFF381CA, 0x68C43EB9, 0x24342C38, 0xA3405FC2, 0x1DC37216, 0xE2250CBC, - 0x3C498B28, 0x0D9541FF, 0xA8017139, 0x0CB3DE08, 0xB4E49CD8, 0x56C19064, - 0xCB84617B, 0x32B670D5, 0x6C5C7448, 0xB85742D0 }; - -/* -* AES Encryption -*/ -void aes_encrypt_n(const byte in[], byte out[], - size_t blocks, - const MemoryRegion& EK, - const MemoryRegion& ME) - { - const size_t BLOCK_SIZE = 16; - - const u32bit* TE0 = TE; - const u32bit* TE1 = TE + 256; - const u32bit* TE2 = TE + 512; - const u32bit* TE3 = TE + 768; - - for(size_t i = 0; i != blocks; ++i) - { - u32bit T0 = load_be(in, 0) ^ EK[0]; - u32bit T1 = load_be(in, 1) ^ EK[1]; - u32bit T2 = load_be(in, 2) ^ EK[2]; - u32bit T3 = load_be(in, 3) ^ EK[3]; - - /* Use only the first 256 entries of the TE table and do the - * rotations directly in the code. This reduces the number of - * cache lines potentially used in the first round from 64 to 16 - * (assuming a typical 64 byte cache line), which makes timing - * attacks a little harder; the first round is particularly - * vulnerable. - */ - - u32bit B0 = TE[get_byte(0, T0)] ^ - rotate_right(TE[get_byte(1, T1)], 8) ^ - rotate_right(TE[get_byte(2, T2)], 16) ^ - rotate_right(TE[get_byte(3, T3)], 24) ^ EK[4]; - - u32bit B1 = TE[get_byte(0, T1)] ^ - rotate_right(TE[get_byte(1, T2)], 8) ^ - rotate_right(TE[get_byte(2, T3)], 16) ^ - rotate_right(TE[get_byte(3, T0)], 24) ^ EK[5]; - - u32bit B2 = TE[get_byte(0, T2)] ^ - rotate_right(TE[get_byte(1, T3)], 8) ^ - rotate_right(TE[get_byte(2, T0)], 16) ^ - rotate_right(TE[get_byte(3, T1)], 24) ^ EK[6]; - - u32bit B3 = TE[get_byte(0, T3)] ^ - rotate_right(TE[get_byte(1, T0)], 8) ^ - rotate_right(TE[get_byte(2, T1)], 16) ^ - rotate_right(TE[get_byte(3, T2)], 24) ^ EK[7]; - - for(size_t r = 2*4; r < EK.size(); r += 2*4) - { - T0 = TE0[get_byte(0, B0)] ^ TE1[get_byte(1, B1)] ^ - TE2[get_byte(2, B2)] ^ TE3[get_byte(3, B3)] ^ EK[r]; - T1 = TE0[get_byte(0, B1)] ^ TE1[get_byte(1, B2)] ^ - TE2[get_byte(2, B3)] ^ TE3[get_byte(3, B0)] ^ EK[r+1]; - T2 = TE0[get_byte(0, B2)] ^ TE1[get_byte(1, B3)] ^ - TE2[get_byte(2, B0)] ^ TE3[get_byte(3, B1)] ^ EK[r+2]; - T3 = TE0[get_byte(0, B3)] ^ TE1[get_byte(1, B0)] ^ - TE2[get_byte(2, B1)] ^ TE3[get_byte(3, B2)] ^ EK[r+3]; - - B0 = TE0[get_byte(0, T0)] ^ TE1[get_byte(1, T1)] ^ - TE2[get_byte(2, T2)] ^ TE3[get_byte(3, T3)] ^ EK[r+4]; - B1 = TE0[get_byte(0, T1)] ^ TE1[get_byte(1, T2)] ^ - TE2[get_byte(2, T3)] ^ TE3[get_byte(3, T0)] ^ EK[r+5]; - B2 = TE0[get_byte(0, T2)] ^ TE1[get_byte(1, T3)] ^ - TE2[get_byte(2, T0)] ^ TE3[get_byte(3, T1)] ^ EK[r+6]; - B3 = TE0[get_byte(0, T3)] ^ TE1[get_byte(1, T0)] ^ - TE2[get_byte(2, T1)] ^ TE3[get_byte(3, T2)] ^ EK[r+7]; - } - - /* - Joseph Bonneau and Ilya Mironov's paper "Cache-Collision Timing - Attacks Against AES" describes an attack that can recover AES - keys with as few as 2**13 samples. - - http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.88.4753 - - They recommend using a byte-wide table, which still allows an attack - but increases the samples required from 2**13 to 2**25: - - """In addition to OpenSSL v. 0.9.8.(a), which was used in our - experiments, the AES implementations of Crypto++ 5.2.1 and - LibTomCrypt 1.09 use the original Rijndael C implementation with - very few changes and are highly vulnerable. The AES implementations - in libgcrypt v. 1.2.2 and Botan v. 1.4.2 are also vulnerable, but - use a smaller byte-wide final table which lessens the effectiveness - of the attacks.""" - */ - - out[ 0] = SE[get_byte(0, B0)] ^ ME[0]; - out[ 1] = SE[get_byte(1, B1)] ^ ME[1]; - out[ 2] = SE[get_byte(2, B2)] ^ ME[2]; - out[ 3] = SE[get_byte(3, B3)] ^ ME[3]; - out[ 4] = SE[get_byte(0, B1)] ^ ME[4]; - out[ 5] = SE[get_byte(1, B2)] ^ ME[5]; - out[ 6] = SE[get_byte(2, B3)] ^ ME[6]; - out[ 7] = SE[get_byte(3, B0)] ^ ME[7]; - out[ 8] = SE[get_byte(0, B2)] ^ ME[8]; - out[ 9] = SE[get_byte(1, B3)] ^ ME[9]; - out[10] = SE[get_byte(2, B0)] ^ ME[10]; - out[11] = SE[get_byte(3, B1)] ^ ME[11]; - out[12] = SE[get_byte(0, B3)] ^ ME[12]; - out[13] = SE[get_byte(1, B0)] ^ ME[13]; - out[14] = SE[get_byte(2, B1)] ^ ME[14]; - out[15] = SE[get_byte(3, B2)] ^ ME[15]; - - in += BLOCK_SIZE; - out += BLOCK_SIZE; - } - } - -/* -* AES Decryption -*/ -void aes_decrypt_n(const byte in[], byte out[], size_t blocks, - const MemoryRegion& DK, - const MemoryRegion& MD) - { - const size_t BLOCK_SIZE = 16; - - const u32bit* TD0 = TD; - const u32bit* TD1 = TD + 256; - const u32bit* TD2 = TD + 512; - const u32bit* TD3 = TD + 768; - - for(size_t i = 0; i != blocks; ++i) - { - u32bit T0 = load_be(in, 0) ^ DK[0]; - u32bit T1 = load_be(in, 1) ^ DK[1]; - u32bit T2 = load_be(in, 2) ^ DK[2]; - u32bit T3 = load_be(in, 3) ^ DK[3]; - - u32bit B0 = TD[get_byte(0, T0)] ^ - rotate_right(TD[get_byte(1, T3)], 8) ^ - rotate_right(TD[get_byte(2, T2)], 16) ^ - rotate_right(TD[get_byte(3, T1)], 24) ^ DK[4]; - - u32bit B1 = TD[get_byte(0, T1)] ^ - rotate_right(TD[get_byte(1, T0)], 8) ^ - rotate_right(TD[get_byte(2, T3)], 16) ^ - rotate_right(TD[get_byte(3, T2)], 24) ^ DK[5]; - - u32bit B2 = TD[get_byte(0, T2)] ^ - rotate_right(TD[get_byte(1, T1)], 8) ^ - rotate_right(TD[get_byte(2, T0)], 16) ^ - rotate_right(TD[get_byte(3, T3)], 24) ^ DK[6]; - - u32bit B3 = TD[get_byte(0, T3)] ^ - rotate_right(TD[get_byte(1, T2)], 8) ^ - rotate_right(TD[get_byte(2, T1)], 16) ^ - rotate_right(TD[get_byte(3, T0)], 24) ^ DK[7]; - - for(size_t r = 2*4; r < DK.size(); r += 2*4) - { - T0 = TD0[get_byte(0, B0)] ^ TD1[get_byte(1, B3)] ^ - TD2[get_byte(2, B2)] ^ TD3[get_byte(3, B1)] ^ DK[r]; - T1 = TD0[get_byte(0, B1)] ^ TD1[get_byte(1, B0)] ^ - TD2[get_byte(2, B3)] ^ TD3[get_byte(3, B2)] ^ DK[r+1]; - T2 = TD0[get_byte(0, B2)] ^ TD1[get_byte(1, B1)] ^ - TD2[get_byte(2, B0)] ^ TD3[get_byte(3, B3)] ^ DK[r+2]; - T3 = TD0[get_byte(0, B3)] ^ TD1[get_byte(1, B2)] ^ - TD2[get_byte(2, B1)] ^ TD3[get_byte(3, B0)] ^ DK[r+3]; - - B0 = TD0[get_byte(0, T0)] ^ TD1[get_byte(1, T3)] ^ - TD2[get_byte(2, T2)] ^ TD3[get_byte(3, T1)] ^ DK[r+4]; - B1 = TD0[get_byte(0, T1)] ^ TD1[get_byte(1, T0)] ^ - TD2[get_byte(2, T3)] ^ TD3[get_byte(3, T2)] ^ DK[r+5]; - B2 = TD0[get_byte(0, T2)] ^ TD1[get_byte(1, T1)] ^ - TD2[get_byte(2, T0)] ^ TD3[get_byte(3, T3)] ^ DK[r+6]; - B3 = TD0[get_byte(0, T3)] ^ TD1[get_byte(1, T2)] ^ - TD2[get_byte(2, T1)] ^ TD3[get_byte(3, T0)] ^ DK[r+7]; - } - - out[ 0] = SD[get_byte(0, B0)] ^ MD[0]; - out[ 1] = SD[get_byte(1, B3)] ^ MD[1]; - out[ 2] = SD[get_byte(2, B2)] ^ MD[2]; - out[ 3] = SD[get_byte(3, B1)] ^ MD[3]; - out[ 4] = SD[get_byte(0, B1)] ^ MD[4]; - out[ 5] = SD[get_byte(1, B0)] ^ MD[5]; - out[ 6] = SD[get_byte(2, B3)] ^ MD[6]; - out[ 7] = SD[get_byte(3, B2)] ^ MD[7]; - out[ 8] = SD[get_byte(0, B2)] ^ MD[8]; - out[ 9] = SD[get_byte(1, B1)] ^ MD[9]; - out[10] = SD[get_byte(2, B0)] ^ MD[10]; - out[11] = SD[get_byte(3, B3)] ^ MD[11]; - out[12] = SD[get_byte(0, B3)] ^ MD[12]; - out[13] = SD[get_byte(1, B2)] ^ MD[13]; - out[14] = SD[get_byte(2, B1)] ^ MD[14]; - out[15] = SD[get_byte(3, B0)] ^ MD[15]; - - in += BLOCK_SIZE; - out += BLOCK_SIZE; - } - } - -void aes_key_schedule(const byte key[], size_t length, - MemoryRegion& EK, - MemoryRegion& DK, - MemoryRegion& ME, - MemoryRegion& MD) - { - static const u32bit RC[10] = { - 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, - 0x20000000, 0x40000000, 0x80000000, 0x1B000000, 0x36000000 }; - - const size_t rounds = (length / 4) + 6; - - SecureVector XEK(length + 32), XDK(length + 32); - - const size_t X = length / 4; - for(size_t i = 0; i != X; ++i) - XEK[i] = load_be(key, i); - - for(size_t i = X; i < 4*(rounds+1); i += X) - { - XEK[i] = XEK[i-X] ^ RC[(i-X)/X] ^ - make_u32bit(SE[get_byte(1, XEK[i-1])], - SE[get_byte(2, XEK[i-1])], - SE[get_byte(3, XEK[i-1])], - SE[get_byte(0, XEK[i-1])]); - - for(size_t j = 1; j != X; ++j) - { - XEK[i+j] = XEK[i+j-X]; - - if(X == 8 && j == 4) - XEK[i+j] ^= make_u32bit(SE[get_byte(0, XEK[i+j-1])], - SE[get_byte(1, XEK[i+j-1])], - SE[get_byte(2, XEK[i+j-1])], - SE[get_byte(3, XEK[i+j-1])]); - else - XEK[i+j] ^= XEK[i+j-1]; - } - } - - for(size_t i = 0; i != 4*(rounds+1); i += 4) - { - XDK[i ] = XEK[4*rounds-i ]; - XDK[i+1] = XEK[4*rounds-i+1]; - XDK[i+2] = XEK[4*rounds-i+2]; - XDK[i+3] = XEK[4*rounds-i+3]; - } - - for(size_t i = 4; i != length + 24; ++i) - XDK[i] = TD[SE[get_byte(0, XDK[i])] + 0] ^ - TD[SE[get_byte(1, XDK[i])] + 256] ^ - TD[SE[get_byte(2, XDK[i])] + 512] ^ - TD[SE[get_byte(3, XDK[i])] + 768]; - - for(size_t i = 0; i != 4; ++i) - { - store_be(XEK[i+4*rounds], &ME[4*i]); - store_be(XEK[i], &MD[4*i]); - } - - EK.resize(length + 24); - DK.resize(length + 24); - copy_mem(&EK[0], &XEK[0], EK.size()); - copy_mem(&DK[0], &XDK[0], DK.size()); - } - -} - -void AES_128::encrypt_n(const byte in[], byte out[], size_t blocks) const - { - aes_encrypt_n(in, out, blocks, EK, ME); - } - -void AES_128::decrypt_n(const byte in[], byte out[], size_t blocks) const - { - aes_decrypt_n(in, out, blocks, DK, MD); - } - -void AES_128::key_schedule(const byte key[], size_t length) - { - aes_key_schedule(key, length, EK, DK, ME, MD); - } - -void AES_128::clear() - { - zeroise(EK); - zeroise(DK); - zeroise(ME); - zeroise(MD); - } - -void AES_192::encrypt_n(const byte in[], byte out[], size_t blocks) const - { - aes_encrypt_n(in, out, blocks, EK, ME); - } - -void AES_192::decrypt_n(const byte in[], byte out[], size_t blocks) const - { - aes_decrypt_n(in, out, blocks, DK, MD); - } - -void AES_192::key_schedule(const byte key[], size_t length) - { - aes_key_schedule(key, length, EK, DK, ME, MD); - } - -void AES_192::clear() - { - zeroise(EK); - zeroise(DK); - zeroise(ME); - zeroise(MD); - } - -void AES_256::encrypt_n(const byte in[], byte out[], size_t blocks) const - { - aes_encrypt_n(in, out, blocks, EK, ME); - } - -void AES_256::decrypt_n(const byte in[], byte out[], size_t blocks) const - { - aes_decrypt_n(in, out, blocks, DK, MD); - } - -void AES_256::key_schedule(const byte key[], size_t length) - { - aes_key_schedule(key, length, EK, DK, ME, MD); - } - -void AES_256::clear() - { - zeroise(EK); - zeroise(DK); - zeroise(ME); - zeroise(MD); - } - -} -/* -* S-Box and P-Box Tables for Blowfish -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -const u32bit Blowfish::P_INIT[18] = { - 0x243F6A88, 0x85A308D3, 0x13198A2E, 0x03707344, 0xA4093822, 0x299F31D0, - 0x082EFA98, 0xEC4E6C89, 0x452821E6, 0x38D01377, 0xBE5466CF, 0x34E90C6C, - 0xC0AC29B7, 0xC97C50DD, 0x3F84D5B5, 0xB5470917, 0x9216D5D9, 0x8979FB1B }; - -const u32bit Blowfish::S_INIT[1024] = { - 0xD1310BA6, 0x98DFB5AC, 0x2FFD72DB, 0xD01ADFB7, 0xB8E1AFED, 0x6A267E96, - 0xBA7C9045, 0xF12C7F99, 0x24A19947, 0xB3916CF7, 0x0801F2E2, 0x858EFC16, - 0x636920D8, 0x71574E69, 0xA458FEA3, 0xF4933D7E, 0x0D95748F, 0x728EB658, - 0x718BCD58, 0x82154AEE, 0x7B54A41D, 0xC25A59B5, 0x9C30D539, 0x2AF26013, - 0xC5D1B023, 0x286085F0, 0xCA417918, 0xB8DB38EF, 0x8E79DCB0, 0x603A180E, - 0x6C9E0E8B, 0xB01E8A3E, 0xD71577C1, 0xBD314B27, 0x78AF2FDA, 0x55605C60, - 0xE65525F3, 0xAA55AB94, 0x57489862, 0x63E81440, 0x55CA396A, 0x2AAB10B6, - 0xB4CC5C34, 0x1141E8CE, 0xA15486AF, 0x7C72E993, 0xB3EE1411, 0x636FBC2A, - 0x2BA9C55D, 0x741831F6, 0xCE5C3E16, 0x9B87931E, 0xAFD6BA33, 0x6C24CF5C, - 0x7A325381, 0x28958677, 0x3B8F4898, 0x6B4BB9AF, 0xC4BFE81B, 0x66282193, - 0x61D809CC, 0xFB21A991, 0x487CAC60, 0x5DEC8032, 0xEF845D5D, 0xE98575B1, - 0xDC262302, 0xEB651B88, 0x23893E81, 0xD396ACC5, 0x0F6D6FF3, 0x83F44239, - 0x2E0B4482, 0xA4842004, 0x69C8F04A, 0x9E1F9B5E, 0x21C66842, 0xF6E96C9A, - 0x670C9C61, 0xABD388F0, 0x6A51A0D2, 0xD8542F68, 0x960FA728, 0xAB5133A3, - 0x6EEF0B6C, 0x137A3BE4, 0xBA3BF050, 0x7EFB2A98, 0xA1F1651D, 0x39AF0176, - 0x66CA593E, 0x82430E88, 0x8CEE8619, 0x456F9FB4, 0x7D84A5C3, 0x3B8B5EBE, - 0xE06F75D8, 0x85C12073, 0x401A449F, 0x56C16AA6, 0x4ED3AA62, 0x363F7706, - 0x1BFEDF72, 0x429B023D, 0x37D0D724, 0xD00A1248, 0xDB0FEAD3, 0x49F1C09B, - 0x075372C9, 0x80991B7B, 0x25D479D8, 0xF6E8DEF7, 0xE3FE501A, 0xB6794C3B, - 0x976CE0BD, 0x04C006BA, 0xC1A94FB6, 0x409F60C4, 0x5E5C9EC2, 0x196A2463, - 0x68FB6FAF, 0x3E6C53B5, 0x1339B2EB, 0x3B52EC6F, 0x6DFC511F, 0x9B30952C, - 0xCC814544, 0xAF5EBD09, 0xBEE3D004, 0xDE334AFD, 0x660F2807, 0x192E4BB3, - 0xC0CBA857, 0x45C8740F, 0xD20B5F39, 0xB9D3FBDB, 0x5579C0BD, 0x1A60320A, - 0xD6A100C6, 0x402C7279, 0x679F25FE, 0xFB1FA3CC, 0x8EA5E9F8, 0xDB3222F8, - 0x3C7516DF, 0xFD616B15, 0x2F501EC8, 0xAD0552AB, 0x323DB5FA, 0xFD238760, - 0x53317B48, 0x3E00DF82, 0x9E5C57BB, 0xCA6F8CA0, 0x1A87562E, 0xDF1769DB, - 0xD542A8F6, 0x287EFFC3, 0xAC6732C6, 0x8C4F5573, 0x695B27B0, 0xBBCA58C8, - 0xE1FFA35D, 0xB8F011A0, 0x10FA3D98, 0xFD2183B8, 0x4AFCB56C, 0x2DD1D35B, - 0x9A53E479, 0xB6F84565, 0xD28E49BC, 0x4BFB9790, 0xE1DDF2DA, 0xA4CB7E33, - 0x62FB1341, 0xCEE4C6E8, 0xEF20CADA, 0x36774C01, 0xD07E9EFE, 0x2BF11FB4, - 0x95DBDA4D, 0xAE909198, 0xEAAD8E71, 0x6B93D5A0, 0xD08ED1D0, 0xAFC725E0, - 0x8E3C5B2F, 0x8E7594B7, 0x8FF6E2FB, 0xF2122B64, 0x8888B812, 0x900DF01C, - 0x4FAD5EA0, 0x688FC31C, 0xD1CFF191, 0xB3A8C1AD, 0x2F2F2218, 0xBE0E1777, - 0xEA752DFE, 0x8B021FA1, 0xE5A0CC0F, 0xB56F74E8, 0x18ACF3D6, 0xCE89E299, - 0xB4A84FE0, 0xFD13E0B7, 0x7CC43B81, 0xD2ADA8D9, 0x165FA266, 0x80957705, - 0x93CC7314, 0x211A1477, 0xE6AD2065, 0x77B5FA86, 0xC75442F5, 0xFB9D35CF, - 0xEBCDAF0C, 0x7B3E89A0, 0xD6411BD3, 0xAE1E7E49, 0x00250E2D, 0x2071B35E, - 0x226800BB, 0x57B8E0AF, 0x2464369B, 0xF009B91E, 0x5563911D, 0x59DFA6AA, - 0x78C14389, 0xD95A537F, 0x207D5BA2, 0x02E5B9C5, 0x83260376, 0x6295CFA9, - 0x11C81968, 0x4E734A41, 0xB3472DCA, 0x7B14A94A, 0x1B510052, 0x9A532915, - 0xD60F573F, 0xBC9BC6E4, 0x2B60A476, 0x81E67400, 0x08BA6FB5, 0x571BE91F, - 0xF296EC6B, 0x2A0DD915, 0xB6636521, 0xE7B9F9B6, 0xFF34052E, 0xC5855664, - 0x53B02D5D, 0xA99F8FA1, 0x08BA4799, 0x6E85076A, 0x4B7A70E9, 0xB5B32944, - 0xDB75092E, 0xC4192623, 0xAD6EA6B0, 0x49A7DF7D, 0x9CEE60B8, 0x8FEDB266, - 0xECAA8C71, 0x699A17FF, 0x5664526C, 0xC2B19EE1, 0x193602A5, 0x75094C29, - 0xA0591340, 0xE4183A3E, 0x3F54989A, 0x5B429D65, 0x6B8FE4D6, 0x99F73FD6, - 0xA1D29C07, 0xEFE830F5, 0x4D2D38E6, 0xF0255DC1, 0x4CDD2086, 0x8470EB26, - 0x6382E9C6, 0x021ECC5E, 0x09686B3F, 0x3EBAEFC9, 0x3C971814, 0x6B6A70A1, - 0x687F3584, 0x52A0E286, 0xB79C5305, 0xAA500737, 0x3E07841C, 0x7FDEAE5C, - 0x8E7D44EC, 0x5716F2B8, 0xB03ADA37, 0xF0500C0D, 0xF01C1F04, 0x0200B3FF, - 0xAE0CF51A, 0x3CB574B2, 0x25837A58, 0xDC0921BD, 0xD19113F9, 0x7CA92FF6, - 0x94324773, 0x22F54701, 0x3AE5E581, 0x37C2DADC, 0xC8B57634, 0x9AF3DDA7, - 0xA9446146, 0x0FD0030E, 0xECC8C73E, 0xA4751E41, 0xE238CD99, 0x3BEA0E2F, - 0x3280BBA1, 0x183EB331, 0x4E548B38, 0x4F6DB908, 0x6F420D03, 0xF60A04BF, - 0x2CB81290, 0x24977C79, 0x5679B072, 0xBCAF89AF, 0xDE9A771F, 0xD9930810, - 0xB38BAE12, 0xDCCF3F2E, 0x5512721F, 0x2E6B7124, 0x501ADDE6, 0x9F84CD87, - 0x7A584718, 0x7408DA17, 0xBC9F9ABC, 0xE94B7D8C, 0xEC7AEC3A, 0xDB851DFA, - 0x63094366, 0xC464C3D2, 0xEF1C1847, 0x3215D908, 0xDD433B37, 0x24C2BA16, - 0x12A14D43, 0x2A65C451, 0x50940002, 0x133AE4DD, 0x71DFF89E, 0x10314E55, - 0x81AC77D6, 0x5F11199B, 0x043556F1, 0xD7A3C76B, 0x3C11183B, 0x5924A509, - 0xF28FE6ED, 0x97F1FBFA, 0x9EBABF2C, 0x1E153C6E, 0x86E34570, 0xEAE96FB1, - 0x860E5E0A, 0x5A3E2AB3, 0x771FE71C, 0x4E3D06FA, 0x2965DCB9, 0x99E71D0F, - 0x803E89D6, 0x5266C825, 0x2E4CC978, 0x9C10B36A, 0xC6150EBA, 0x94E2EA78, - 0xA5FC3C53, 0x1E0A2DF4, 0xF2F74EA7, 0x361D2B3D, 0x1939260F, 0x19C27960, - 0x5223A708, 0xF71312B6, 0xEBADFE6E, 0xEAC31F66, 0xE3BC4595, 0xA67BC883, - 0xB17F37D1, 0x018CFF28, 0xC332DDEF, 0xBE6C5AA5, 0x65582185, 0x68AB9802, - 0xEECEA50F, 0xDB2F953B, 0x2AEF7DAD, 0x5B6E2F84, 0x1521B628, 0x29076170, - 0xECDD4775, 0x619F1510, 0x13CCA830, 0xEB61BD96, 0x0334FE1E, 0xAA0363CF, - 0xB5735C90, 0x4C70A239, 0xD59E9E0B, 0xCBAADE14, 0xEECC86BC, 0x60622CA7, - 0x9CAB5CAB, 0xB2F3846E, 0x648B1EAF, 0x19BDF0CA, 0xA02369B9, 0x655ABB50, - 0x40685A32, 0x3C2AB4B3, 0x319EE9D5, 0xC021B8F7, 0x9B540B19, 0x875FA099, - 0x95F7997E, 0x623D7DA8, 0xF837889A, 0x97E32D77, 0x11ED935F, 0x16681281, - 0x0E358829, 0xC7E61FD6, 0x96DEDFA1, 0x7858BA99, 0x57F584A5, 0x1B227263, - 0x9B83C3FF, 0x1AC24696, 0xCDB30AEB, 0x532E3054, 0x8FD948E4, 0x6DBC3128, - 0x58EBF2EF, 0x34C6FFEA, 0xFE28ED61, 0xEE7C3C73, 0x5D4A14D9, 0xE864B7E3, - 0x42105D14, 0x203E13E0, 0x45EEE2B6, 0xA3AAABEA, 0xDB6C4F15, 0xFACB4FD0, - 0xC742F442, 0xEF6ABBB5, 0x654F3B1D, 0x41CD2105, 0xD81E799E, 0x86854DC7, - 0xE44B476A, 0x3D816250, 0xCF62A1F2, 0x5B8D2646, 0xFC8883A0, 0xC1C7B6A3, - 0x7F1524C3, 0x69CB7492, 0x47848A0B, 0x5692B285, 0x095BBF00, 0xAD19489D, - 0x1462B174, 0x23820E00, 0x58428D2A, 0x0C55F5EA, 0x1DADF43E, 0x233F7061, - 0x3372F092, 0x8D937E41, 0xD65FECF1, 0x6C223BDB, 0x7CDE3759, 0xCBEE7460, - 0x4085F2A7, 0xCE77326E, 0xA6078084, 0x19F8509E, 0xE8EFD855, 0x61D99735, - 0xA969A7AA, 0xC50C06C2, 0x5A04ABFC, 0x800BCADC, 0x9E447A2E, 0xC3453484, - 0xFDD56705, 0x0E1E9EC9, 0xDB73DBD3, 0x105588CD, 0x675FDA79, 0xE3674340, - 0xC5C43465, 0x713E38D8, 0x3D28F89E, 0xF16DFF20, 0x153E21E7, 0x8FB03D4A, - 0xE6E39F2B, 0xDB83ADF7, 0xE93D5A68, 0x948140F7, 0xF64C261C, 0x94692934, - 0x411520F7, 0x7602D4F7, 0xBCF46B2E, 0xD4A20068, 0xD4082471, 0x3320F46A, - 0x43B7D4B7, 0x500061AF, 0x1E39F62E, 0x97244546, 0x14214F74, 0xBF8B8840, - 0x4D95FC1D, 0x96B591AF, 0x70F4DDD3, 0x66A02F45, 0xBFBC09EC, 0x03BD9785, - 0x7FAC6DD0, 0x31CB8504, 0x96EB27B3, 0x55FD3941, 0xDA2547E6, 0xABCA0A9A, - 0x28507825, 0x530429F4, 0x0A2C86DA, 0xE9B66DFB, 0x68DC1462, 0xD7486900, - 0x680EC0A4, 0x27A18DEE, 0x4F3FFEA2, 0xE887AD8C, 0xB58CE006, 0x7AF4D6B6, - 0xAACE1E7C, 0xD3375FEC, 0xCE78A399, 0x406B2A42, 0x20FE9E35, 0xD9F385B9, - 0xEE39D7AB, 0x3B124E8B, 0x1DC9FAF7, 0x4B6D1856, 0x26A36631, 0xEAE397B2, - 0x3A6EFA74, 0xDD5B4332, 0x6841E7F7, 0xCA7820FB, 0xFB0AF54E, 0xD8FEB397, - 0x454056AC, 0xBA489527, 0x55533A3A, 0x20838D87, 0xFE6BA9B7, 0xD096954B, - 0x55A867BC, 0xA1159A58, 0xCCA92963, 0x99E1DB33, 0xA62A4A56, 0x3F3125F9, - 0x5EF47E1C, 0x9029317C, 0xFDF8E802, 0x04272F70, 0x80BB155C, 0x05282CE3, - 0x95C11548, 0xE4C66D22, 0x48C1133F, 0xC70F86DC, 0x07F9C9EE, 0x41041F0F, - 0x404779A4, 0x5D886E17, 0x325F51EB, 0xD59BC0D1, 0xF2BCC18F, 0x41113564, - 0x257B7834, 0x602A9C60, 0xDFF8E8A3, 0x1F636C1B, 0x0E12B4C2, 0x02E1329E, - 0xAF664FD1, 0xCAD18115, 0x6B2395E0, 0x333E92E1, 0x3B240B62, 0xEEBEB922, - 0x85B2A20E, 0xE6BA0D99, 0xDE720C8C, 0x2DA2F728, 0xD0127845, 0x95B794FD, - 0x647D0862, 0xE7CCF5F0, 0x5449A36F, 0x877D48FA, 0xC39DFD27, 0xF33E8D1E, - 0x0A476341, 0x992EFF74, 0x3A6F6EAB, 0xF4F8FD37, 0xA812DC60, 0xA1EBDDF8, - 0x991BE14C, 0xDB6E6B0D, 0xC67B5510, 0x6D672C37, 0x2765D43B, 0xDCD0E804, - 0xF1290DC7, 0xCC00FFA3, 0xB5390F92, 0x690FED0B, 0x667B9FFB, 0xCEDB7D9C, - 0xA091CF0B, 0xD9155EA3, 0xBB132F88, 0x515BAD24, 0x7B9479BF, 0x763BD6EB, - 0x37392EB3, 0xCC115979, 0x8026E297, 0xF42E312D, 0x6842ADA7, 0xC66A2B3B, - 0x12754CCC, 0x782EF11C, 0x6A124237, 0xB79251E7, 0x06A1BBE6, 0x4BFB6350, - 0x1A6B1018, 0x11CAEDFA, 0x3D25BDD8, 0xE2E1C3C9, 0x44421659, 0x0A121386, - 0xD90CEC6E, 0xD5ABEA2A, 0x64AF674E, 0xDA86A85F, 0xBEBFE988, 0x64E4C3FE, - 0x9DBC8057, 0xF0F7C086, 0x60787BF8, 0x6003604D, 0xD1FD8346, 0xF6381FB0, - 0x7745AE04, 0xD736FCCC, 0x83426B33, 0xF01EAB71, 0xB0804187, 0x3C005E5F, - 0x77A057BE, 0xBDE8AE24, 0x55464299, 0xBF582E61, 0x4E58F48F, 0xF2DDFDA2, - 0xF474EF38, 0x8789BDC2, 0x5366F9C3, 0xC8B38E74, 0xB475F255, 0x46FCD9B9, - 0x7AEB2661, 0x8B1DDF84, 0x846A0E79, 0x915F95E2, 0x466E598E, 0x20B45770, - 0x8CD55591, 0xC902DE4C, 0xB90BACE1, 0xBB8205D0, 0x11A86248, 0x7574A99E, - 0xB77F19B6, 0xE0A9DC09, 0x662D09A1, 0xC4324633, 0xE85A1F02, 0x09F0BE8C, - 0x4A99A025, 0x1D6EFE10, 0x1AB93D1D, 0x0BA5A4DF, 0xA186F20F, 0x2868F169, - 0xDCB7DA83, 0x573906FE, 0xA1E2CE9B, 0x4FCD7F52, 0x50115E01, 0xA70683FA, - 0xA002B5C4, 0x0DE6D027, 0x9AF88C27, 0x773F8641, 0xC3604C06, 0x61A806B5, - 0xF0177A28, 0xC0F586E0, 0x006058AA, 0x30DC7D62, 0x11E69ED7, 0x2338EA63, - 0x53C2DD94, 0xC2C21634, 0xBBCBEE56, 0x90BCB6DE, 0xEBFC7DA1, 0xCE591D76, - 0x6F05E409, 0x4B7C0188, 0x39720A3D, 0x7C927C24, 0x86E3725F, 0x724D9DB9, - 0x1AC15BB4, 0xD39EB8FC, 0xED545578, 0x08FCA5B5, 0xD83D7CD3, 0x4DAD0FC4, - 0x1E50EF5E, 0xB161E6F8, 0xA28514D9, 0x6C51133C, 0x6FD5C7E7, 0x56E14EC4, - 0x362ABFCE, 0xDDC6C837, 0xD79A3234, 0x92638212, 0x670EFA8E, 0x406000E0, - 0x3A39CE37, 0xD3FAF5CF, 0xABC27737, 0x5AC52D1B, 0x5CB0679E, 0x4FA33742, - 0xD3822740, 0x99BC9BBE, 0xD5118E9D, 0xBF0F7315, 0xD62D1C7E, 0xC700C47B, - 0xB78C1B6B, 0x21A19045, 0xB26EB1BE, 0x6A366EB4, 0x5748AB2F, 0xBC946E79, - 0xC6A376D2, 0x6549C2C8, 0x530FF8EE, 0x468DDE7D, 0xD5730A1D, 0x4CD04DC6, - 0x2939BBDB, 0xA9BA4650, 0xAC9526E8, 0xBE5EE304, 0xA1FAD5F0, 0x6A2D519A, - 0x63EF8CE2, 0x9A86EE22, 0xC089C2B8, 0x43242EF6, 0xA51E03AA, 0x9CF2D0A4, - 0x83C061BA, 0x9BE96A4D, 0x8FE51550, 0xBA645BD6, 0x2826A2F9, 0xA73A3AE1, - 0x4BA99586, 0xEF5562E9, 0xC72FEFD3, 0xF752F7DA, 0x3F046F69, 0x77FA0A59, - 0x80E4A915, 0x87B08601, 0x9B09E6AD, 0x3B3EE593, 0xE990FD5A, 0x9E34D797, - 0x2CF0B7D9, 0x022B8B51, 0x96D5AC3A, 0x017DA67D, 0xD1CF3ED6, 0x7C7D2D28, - 0x1F9F25CF, 0xADF2B89B, 0x5AD6B472, 0x5A88F54C, 0xE029AC71, 0xE019A5E6, - 0x47B0ACFD, 0xED93FA9B, 0xE8D3C48D, 0x283B57CC, 0xF8D56629, 0x79132E28, - 0x785F0191, 0xED756055, 0xF7960E44, 0xE3D35E8C, 0x15056DD4, 0x88F46DBA, - 0x03A16125, 0x0564F0BD, 0xC3EB9E15, 0x3C9057A2, 0x97271AEC, 0xA93A072A, - 0x1B3F6D9B, 0x1E6321F5, 0xF59C66FB, 0x26DCF319, 0x7533D928, 0xB155FDF5, - 0x03563482, 0x8ABA3CBB, 0x28517711, 0xC20AD9F8, 0xABCC5167, 0xCCAD925F, - 0x4DE81751, 0x3830DC8E, 0x379D5862, 0x9320F991, 0xEA7A90C2, 0xFB3E7BCE, - 0x5121CE64, 0x774FBE32, 0xA8B6E37E, 0xC3293D46, 0x48DE5369, 0x6413E680, - 0xA2AE0810, 0xDD6DB224, 0x69852DFD, 0x09072166, 0xB39A460A, 0x6445C0DD, - 0x586CDECF, 0x1C20C8AE, 0x5BBEF7DD, 0x1B588D40, 0xCCD2017F, 0x6BB4E3BB, - 0xDDA26A7E, 0x3A59FF45, 0x3E350A44, 0xBCB4CDD5, 0x72EACEA8, 0xFA6484BB, - 0x8D6612AE, 0xBF3C6F47, 0xD29BE463, 0x542F5D9E, 0xAEC2771B, 0xF64E6370, - 0x740E0D8D, 0xE75B1357, 0xF8721671, 0xAF537D5D, 0x4040CB08, 0x4EB4E2CC, - 0x34D2466A, 0x0115AF84, 0xE1B00428, 0x95983A1D, 0x06B89FB4, 0xCE6EA048, - 0x6F3F3B82, 0x3520AB82, 0x011A1D4B, 0x277227F8, 0x611560B1, 0xE7933FDC, - 0xBB3A792B, 0x344525BD, 0xA08839E1, 0x51CE794B, 0x2F32C9B7, 0xA01FBAC9, - 0xE01CC87E, 0xBCC7D1F6, 0xCF0111C3, 0xA1E8AAC7, 0x1A908749, 0xD44FBD9A, - 0xD0DADECB, 0xD50ADA38, 0x0339C32A, 0xC6913667, 0x8DF9317C, 0xE0B12B4F, - 0xF79E59B7, 0x43F5BB3A, 0xF2D519FF, 0x27D9459C, 0xBF97222C, 0x15E6FC2A, - 0x0F91FC71, 0x9B941525, 0xFAE59361, 0xCEB69CEB, 0xC2A86459, 0x12BAA8D1, - 0xB6C1075E, 0xE3056A0C, 0x10D25065, 0xCB03A442, 0xE0EC6E0E, 0x1698DB3B, - 0x4C98A0BE, 0x3278E964, 0x9F1F9532, 0xE0D392DF, 0xD3A0342B, 0x8971F21E, - 0x1B0A7441, 0x4BA3348C, 0xC5BE7120, 0xC37632D8, 0xDF359F8D, 0x9B992F2E, - 0xE60B6F47, 0x0FE3F11D, 0xE54CDA54, 0x1EDAD891, 0xCE6279CF, 0xCD3E7E6F, - 0x1618B166, 0xFD2C1D05, 0x848FD2C5, 0xF6FB2299, 0xF523F357, 0xA6327623, - 0x93A83531, 0x56CCCD02, 0xACF08162, 0x5A75EBB5, 0x6E163697, 0x88D273CC, - 0xDE966292, 0x81B949D0, 0x4C50901B, 0x71C65614, 0xE6C6C7BD, 0x327A140A, - 0x45E1D006, 0xC3F27B9A, 0xC9AA53FD, 0x62A80F00, 0xBB25BFE2, 0x35BDD2F6, - 0x71126905, 0xB2040222, 0xB6CBCF7C, 0xCD769C2B, 0x53113EC0, 0x1640E3D3, - 0x38ABBD60, 0x2547ADF0, 0xBA38209C, 0xF746CE76, 0x77AFA1C5, 0x20756060, - 0x85CBFE4E, 0x8AE88DD8, 0x7AAAF9B0, 0x4CF9AA7E, 0x1948C25C, 0x02FB8A8C, - 0x01C36AE4, 0xD6EBE1F9, 0x90D4F869, 0xA65CDEA0, 0x3F09252D, 0xC208E69F, - 0xB74E6132, 0xCE77E25B, 0x578FDFE3, 0x3AC372E6 }; - -} -/* -* Blowfish -* (C) 1999-2011 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -/* -* Blowfish Encryption -*/ -void Blowfish::encrypt_n(const byte in[], byte out[], size_t blocks) const - { - const u32bit* S1 = &S[0]; - const u32bit* S2 = &S[256]; - const u32bit* S3 = &S[512]; - const u32bit* S4 = &S[768]; - - for(size_t i = 0; i != blocks; ++i) - { - u32bit L = load_be(in, 0); - u32bit R = load_be(in, 1); - - for(size_t j = 0; j != 16; j += 2) - { - L ^= P[j]; - R ^= ((S1[get_byte(0, L)] + S2[get_byte(1, L)]) ^ - S3[get_byte(2, L)]) + S4[get_byte(3, L)]; - - R ^= P[j+1]; - L ^= ((S1[get_byte(0, R)] + S2[get_byte(1, R)]) ^ - S3[get_byte(2, R)]) + S4[get_byte(3, R)]; - } - - L ^= P[16]; R ^= P[17]; - - store_be(out, R, L); - - in += BLOCK_SIZE; - out += BLOCK_SIZE; - } - } - -/* -* Blowfish Decryption -*/ -void Blowfish::decrypt_n(const byte in[], byte out[], size_t blocks) const - { - const u32bit* S1 = &S[0]; - const u32bit* S2 = &S[256]; - const u32bit* S3 = &S[512]; - const u32bit* S4 = &S[768]; - - for(size_t i = 0; i != blocks; ++i) - { - u32bit L = load_be(in, 0); - u32bit R = load_be(in, 1); - - for(size_t j = 17; j != 1; j -= 2) - { - L ^= P[j]; - R ^= ((S1[get_byte(0, L)] + S2[get_byte(1, L)]) ^ - S3[get_byte(2, L)]) + S4[get_byte(3, L)]; - - R ^= P[j-1]; - L ^= ((S1[get_byte(0, R)] + S2[get_byte(1, R)]) ^ - S3[get_byte(2, R)]) + S4[get_byte(3, R)]; - } - - L ^= P[1]; R ^= P[0]; - - store_be(out, R, L); - - in += BLOCK_SIZE; - out += BLOCK_SIZE; - } - } - -/* -* Blowfish Key Schedule -*/ -void Blowfish::key_schedule(const byte key[], size_t length) - { - clear(); - - const byte null_salt[16] = { 0 }; - - key_expansion(key, length, null_salt); - } - -void Blowfish::key_expansion(const byte key[], - size_t length, - const byte salt[16]) - { - for(size_t i = 0, j = 0; i != 18; ++i, j += 4) - P[i] ^= make_u32bit(key[(j ) % length], key[(j+1) % length], - key[(j+2) % length], key[(j+3) % length]); - - u32bit L = 0, R = 0; - generate_sbox(P, L, R, salt, 0); - generate_sbox(S, L, R, salt, 2); - } - -/* -* Modified key schedule used for bcrypt password hashing -*/ -void Blowfish::eks_key_schedule(const byte key[], size_t length, - const byte salt[16], size_t workfactor) - { - if(length == 0 || length >= 56) - throw Invalid_Key_Length("EKSBlowfish", length); - - if(workfactor == 0) - throw std::invalid_argument("Bcrypt work factor must be at least 1"); - - /* - * On a 2.8 GHz Core-i7, workfactor == 18 takes about 25 seconds to - * hash a password. This seems like a reasonable upper bound for the - * time being. - */ - if(workfactor > 18) - throw std::invalid_argument("Requested Bcrypt work factor too large"); - - clear(); - - const byte null_salt[16] = { 0 }; - - key_expansion(key, length, salt); - - const size_t rounds = 1 << workfactor; - - for(size_t r = 0; r != rounds; ++r) - { - key_expansion(key, length, null_salt); - key_expansion(salt, 16, null_salt); - } - } - -/* -* Generate one of the Sboxes -*/ -void Blowfish::generate_sbox(MemoryRegion& box, - u32bit& L, u32bit& R, - const byte salt[16], - size_t salt_off) const - { - const u32bit* S1 = &S[0]; - const u32bit* S2 = &S[256]; - const u32bit* S3 = &S[512]; - const u32bit* S4 = &S[768]; - - for(size_t i = 0; i != box.size(); i += 2) - { - L ^= load_be(salt, (i + salt_off) % 4); - R ^= load_be(salt, (i + salt_off + 1) % 4); - - for(size_t j = 0; j != 16; j += 2) - { - L ^= P[j]; - R ^= ((S1[get_byte(0, L)] + S2[get_byte(1, L)]) ^ - S3[get_byte(2, L)]) + S4[get_byte(3, L)]; - - R ^= P[j+1]; - L ^= ((S1[get_byte(0, R)] + S2[get_byte(1, R)]) ^ - S3[get_byte(2, R)]) + S4[get_byte(3, R)]; - } - - u32bit T = R; R = L ^ P[16]; L = T ^ P[17]; - box[i] = L; - box[i+1] = R; - } - } - -/* -* Clear memory of sensitive data -*/ -void Blowfish::clear() - { - std::copy(P_INIT, P_INIT + 18, P.begin()); - std::copy(S_INIT, S_INIT + 1024, S.begin()); - } - -} -/* -* Camellia -* (C) 2012 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -namespace Camellia_F { - -namespace { - -/* -* We use the slow byte-wise version of F in the first and last rounds -* to help protect against timing attacks -*/ -u64bit F_SLOW(u64bit v, u64bit K) - { - static const byte SBOX[256] = { - 0x70, 0x82, 0x2C, 0xEC, 0xB3, 0x27, 0xC0, 0xE5, 0xE4, 0x85, 0x57, - 0x35, 0xEA, 0x0C, 0xAE, 0x41, 0x23, 0xEF, 0x6B, 0x93, 0x45, 0x19, - 0xA5, 0x21, 0xED, 0x0E, 0x4F, 0x4E, 0x1D, 0x65, 0x92, 0xBD, 0x86, - 0xB8, 0xAF, 0x8F, 0x7C, 0xEB, 0x1F, 0xCE, 0x3E, 0x30, 0xDC, 0x5F, - 0x5E, 0xC5, 0x0B, 0x1A, 0xA6, 0xE1, 0x39, 0xCA, 0xD5, 0x47, 0x5D, - 0x3D, 0xD9, 0x01, 0x5A, 0xD6, 0x51, 0x56, 0x6C, 0x4D, 0x8B, 0x0D, - 0x9A, 0x66, 0xFB, 0xCC, 0xB0, 0x2D, 0x74, 0x12, 0x2B, 0x20, 0xF0, - 0xB1, 0x84, 0x99, 0xDF, 0x4C, 0xCB, 0xC2, 0x34, 0x7E, 0x76, 0x05, - 0x6D, 0xB7, 0xA9, 0x31, 0xD1, 0x17, 0x04, 0xD7, 0x14, 0x58, 0x3A, - 0x61, 0xDE, 0x1B, 0x11, 0x1C, 0x32, 0x0F, 0x9C, 0x16, 0x53, 0x18, - 0xF2, 0x22, 0xFE, 0x44, 0xCF, 0xB2, 0xC3, 0xB5, 0x7A, 0x91, 0x24, - 0x08, 0xE8, 0xA8, 0x60, 0xFC, 0x69, 0x50, 0xAA, 0xD0, 0xA0, 0x7D, - 0xA1, 0x89, 0x62, 0x97, 0x54, 0x5B, 0x1E, 0x95, 0xE0, 0xFF, 0x64, - 0xD2, 0x10, 0xC4, 0x00, 0x48, 0xA3, 0xF7, 0x75, 0xDB, 0x8A, 0x03, - 0xE6, 0xDA, 0x09, 0x3F, 0xDD, 0x94, 0x87, 0x5C, 0x83, 0x02, 0xCD, - 0x4A, 0x90, 0x33, 0x73, 0x67, 0xF6, 0xF3, 0x9D, 0x7F, 0xBF, 0xE2, - 0x52, 0x9B, 0xD8, 0x26, 0xC8, 0x37, 0xC6, 0x3B, 0x81, 0x96, 0x6F, - 0x4B, 0x13, 0xBE, 0x63, 0x2E, 0xE9, 0x79, 0xA7, 0x8C, 0x9F, 0x6E, - 0xBC, 0x8E, 0x29, 0xF5, 0xF9, 0xB6, 0x2F, 0xFD, 0xB4, 0x59, 0x78, - 0x98, 0x06, 0x6A, 0xE7, 0x46, 0x71, 0xBA, 0xD4, 0x25, 0xAB, 0x42, - 0x88, 0xA2, 0x8D, 0xFA, 0x72, 0x07, 0xB9, 0x55, 0xF8, 0xEE, 0xAC, - 0x0A, 0x36, 0x49, 0x2A, 0x68, 0x3C, 0x38, 0xF1, 0xA4, 0x40, 0x28, - 0xD3, 0x7B, 0xBB, 0xC9, 0x43, 0xC1, 0x15, 0xE3, 0xAD, 0xF4, 0x77, - 0xC7, 0x80, 0x9E }; - - const u64bit x = v ^ K; - - const byte t1 = SBOX[get_byte(0, x)]; - const byte t2 = rotate_left(SBOX[get_byte(1, x)], 1); - const byte t3 = rotate_left(SBOX[get_byte(2, x)], 7); - const byte t4 = SBOX[rotate_left(get_byte(3, x), 1)]; - const byte t5 = rotate_left(SBOX[get_byte(4, x)], 1); - const byte t6 = rotate_left(SBOX[get_byte(5, x)], 7); - const byte t7 = SBOX[rotate_left(get_byte(6, x), 1)]; - const byte t8 = SBOX[get_byte(7, x)]; - - const byte y1 = t1 ^ t3 ^ t4 ^ t6 ^ t7 ^ t8; - const byte y2 = t1 ^ t2 ^ t4 ^ t5 ^ t7 ^ t8; - const byte y3 = t1 ^ t2 ^ t3 ^ t5 ^ t6 ^ t8; - const byte y4 = t2 ^ t3 ^ t4 ^ t5 ^ t6 ^ t7; - const byte y5 = t1 ^ t2 ^ t6 ^ t7 ^ t8; - const byte y6 = t2 ^ t3 ^ t5 ^ t7 ^ t8; - const byte y7 = t3 ^ t4 ^ t5 ^ t6 ^ t8; - const byte y8 = t1 ^ t4 ^ t5 ^ t6 ^ t7; - - return make_u64bit(y1, y2, y3, y4, y5, y6, y7, y8); - } - -inline u64bit F(u64bit v, u64bit K) - { - const u64bit x = v ^ K; - - return Camellia_SBOX1[get_byte(0, x)] ^ - Camellia_SBOX2[get_byte(1, x)] ^ - Camellia_SBOX3[get_byte(2, x)] ^ - Camellia_SBOX4[get_byte(3, x)] ^ - Camellia_SBOX5[get_byte(4, x)] ^ - Camellia_SBOX6[get_byte(5, x)] ^ - Camellia_SBOX7[get_byte(6, x)] ^ - Camellia_SBOX8[get_byte(7, x)]; - } - -inline u64bit FL(u64bit v, u64bit K) - { - u32bit x1 = (v >> 32); - u32bit x2 = (v & 0xFFFFFFFF); - - const u32bit k1 = (K >> 32); - const u32bit k2 = (K & 0xFFFFFFFF); - - x2 ^= rotate_left(x1 & k1, 1); - x1 ^= (x2 | k2); - - return ((static_cast(x1) << 32) | x2); - } - -inline u64bit FLINV(u64bit v, u64bit K) - { - u32bit x1 = (v >> 32); - u32bit x2 = (v & 0xFFFFFFFF); - - const u32bit k1 = (K >> 32); - const u32bit k2 = (K & 0xFFFFFFFF); - - x1 ^= (x2 | k2); - x2 ^= rotate_left(x1 & k1, 1); - - return ((static_cast(x1) << 32) | x2); - } - -/* -* Camellia Encryption -*/ -void encrypt(const byte in[], byte out[], size_t blocks, - const SecureVector& SK, const size_t rounds) - { - for(size_t i = 0; i != blocks; ++i) - { - u64bit D1 = load_be(in, 0); - u64bit D2 = load_be(in, 1); - - const u64bit* K = &SK[0]; - - D1 ^= *K++; - D2 ^= *K++; - - D2 ^= F_SLOW(D1, *K++); - D1 ^= F_SLOW(D2, *K++); - - for(size_t r = 1; r != rounds - 1; ++r) - { - if(r % 3 == 0) - { - D1 = FL (D1, *K++); - D2 = FLINV(D2, *K++); - } - - D2 ^= F(D1, *K++); - D1 ^= F(D2, *K++); - } - - D2 ^= F_SLOW(D1, *K++); - D1 ^= F_SLOW(D2, *K++); - - D2 ^= *K++; - D1 ^= *K++; - - store_be(out, D2, D1); - - in += 16; - out += 16; - } - } - -/* -* Camellia Decryption -*/ -void decrypt(const byte in[], byte out[], size_t blocks, - const SecureVector& SK, const size_t rounds) - { - for(size_t i = 0; i != blocks; ++i) - { - u64bit D1 = load_be(in, 0); - u64bit D2 = load_be(in, 1); - - const u64bit* K = &SK[SK.size()-1]; - - D2 ^= *K--; - D1 ^= *K--; - - D2 ^= F_SLOW(D1, *K--); - D1 ^= F_SLOW(D2, *K--); - - for(size_t r = 1; r != rounds - 1; ++r) - { - if(r % 3 == 0) - { - D1 = FL (D1, *K--); - D2 = FLINV(D2, *K--); - } - - D2 ^= F(D1, *K--); - D1 ^= F(D2, *K--); - } - - D2 ^= F_SLOW(D1, *K--); - D1 ^= F_SLOW(D2, *K--); - - D1 ^= *K--; - D2 ^= *K; - - store_be(out, D2, D1); - - in += 16; - out += 16; - } - } - -u64bit left_rot_hi(u64bit h, u64bit l, size_t shift) - { - return (h << shift) | ((l >> (64-shift))); - } - -u64bit left_rot_lo(u64bit h, u64bit l, size_t shift) - { - return (h >> (64-shift)) | (l << shift); - } - -/* -* Camellia Key Schedule -*/ -void key_schedule(SecureVector& SK, const byte key[], size_t length) - { - const u64bit Sigma1 = 0xA09E667F3BCC908BULL; - const u64bit Sigma2 = 0xB67AE8584CAA73B2ULL; - const u64bit Sigma3 = 0xC6EF372FE94F82BEULL; - const u64bit Sigma4 = 0x54FF53A5F1D36F1CULL; - const u64bit Sigma5 = 0x10E527FADE682D1DULL; - const u64bit Sigma6 = 0xB05688C2B3E6C1FDULL; - - const u64bit KL_H = load_be(key, 0); - const u64bit KL_L = load_be(key, 1); - - const u64bit KR_H = (length >= 24) ? load_be(key, 2) : 0; - const u64bit KR_L = - (length == 32) ? load_be(key, 3) : ((length == 24) ? ~KR_H : 0); - - u64bit D1 = KL_H ^ KR_H; - u64bit D2 = KL_L ^ KR_L; - D2 ^= F(D1, Sigma1); - D1 ^= F(D2, Sigma2); - D1 ^= KL_H; - D2 ^= KL_L; - D2 ^= F(D1, Sigma3); - D1 ^= F(D2, Sigma4); - - const u64bit KA_H = D1; - const u64bit KA_L = D2; - - D1 = KA_H ^ KR_H; - D2 = KA_L ^ KR_L; - D2 ^= F(D1, Sigma5); - D1 ^= F(D2, Sigma6); - - const u64bit KB_H = D1; - const u64bit KB_L = D2; - - if(length == 16) - { - SK.resize(26); - - SK[ 0] = KL_H; - SK[ 1] = KL_L; - SK[ 2] = KA_H; - SK[ 3] = KA_L; - SK[ 4] = left_rot_hi(KL_H, KL_L, 15); - SK[ 5] = left_rot_lo(KL_H, KL_L, 15); - SK[ 6] = left_rot_hi(KA_H, KA_L, 15); - SK[ 7] = left_rot_lo(KA_H, KA_L, 15); - SK[ 8] = left_rot_hi(KA_H, KA_L, 30); - SK[ 9] = left_rot_lo(KA_H, KA_L, 30); - SK[10] = left_rot_hi(KL_H, KL_L, 45); - SK[11] = left_rot_lo(KL_H, KL_L, 45); - SK[12] = left_rot_hi(KA_H, KA_L, 45); - SK[13] = left_rot_lo(KL_H, KL_L, 60); - SK[14] = left_rot_hi(KA_H, KA_L, 60); - SK[15] = left_rot_lo(KA_H, KA_L, 60); - SK[16] = left_rot_lo(KL_H, KL_L, 77-64); - SK[17] = left_rot_hi(KL_H, KL_L, 77-64); - SK[18] = left_rot_lo(KL_H, KL_L, 94-64); - SK[19] = left_rot_hi(KL_H, KL_L, 94-64); - SK[20] = left_rot_lo(KA_H, KA_L, 94-64); - SK[21] = left_rot_hi(KA_H, KA_L, 94-64); - SK[22] = left_rot_lo(KL_H, KL_L, 111-64); - SK[23] = left_rot_hi(KL_H, KL_L, 111-64); - SK[24] = left_rot_lo(KA_H, KA_L, 111-64); - SK[25] = left_rot_hi(KA_H, KA_L, 111-64); - } - else - { - SK.resize(34); - - SK[ 0] = KL_H; - SK[ 1] = KL_L; - SK[ 2] = KB_H; - SK[ 3] = KB_L; - - SK[ 4] = left_rot_hi(KR_H, KR_L, 15); - SK[ 5] = left_rot_lo(KR_H, KR_L, 15); - SK[ 6] = left_rot_hi(KA_H, KA_L, 15); - SK[ 7] = left_rot_lo(KA_H, KA_L, 15); - - SK[ 8] = left_rot_hi(KR_H, KR_L, 30); - SK[ 9] = left_rot_lo(KR_H, KR_L, 30); - SK[10] = left_rot_hi(KB_H, KB_L, 30); - SK[11] = left_rot_lo(KB_H, KB_L, 30); - - SK[12] = left_rot_hi(KL_H, KL_L, 45); - SK[13] = left_rot_lo(KL_H, KL_L, 45); - SK[14] = left_rot_hi(KA_H, KA_L, 45); - SK[15] = left_rot_lo(KA_H, KA_L, 45); - - SK[16] = left_rot_hi(KL_H, KL_L, 60); - SK[17] = left_rot_lo(KL_H, KL_L, 60); - SK[18] = left_rot_hi(KR_H, KR_L, 60); - SK[19] = left_rot_lo(KR_H, KR_L, 60); - SK[20] = left_rot_hi(KB_H, KB_L, 60); - SK[21] = left_rot_lo(KB_H, KB_L, 60); - - SK[22] = left_rot_lo(KL_H, KL_L, 77-64); - SK[23] = left_rot_hi(KL_H, KL_L, 77-64); - SK[24] = left_rot_lo(KA_H, KA_L, 77-64); - SK[25] = left_rot_hi(KA_H, KA_L, 77-64); - - SK[26] = left_rot_lo(KR_H, KR_L, 94-64); - SK[27] = left_rot_hi(KR_H, KR_L, 94-64); - SK[28] = left_rot_lo(KA_H, KA_L, 94-64); - SK[29] = left_rot_hi(KA_H, KA_L, 94-64); - SK[30] = left_rot_lo(KL_H, KL_L, 111-64); - SK[31] = left_rot_hi(KL_H, KL_L, 111-64); - SK[32] = left_rot_lo(KB_H, KB_L, 111-64); - SK[33] = left_rot_hi(KB_H, KB_L, 111-64); - } - } - -} - -} - -void Camellia_128::encrypt_n(const byte in[], byte out[], size_t blocks) const - { - Camellia_F::encrypt(in, out, blocks, SK, 9); - } - -void Camellia_192::encrypt_n(const byte in[], byte out[], size_t blocks) const - { - Camellia_F::encrypt(in, out, blocks, SK, 12); - } - -void Camellia_256::encrypt_n(const byte in[], byte out[], size_t blocks) const - { - Camellia_F::encrypt(in, out, blocks, SK, 12); - } - -void Camellia_128::decrypt_n(const byte in[], byte out[], size_t blocks) const - { - Camellia_F::decrypt(in, out, blocks, SK, 9); - } - -void Camellia_192::decrypt_n(const byte in[], byte out[], size_t blocks) const - { - Camellia_F::decrypt(in, out, blocks, SK, 12); - } - -void Camellia_256::decrypt_n(const byte in[], byte out[], size_t blocks) const - { - Camellia_F::decrypt(in, out, blocks, SK, 12); - } - -void Camellia_128::key_schedule(const byte key[], size_t length) - { - Camellia_F::key_schedule(SK, key, length); - } - -void Camellia_192::key_schedule(const byte key[], size_t length) - { - Camellia_F::key_schedule(SK, key, length); - } - -void Camellia_256::key_schedule(const byte key[], size_t length) - { - Camellia_F::key_schedule(SK, key, length); - } - -} -/* -* Block Cipher Cascade -* (C) 2010 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -void Cascade_Cipher::encrypt_n(const byte in[], byte out[], - size_t blocks) const - { - size_t c1_blocks = blocks * (block_size() / cipher1->block_size()); - size_t c2_blocks = blocks * (block_size() / cipher2->block_size()); - - cipher1->encrypt_n(in, out, c1_blocks); - cipher2->encrypt_n(out, out, c2_blocks); - } - -void Cascade_Cipher::decrypt_n(const byte in[], byte out[], - size_t blocks) const - { - size_t c1_blocks = blocks * (block_size() / cipher1->block_size()); - size_t c2_blocks = blocks * (block_size() / cipher2->block_size()); - - cipher2->decrypt_n(in, out, c2_blocks); - cipher1->decrypt_n(out, out, c1_blocks); - } - -void Cascade_Cipher::key_schedule(const byte key[], size_t) - { - const byte* key2 = key + cipher1->maximum_keylength(); - - cipher1->set_key(key , cipher1->maximum_keylength()); - cipher2->set_key(key2, cipher2->maximum_keylength()); - } - -void Cascade_Cipher::clear() - { - cipher1->clear(); - cipher2->clear(); - } - -std::string Cascade_Cipher::name() const - { - return "Cascade(" + cipher1->name() + "," + cipher2->name() + ")"; - } - -BlockCipher* Cascade_Cipher::clone() const - { - return new Cascade_Cipher(cipher1->clone(), - cipher2->clone()); - } - -namespace { - -size_t euclids_algorithm(size_t a, size_t b) - { - while(b != 0) // gcd - { - size_t t = b; - b = a % b; - a = t; - } - - return a; - } - -size_t block_size_for_cascade(size_t bs, size_t bs2) - { - if(bs == bs2) - return bs; - - size_t gcd = euclids_algorithm(bs, bs2); - - return (bs * bs2) / gcd; - } - -} - -Cascade_Cipher::Cascade_Cipher(BlockCipher* c1, BlockCipher* c2) : - cipher1(c1), cipher2(c2) - { - block = block_size_for_cascade(c1->block_size(), c2->block_size()); - - if(block_size() % c1->block_size() || block_size() % c2->block_size()) - throw Internal_Error("Failure in " + name() + " constructor"); - } - -Cascade_Cipher::~Cascade_Cipher() - { - delete cipher1; - delete cipher2; - } - -} -/* -* CAST-128 -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -namespace { - -/* -* CAST-128 Round Type 1 -*/ -inline void R1(u32bit& L, u32bit R, u32bit MK, u32bit RK) - { - u32bit T = rotate_left(MK + R, RK); - L ^= (CAST_SBOX1[get_byte(0, T)] ^ CAST_SBOX2[get_byte(1, T)]) - - CAST_SBOX3[get_byte(2, T)] + CAST_SBOX4[get_byte(3, T)]; - } - -/* -* CAST-128 Round Type 2 -*/ -inline void R2(u32bit& L, u32bit R, u32bit MK, u32bit RK) - { - u32bit T = rotate_left(MK ^ R, RK); - L ^= (CAST_SBOX1[get_byte(0, T)] - CAST_SBOX2[get_byte(1, T)] + - CAST_SBOX3[get_byte(2, T)]) ^ CAST_SBOX4[get_byte(3, T)]; - } - -/* -* CAST-128 Round Type 3 -*/ -inline void R3(u32bit& L, u32bit R, u32bit MK, u32bit RK) - { - u32bit T = rotate_left(MK - R, RK); - L ^= ((CAST_SBOX1[get_byte(0, T)] + CAST_SBOX2[get_byte(1, T)]) ^ - CAST_SBOX3[get_byte(2, T)]) - CAST_SBOX4[get_byte(3, T)]; - } - -} - -/* -* CAST-128 Encryption -*/ -void CAST_128::encrypt_n(const byte in[], byte out[], size_t blocks) const - { - for(size_t i = 0; i != blocks; ++i) - { - u32bit L = load_be(in, 0); - u32bit R = load_be(in, 1); - - R1(L, R, MK[ 0], RK[ 0]); - R2(R, L, MK[ 1], RK[ 1]); - R3(L, R, MK[ 2], RK[ 2]); - R1(R, L, MK[ 3], RK[ 3]); - R2(L, R, MK[ 4], RK[ 4]); - R3(R, L, MK[ 5], RK[ 5]); - R1(L, R, MK[ 6], RK[ 6]); - R2(R, L, MK[ 7], RK[ 7]); - R3(L, R, MK[ 8], RK[ 8]); - R1(R, L, MK[ 9], RK[ 9]); - R2(L, R, MK[10], RK[10]); - R3(R, L, MK[11], RK[11]); - R1(L, R, MK[12], RK[12]); - R2(R, L, MK[13], RK[13]); - R3(L, R, MK[14], RK[14]); - R1(R, L, MK[15], RK[15]); - - store_be(out, R, L); - - in += BLOCK_SIZE; - out += BLOCK_SIZE; - } - } - -/* -* CAST-128 Decryption -*/ -void CAST_128::decrypt_n(const byte in[], byte out[], size_t blocks) const - { - for(size_t i = 0; i != blocks; ++i) - { - u32bit L = load_be(in, 0); - u32bit R = load_be(in, 1); - - R1(L, R, MK[15], RK[15]); - R3(R, L, MK[14], RK[14]); - R2(L, R, MK[13], RK[13]); - R1(R, L, MK[12], RK[12]); - R3(L, R, MK[11], RK[11]); - R2(R, L, MK[10], RK[10]); - R1(L, R, MK[ 9], RK[ 9]); - R3(R, L, MK[ 8], RK[ 8]); - R2(L, R, MK[ 7], RK[ 7]); - R1(R, L, MK[ 6], RK[ 6]); - R3(L, R, MK[ 5], RK[ 5]); - R2(R, L, MK[ 4], RK[ 4]); - R1(L, R, MK[ 3], RK[ 3]); - R3(R, L, MK[ 2], RK[ 2]); - R2(L, R, MK[ 1], RK[ 1]); - R1(R, L, MK[ 0], RK[ 0]); - - store_be(out, R, L); - - in += BLOCK_SIZE; - out += BLOCK_SIZE; - } - } - -/* -* CAST-128 Key Schedule -*/ -void CAST_128::key_schedule(const byte key[], size_t length) - { - clear(); - SecureVector X(4); - for(size_t j = 0; j != length; ++j) - X[j/4] = (X[j/4] << 8) + key[j]; - - cast_ks(MK, X); - cast_ks(RK, X); - - for(size_t j = 0; j != 16; ++j) - RK[j] %= 32; - } - -/* -* S-Box Based Key Expansion -*/ -void CAST_128::cast_ks(MemoryRegion& K, - MemoryRegion& X) - { - class ByteReader - { - public: - byte operator()(size_t i) { return (X[i/4] >> (8*(3 - (i%4)))); } - ByteReader(const u32bit* x) : X(x) {} - private: - const u32bit* X; - }; - - SecureVector Z(4); - ByteReader x(&X[0]), z(&Z[0]); - - Z[0] = X[0] ^ S5[x(13)] ^ S6[x(15)] ^ S7[x(12)] ^ S8[x(14)] ^ S7[x( 8)]; - Z[1] = X[2] ^ S5[z( 0)] ^ S6[z( 2)] ^ S7[z( 1)] ^ S8[z( 3)] ^ S8[x(10)]; - Z[2] = X[3] ^ S5[z( 7)] ^ S6[z( 6)] ^ S7[z( 5)] ^ S8[z( 4)] ^ S5[x( 9)]; - Z[3] = X[1] ^ S5[z(10)] ^ S6[z( 9)] ^ S7[z(11)] ^ S8[z( 8)] ^ S6[x(11)]; - K[ 0] = S5[z( 8)] ^ S6[z( 9)] ^ S7[z( 7)] ^ S8[z( 6)] ^ S5[z( 2)]; - K[ 1] = S5[z(10)] ^ S6[z(11)] ^ S7[z( 5)] ^ S8[z( 4)] ^ S6[z( 6)]; - K[ 2] = S5[z(12)] ^ S6[z(13)] ^ S7[z( 3)] ^ S8[z( 2)] ^ S7[z( 9)]; - K[ 3] = S5[z(14)] ^ S6[z(15)] ^ S7[z( 1)] ^ S8[z( 0)] ^ S8[z(12)]; - X[0] = Z[2] ^ S5[z( 5)] ^ S6[z( 7)] ^ S7[z( 4)] ^ S8[z( 6)] ^ S7[z( 0)]; - X[1] = Z[0] ^ S5[x( 0)] ^ S6[x( 2)] ^ S7[x( 1)] ^ S8[x( 3)] ^ S8[z( 2)]; - X[2] = Z[1] ^ S5[x( 7)] ^ S6[x( 6)] ^ S7[x( 5)] ^ S8[x( 4)] ^ S5[z( 1)]; - X[3] = Z[3] ^ S5[x(10)] ^ S6[x( 9)] ^ S7[x(11)] ^ S8[x( 8)] ^ S6[z( 3)]; - K[ 4] = S5[x( 3)] ^ S6[x( 2)] ^ S7[x(12)] ^ S8[x(13)] ^ S5[x( 8)]; - K[ 5] = S5[x( 1)] ^ S6[x( 0)] ^ S7[x(14)] ^ S8[x(15)] ^ S6[x(13)]; - K[ 6] = S5[x( 7)] ^ S6[x( 6)] ^ S7[x( 8)] ^ S8[x( 9)] ^ S7[x( 3)]; - K[ 7] = S5[x( 5)] ^ S6[x( 4)] ^ S7[x(10)] ^ S8[x(11)] ^ S8[x( 7)]; - Z[0] = X[0] ^ S5[x(13)] ^ S6[x(15)] ^ S7[x(12)] ^ S8[x(14)] ^ S7[x( 8)]; - Z[1] = X[2] ^ S5[z( 0)] ^ S6[z( 2)] ^ S7[z( 1)] ^ S8[z( 3)] ^ S8[x(10)]; - Z[2] = X[3] ^ S5[z( 7)] ^ S6[z( 6)] ^ S7[z( 5)] ^ S8[z( 4)] ^ S5[x( 9)]; - Z[3] = X[1] ^ S5[z(10)] ^ S6[z( 9)] ^ S7[z(11)] ^ S8[z( 8)] ^ S6[x(11)]; - K[ 8] = S5[z( 3)] ^ S6[z( 2)] ^ S7[z(12)] ^ S8[z(13)] ^ S5[z( 9)]; - K[ 9] = S5[z( 1)] ^ S6[z( 0)] ^ S7[z(14)] ^ S8[z(15)] ^ S6[z(12)]; - K[10] = S5[z( 7)] ^ S6[z( 6)] ^ S7[z( 8)] ^ S8[z( 9)] ^ S7[z( 2)]; - K[11] = S5[z( 5)] ^ S6[z( 4)] ^ S7[z(10)] ^ S8[z(11)] ^ S8[z( 6)]; - X[0] = Z[2] ^ S5[z( 5)] ^ S6[z( 7)] ^ S7[z( 4)] ^ S8[z( 6)] ^ S7[z( 0)]; - X[1] = Z[0] ^ S5[x( 0)] ^ S6[x( 2)] ^ S7[x( 1)] ^ S8[x( 3)] ^ S8[z( 2)]; - X[2] = Z[1] ^ S5[x( 7)] ^ S6[x( 6)] ^ S7[x( 5)] ^ S8[x( 4)] ^ S5[z( 1)]; - X[3] = Z[3] ^ S5[x(10)] ^ S6[x( 9)] ^ S7[x(11)] ^ S8[x( 8)] ^ S6[z( 3)]; - K[12] = S5[x( 8)] ^ S6[x( 9)] ^ S7[x( 7)] ^ S8[x( 6)] ^ S5[x( 3)]; - K[13] = S5[x(10)] ^ S6[x(11)] ^ S7[x( 5)] ^ S8[x( 4)] ^ S6[x( 7)]; - K[14] = S5[x(12)] ^ S6[x(13)] ^ S7[x( 3)] ^ S8[x( 2)] ^ S7[x( 8)]; - K[15] = S5[x(14)] ^ S6[x(15)] ^ S7[x( 1)] ^ S8[x( 0)] ^ S8[x(13)]; - } - -} -/* -* CAST-256 -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -namespace { - -/* -* CAST-256 Round Type 1 -*/ -void round1(u32bit& out, u32bit in, u32bit mask, u32bit rot) - { - u32bit temp = rotate_left(mask + in, rot); - out ^= (CAST_SBOX1[get_byte(0, temp)] ^ CAST_SBOX2[get_byte(1, temp)]) - - CAST_SBOX3[get_byte(2, temp)] + CAST_SBOX4[get_byte(3, temp)]; - } - -/* -* CAST-256 Round Type 2 -*/ -void round2(u32bit& out, u32bit in, u32bit mask, u32bit rot) - { - u32bit temp = rotate_left(mask ^ in, rot); - out ^= (CAST_SBOX1[get_byte(0, temp)] - CAST_SBOX2[get_byte(1, temp)] + - CAST_SBOX3[get_byte(2, temp)]) ^ CAST_SBOX4[get_byte(3, temp)]; - } - -/* -* CAST-256 Round Type 3 -*/ -void round3(u32bit& out, u32bit in, u32bit mask, u32bit rot) - { - u32bit temp = rotate_left(mask - in, rot); - out ^= ((CAST_SBOX1[get_byte(0, temp)] + CAST_SBOX2[get_byte(1, temp)]) ^ - CAST_SBOX3[get_byte(2, temp)]) - CAST_SBOX4[get_byte(3, temp)]; - } - -} - -/* -* CAST-256 Encryption -*/ -void CAST_256::encrypt_n(const byte in[], byte out[], size_t blocks) const - { - for(size_t i = 0; i != blocks; ++i) - { - u32bit A = load_be(in, 0); - u32bit B = load_be(in, 1); - u32bit C = load_be(in, 2); - u32bit D = load_be(in, 3); - - round1(C, D, MK[ 0], RK[ 0]); round2(B, C, MK[ 1], RK[ 1]); - round3(A, B, MK[ 2], RK[ 2]); round1(D, A, MK[ 3], RK[ 3]); - round1(C, D, MK[ 4], RK[ 4]); round2(B, C, MK[ 5], RK[ 5]); - round3(A, B, MK[ 6], RK[ 6]); round1(D, A, MK[ 7], RK[ 7]); - round1(C, D, MK[ 8], RK[ 8]); round2(B, C, MK[ 9], RK[ 9]); - round3(A, B, MK[10], RK[10]); round1(D, A, MK[11], RK[11]); - round1(C, D, MK[12], RK[12]); round2(B, C, MK[13], RK[13]); - round3(A, B, MK[14], RK[14]); round1(D, A, MK[15], RK[15]); - round1(C, D, MK[16], RK[16]); round2(B, C, MK[17], RK[17]); - round3(A, B, MK[18], RK[18]); round1(D, A, MK[19], RK[19]); - round1(C, D, MK[20], RK[20]); round2(B, C, MK[21], RK[21]); - round3(A, B, MK[22], RK[22]); round1(D, A, MK[23], RK[23]); - round1(D, A, MK[27], RK[27]); round3(A, B, MK[26], RK[26]); - round2(B, C, MK[25], RK[25]); round1(C, D, MK[24], RK[24]); - round1(D, A, MK[31], RK[31]); round3(A, B, MK[30], RK[30]); - round2(B, C, MK[29], RK[29]); round1(C, D, MK[28], RK[28]); - round1(D, A, MK[35], RK[35]); round3(A, B, MK[34], RK[34]); - round2(B, C, MK[33], RK[33]); round1(C, D, MK[32], RK[32]); - round1(D, A, MK[39], RK[39]); round3(A, B, MK[38], RK[38]); - round2(B, C, MK[37], RK[37]); round1(C, D, MK[36], RK[36]); - round1(D, A, MK[43], RK[43]); round3(A, B, MK[42], RK[42]); - round2(B, C, MK[41], RK[41]); round1(C, D, MK[40], RK[40]); - round1(D, A, MK[47], RK[47]); round3(A, B, MK[46], RK[46]); - round2(B, C, MK[45], RK[45]); round1(C, D, MK[44], RK[44]); - - store_be(out, A, B, C, D); - - in += BLOCK_SIZE; - out += BLOCK_SIZE; - } - } - -/* -* CAST-256 Decryption -*/ -void CAST_256::decrypt_n(const byte in[], byte out[], size_t blocks) const - { - for(size_t i = 0; i != blocks; ++i) - { - u32bit A = load_be(in, 0); - u32bit B = load_be(in, 1); - u32bit C = load_be(in, 2); - u32bit D = load_be(in, 3); - - round1(C, D, MK[44], RK[44]); round2(B, C, MK[45], RK[45]); - round3(A, B, MK[46], RK[46]); round1(D, A, MK[47], RK[47]); - round1(C, D, MK[40], RK[40]); round2(B, C, MK[41], RK[41]); - round3(A, B, MK[42], RK[42]); round1(D, A, MK[43], RK[43]); - round1(C, D, MK[36], RK[36]); round2(B, C, MK[37], RK[37]); - round3(A, B, MK[38], RK[38]); round1(D, A, MK[39], RK[39]); - round1(C, D, MK[32], RK[32]); round2(B, C, MK[33], RK[33]); - round3(A, B, MK[34], RK[34]); round1(D, A, MK[35], RK[35]); - round1(C, D, MK[28], RK[28]); round2(B, C, MK[29], RK[29]); - round3(A, B, MK[30], RK[30]); round1(D, A, MK[31], RK[31]); - round1(C, D, MK[24], RK[24]); round2(B, C, MK[25], RK[25]); - round3(A, B, MK[26], RK[26]); round1(D, A, MK[27], RK[27]); - round1(D, A, MK[23], RK[23]); round3(A, B, MK[22], RK[22]); - round2(B, C, MK[21], RK[21]); round1(C, D, MK[20], RK[20]); - round1(D, A, MK[19], RK[19]); round3(A, B, MK[18], RK[18]); - round2(B, C, MK[17], RK[17]); round1(C, D, MK[16], RK[16]); - round1(D, A, MK[15], RK[15]); round3(A, B, MK[14], RK[14]); - round2(B, C, MK[13], RK[13]); round1(C, D, MK[12], RK[12]); - round1(D, A, MK[11], RK[11]); round3(A, B, MK[10], RK[10]); - round2(B, C, MK[ 9], RK[ 9]); round1(C, D, MK[ 8], RK[ 8]); - round1(D, A, MK[ 7], RK[ 7]); round3(A, B, MK[ 6], RK[ 6]); - round2(B, C, MK[ 5], RK[ 5]); round1(C, D, MK[ 4], RK[ 4]); - round1(D, A, MK[ 3], RK[ 3]); round3(A, B, MK[ 2], RK[ 2]); - round2(B, C, MK[ 1], RK[ 1]); round1(C, D, MK[ 0], RK[ 0]); - - store_be(out, A, B, C, D); - - in += BLOCK_SIZE; - out += BLOCK_SIZE; - } - } - -/* -* CAST-256 Key Schedule -*/ -void CAST_256::key_schedule(const byte key[], size_t length) - { - SecureVector K(8); - for(size_t j = 0; j != length; ++j) - K[j/4] = (K[j/4] << 8) + key[j]; - - u32bit A = K[0], B = K[1], C = K[2], D = K[3], - E = K[4], F = K[5], G = K[6], H = K[7]; - - for(size_t j = 0; j != 48; j += 4) - { - round1(G, H, KEY_MASK[4*j+ 0], KEY_ROT[(4*j+ 0) % 32]); - round2(F, G, KEY_MASK[4*j+ 1], KEY_ROT[(4*j+ 1) % 32]); - round3(E, F, KEY_MASK[4*j+ 2], KEY_ROT[(4*j+ 2) % 32]); - round1(D, E, KEY_MASK[4*j+ 3], KEY_ROT[(4*j+ 3) % 32]); - round2(C, D, KEY_MASK[4*j+ 4], KEY_ROT[(4*j+ 4) % 32]); - round3(B, C, KEY_MASK[4*j+ 5], KEY_ROT[(4*j+ 5) % 32]); - round1(A, B, KEY_MASK[4*j+ 6], KEY_ROT[(4*j+ 6) % 32]); - round2(H, A, KEY_MASK[4*j+ 7], KEY_ROT[(4*j+ 7) % 32]); - round1(G, H, KEY_MASK[4*j+ 8], KEY_ROT[(4*j+ 8) % 32]); - round2(F, G, KEY_MASK[4*j+ 9], KEY_ROT[(4*j+ 9) % 32]); - round3(E, F, KEY_MASK[4*j+10], KEY_ROT[(4*j+10) % 32]); - round1(D, E, KEY_MASK[4*j+11], KEY_ROT[(4*j+11) % 32]); - round2(C, D, KEY_MASK[4*j+12], KEY_ROT[(4*j+12) % 32]); - round3(B, C, KEY_MASK[4*j+13], KEY_ROT[(4*j+13) % 32]); - round1(A, B, KEY_MASK[4*j+14], KEY_ROT[(4*j+14) % 32]); - round2(H, A, KEY_MASK[4*j+15], KEY_ROT[(4*j+15) % 32]); - - RK[j ] = (A % 32); - RK[j+1] = (C % 32); - RK[j+2] = (E % 32); - RK[j+3] = (G % 32); - MK[j ] = H; - MK[j+1] = F; - MK[j+2] = D; - MK[j+3] = B; - } - } - -} -/* -* S-Box Tables for CAST-128 and CAST-256 -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -const u32bit CAST_SBOX1[256] = { - 0x30FB40D4, 0x9FA0FF0B, 0x6BECCD2F, 0x3F258C7A, 0x1E213F2F, 0x9C004DD3, - 0x6003E540, 0xCF9FC949, 0xBFD4AF27, 0x88BBBDB5, 0xE2034090, 0x98D09675, - 0x6E63A0E0, 0x15C361D2, 0xC2E7661D, 0x22D4FF8E, 0x28683B6F, 0xC07FD059, - 0xFF2379C8, 0x775F50E2, 0x43C340D3, 0xDF2F8656, 0x887CA41A, 0xA2D2BD2D, - 0xA1C9E0D6, 0x346C4819, 0x61B76D87, 0x22540F2F, 0x2ABE32E1, 0xAA54166B, - 0x22568E3A, 0xA2D341D0, 0x66DB40C8, 0xA784392F, 0x004DFF2F, 0x2DB9D2DE, - 0x97943FAC, 0x4A97C1D8, 0x527644B7, 0xB5F437A7, 0xB82CBAEF, 0xD751D159, - 0x6FF7F0ED, 0x5A097A1F, 0x827B68D0, 0x90ECF52E, 0x22B0C054, 0xBC8E5935, - 0x4B6D2F7F, 0x50BB64A2, 0xD2664910, 0xBEE5812D, 0xB7332290, 0xE93B159F, - 0xB48EE411, 0x4BFF345D, 0xFD45C240, 0xAD31973F, 0xC4F6D02E, 0x55FC8165, - 0xD5B1CAAD, 0xA1AC2DAE, 0xA2D4B76D, 0xC19B0C50, 0x882240F2, 0x0C6E4F38, - 0xA4E4BFD7, 0x4F5BA272, 0x564C1D2F, 0xC59C5319, 0xB949E354, 0xB04669FE, - 0xB1B6AB8A, 0xC71358DD, 0x6385C545, 0x110F935D, 0x57538AD5, 0x6A390493, - 0xE63D37E0, 0x2A54F6B3, 0x3A787D5F, 0x6276A0B5, 0x19A6FCDF, 0x7A42206A, - 0x29F9D4D5, 0xF61B1891, 0xBB72275E, 0xAA508167, 0x38901091, 0xC6B505EB, - 0x84C7CB8C, 0x2AD75A0F, 0x874A1427, 0xA2D1936B, 0x2AD286AF, 0xAA56D291, - 0xD7894360, 0x425C750D, 0x93B39E26, 0x187184C9, 0x6C00B32D, 0x73E2BB14, - 0xA0BEBC3C, 0x54623779, 0x64459EAB, 0x3F328B82, 0x7718CF82, 0x59A2CEA6, - 0x04EE002E, 0x89FE78E6, 0x3FAB0950, 0x325FF6C2, 0x81383F05, 0x6963C5C8, - 0x76CB5AD6, 0xD49974C9, 0xCA180DCF, 0x380782D5, 0xC7FA5CF6, 0x8AC31511, - 0x35E79E13, 0x47DA91D0, 0xF40F9086, 0xA7E2419E, 0x31366241, 0x051EF495, - 0xAA573B04, 0x4A805D8D, 0x548300D0, 0x00322A3C, 0xBF64CDDF, 0xBA57A68E, - 0x75C6372B, 0x50AFD341, 0xA7C13275, 0x915A0BF5, 0x6B54BFAB, 0x2B0B1426, - 0xAB4CC9D7, 0x449CCD82, 0xF7FBF265, 0xAB85C5F3, 0x1B55DB94, 0xAAD4E324, - 0xCFA4BD3F, 0x2DEAA3E2, 0x9E204D02, 0xC8BD25AC, 0xEADF55B3, 0xD5BD9E98, - 0xE31231B2, 0x2AD5AD6C, 0x954329DE, 0xADBE4528, 0xD8710F69, 0xAA51C90F, - 0xAA786BF6, 0x22513F1E, 0xAA51A79B, 0x2AD344CC, 0x7B5A41F0, 0xD37CFBAD, - 0x1B069505, 0x41ECE491, 0xB4C332E6, 0x032268D4, 0xC9600ACC, 0xCE387E6D, - 0xBF6BB16C, 0x6A70FB78, 0x0D03D9C9, 0xD4DF39DE, 0xE01063DA, 0x4736F464, - 0x5AD328D8, 0xB347CC96, 0x75BB0FC3, 0x98511BFB, 0x4FFBCC35, 0xB58BCF6A, - 0xE11F0ABC, 0xBFC5FE4A, 0xA70AEC10, 0xAC39570A, 0x3F04442F, 0x6188B153, - 0xE0397A2E, 0x5727CB79, 0x9CEB418F, 0x1CACD68D, 0x2AD37C96, 0x0175CB9D, - 0xC69DFF09, 0xC75B65F0, 0xD9DB40D8, 0xEC0E7779, 0x4744EAD4, 0xB11C3274, - 0xDD24CB9E, 0x7E1C54BD, 0xF01144F9, 0xD2240EB1, 0x9675B3FD, 0xA3AC3755, - 0xD47C27AF, 0x51C85F4D, 0x56907596, 0xA5BB15E6, 0x580304F0, 0xCA042CF1, - 0x011A37EA, 0x8DBFAADB, 0x35BA3E4A, 0x3526FFA0, 0xC37B4D09, 0xBC306ED9, - 0x98A52666, 0x5648F725, 0xFF5E569D, 0x0CED63D0, 0x7C63B2CF, 0x700B45E1, - 0xD5EA50F1, 0x85A92872, 0xAF1FBDA7, 0xD4234870, 0xA7870BF3, 0x2D3B4D79, - 0x42E04198, 0x0CD0EDE7, 0x26470DB8, 0xF881814C, 0x474D6AD7, 0x7C0C5E5C, - 0xD1231959, 0x381B7298, 0xF5D2F4DB, 0xAB838653, 0x6E2F1E23, 0x83719C9E, - 0xBD91E046, 0x9A56456E, 0xDC39200C, 0x20C8C571, 0x962BDA1C, 0xE1E696FF, - 0xB141AB08, 0x7CCA89B9, 0x1A69E783, 0x02CC4843, 0xA2F7C579, 0x429EF47D, - 0x427B169C, 0x5AC9F049, 0xDD8F0F00, 0x5C8165BF }; - -const u32bit CAST_SBOX2[256] = { - 0x1F201094, 0xEF0BA75B, 0x69E3CF7E, 0x393F4380, 0xFE61CF7A, 0xEEC5207A, - 0x55889C94, 0x72FC0651, 0xADA7EF79, 0x4E1D7235, 0xD55A63CE, 0xDE0436BA, - 0x99C430EF, 0x5F0C0794, 0x18DCDB7D, 0xA1D6EFF3, 0xA0B52F7B, 0x59E83605, - 0xEE15B094, 0xE9FFD909, 0xDC440086, 0xEF944459, 0xBA83CCB3, 0xE0C3CDFB, - 0xD1DA4181, 0x3B092AB1, 0xF997F1C1, 0xA5E6CF7B, 0x01420DDB, 0xE4E7EF5B, - 0x25A1FF41, 0xE180F806, 0x1FC41080, 0x179BEE7A, 0xD37AC6A9, 0xFE5830A4, - 0x98DE8B7F, 0x77E83F4E, 0x79929269, 0x24FA9F7B, 0xE113C85B, 0xACC40083, - 0xD7503525, 0xF7EA615F, 0x62143154, 0x0D554B63, 0x5D681121, 0xC866C359, - 0x3D63CF73, 0xCEE234C0, 0xD4D87E87, 0x5C672B21, 0x071F6181, 0x39F7627F, - 0x361E3084, 0xE4EB573B, 0x602F64A4, 0xD63ACD9C, 0x1BBC4635, 0x9E81032D, - 0x2701F50C, 0x99847AB4, 0xA0E3DF79, 0xBA6CF38C, 0x10843094, 0x2537A95E, - 0xF46F6FFE, 0xA1FF3B1F, 0x208CFB6A, 0x8F458C74, 0xD9E0A227, 0x4EC73A34, - 0xFC884F69, 0x3E4DE8DF, 0xEF0E0088, 0x3559648D, 0x8A45388C, 0x1D804366, - 0x721D9BFD, 0xA58684BB, 0xE8256333, 0x844E8212, 0x128D8098, 0xFED33FB4, - 0xCE280AE1, 0x27E19BA5, 0xD5A6C252, 0xE49754BD, 0xC5D655DD, 0xEB667064, - 0x77840B4D, 0xA1B6A801, 0x84DB26A9, 0xE0B56714, 0x21F043B7, 0xE5D05860, - 0x54F03084, 0x066FF472, 0xA31AA153, 0xDADC4755, 0xB5625DBF, 0x68561BE6, - 0x83CA6B94, 0x2D6ED23B, 0xECCF01DB, 0xA6D3D0BA, 0xB6803D5C, 0xAF77A709, - 0x33B4A34C, 0x397BC8D6, 0x5EE22B95, 0x5F0E5304, 0x81ED6F61, 0x20E74364, - 0xB45E1378, 0xDE18639B, 0x881CA122, 0xB96726D1, 0x8049A7E8, 0x22B7DA7B, - 0x5E552D25, 0x5272D237, 0x79D2951C, 0xC60D894C, 0x488CB402, 0x1BA4FE5B, - 0xA4B09F6B, 0x1CA815CF, 0xA20C3005, 0x8871DF63, 0xB9DE2FCB, 0x0CC6C9E9, - 0x0BEEFF53, 0xE3214517, 0xB4542835, 0x9F63293C, 0xEE41E729, 0x6E1D2D7C, - 0x50045286, 0x1E6685F3, 0xF33401C6, 0x30A22C95, 0x31A70850, 0x60930F13, - 0x73F98417, 0xA1269859, 0xEC645C44, 0x52C877A9, 0xCDFF33A6, 0xA02B1741, - 0x7CBAD9A2, 0x2180036F, 0x50D99C08, 0xCB3F4861, 0xC26BD765, 0x64A3F6AB, - 0x80342676, 0x25A75E7B, 0xE4E6D1FC, 0x20C710E6, 0xCDF0B680, 0x17844D3B, - 0x31EEF84D, 0x7E0824E4, 0x2CCB49EB, 0x846A3BAE, 0x8FF77888, 0xEE5D60F6, - 0x7AF75673, 0x2FDD5CDB, 0xA11631C1, 0x30F66F43, 0xB3FAEC54, 0x157FD7FA, - 0xEF8579CC, 0xD152DE58, 0xDB2FFD5E, 0x8F32CE19, 0x306AF97A, 0x02F03EF8, - 0x99319AD5, 0xC242FA0F, 0xA7E3EBB0, 0xC68E4906, 0xB8DA230C, 0x80823028, - 0xDCDEF3C8, 0xD35FB171, 0x088A1BC8, 0xBEC0C560, 0x61A3C9E8, 0xBCA8F54D, - 0xC72FEFFA, 0x22822E99, 0x82C570B4, 0xD8D94E89, 0x8B1C34BC, 0x301E16E6, - 0x273BE979, 0xB0FFEAA6, 0x61D9B8C6, 0x00B24869, 0xB7FFCE3F, 0x08DC283B, - 0x43DAF65A, 0xF7E19798, 0x7619B72F, 0x8F1C9BA4, 0xDC8637A0, 0x16A7D3B1, - 0x9FC393B7, 0xA7136EEB, 0xC6BCC63E, 0x1A513742, 0xEF6828BC, 0x520365D6, - 0x2D6A77AB, 0x3527ED4B, 0x821FD216, 0x095C6E2E, 0xDB92F2FB, 0x5EEA29CB, - 0x145892F5, 0x91584F7F, 0x5483697B, 0x2667A8CC, 0x85196048, 0x8C4BACEA, - 0x833860D4, 0x0D23E0F9, 0x6C387E8A, 0x0AE6D249, 0xB284600C, 0xD835731D, - 0xDCB1C647, 0xAC4C56EA, 0x3EBD81B3, 0x230EABB0, 0x6438BC87, 0xF0B5B1FA, - 0x8F5EA2B3, 0xFC184642, 0x0A036B7A, 0x4FB089BD, 0x649DA589, 0xA345415E, - 0x5C038323, 0x3E5D3BB9, 0x43D79572, 0x7E6DD07C, 0x06DFDF1E, 0x6C6CC4EF, - 0x7160A539, 0x73BFBE70, 0x83877605, 0x4523ECF1 }; - -const u32bit CAST_SBOX3[256] = { - 0x8DEFC240, 0x25FA5D9F, 0xEB903DBF, 0xE810C907, 0x47607FFF, 0x369FE44B, - 0x8C1FC644, 0xAECECA90, 0xBEB1F9BF, 0xEEFBCAEA, 0xE8CF1950, 0x51DF07AE, - 0x920E8806, 0xF0AD0548, 0xE13C8D83, 0x927010D5, 0x11107D9F, 0x07647DB9, - 0xB2E3E4D4, 0x3D4F285E, 0xB9AFA820, 0xFADE82E0, 0xA067268B, 0x8272792E, - 0x553FB2C0, 0x489AE22B, 0xD4EF9794, 0x125E3FBC, 0x21FFFCEE, 0x825B1BFD, - 0x9255C5ED, 0x1257A240, 0x4E1A8302, 0xBAE07FFF, 0x528246E7, 0x8E57140E, - 0x3373F7BF, 0x8C9F8188, 0xA6FC4EE8, 0xC982B5A5, 0xA8C01DB7, 0x579FC264, - 0x67094F31, 0xF2BD3F5F, 0x40FFF7C1, 0x1FB78DFC, 0x8E6BD2C1, 0x437BE59B, - 0x99B03DBF, 0xB5DBC64B, 0x638DC0E6, 0x55819D99, 0xA197C81C, 0x4A012D6E, - 0xC5884A28, 0xCCC36F71, 0xB843C213, 0x6C0743F1, 0x8309893C, 0x0FEDDD5F, - 0x2F7FE850, 0xD7C07F7E, 0x02507FBF, 0x5AFB9A04, 0xA747D2D0, 0x1651192E, - 0xAF70BF3E, 0x58C31380, 0x5F98302E, 0x727CC3C4, 0x0A0FB402, 0x0F7FEF82, - 0x8C96FDAD, 0x5D2C2AAE, 0x8EE99A49, 0x50DA88B8, 0x8427F4A0, 0x1EAC5790, - 0x796FB449, 0x8252DC15, 0xEFBD7D9B, 0xA672597D, 0xADA840D8, 0x45F54504, - 0xFA5D7403, 0xE83EC305, 0x4F91751A, 0x925669C2, 0x23EFE941, 0xA903F12E, - 0x60270DF2, 0x0276E4B6, 0x94FD6574, 0x927985B2, 0x8276DBCB, 0x02778176, - 0xF8AF918D, 0x4E48F79E, 0x8F616DDF, 0xE29D840E, 0x842F7D83, 0x340CE5C8, - 0x96BBB682, 0x93B4B148, 0xEF303CAB, 0x984FAF28, 0x779FAF9B, 0x92DC560D, - 0x224D1E20, 0x8437AA88, 0x7D29DC96, 0x2756D3DC, 0x8B907CEE, 0xB51FD240, - 0xE7C07CE3, 0xE566B4A1, 0xC3E9615E, 0x3CF8209D, 0x6094D1E3, 0xCD9CA341, - 0x5C76460E, 0x00EA983B, 0xD4D67881, 0xFD47572C, 0xF76CEDD9, 0xBDA8229C, - 0x127DADAA, 0x438A074E, 0x1F97C090, 0x081BDB8A, 0x93A07EBE, 0xB938CA15, - 0x97B03CFF, 0x3DC2C0F8, 0x8D1AB2EC, 0x64380E51, 0x68CC7BFB, 0xD90F2788, - 0x12490181, 0x5DE5FFD4, 0xDD7EF86A, 0x76A2E214, 0xB9A40368, 0x925D958F, - 0x4B39FFFA, 0xBA39AEE9, 0xA4FFD30B, 0xFAF7933B, 0x6D498623, 0x193CBCFA, - 0x27627545, 0x825CF47A, 0x61BD8BA0, 0xD11E42D1, 0xCEAD04F4, 0x127EA392, - 0x10428DB7, 0x8272A972, 0x9270C4A8, 0x127DE50B, 0x285BA1C8, 0x3C62F44F, - 0x35C0EAA5, 0xE805D231, 0x428929FB, 0xB4FCDF82, 0x4FB66A53, 0x0E7DC15B, - 0x1F081FAB, 0x108618AE, 0xFCFD086D, 0xF9FF2889, 0x694BCC11, 0x236A5CAE, - 0x12DECA4D, 0x2C3F8CC5, 0xD2D02DFE, 0xF8EF5896, 0xE4CF52DA, 0x95155B67, - 0x494A488C, 0xB9B6A80C, 0x5C8F82BC, 0x89D36B45, 0x3A609437, 0xEC00C9A9, - 0x44715253, 0x0A874B49, 0xD773BC40, 0x7C34671C, 0x02717EF6, 0x4FEB5536, - 0xA2D02FFF, 0xD2BF60C4, 0xD43F03C0, 0x50B4EF6D, 0x07478CD1, 0x006E1888, - 0xA2E53F55, 0xB9E6D4BC, 0xA2048016, 0x97573833, 0xD7207D67, 0xDE0F8F3D, - 0x72F87B33, 0xABCC4F33, 0x7688C55D, 0x7B00A6B0, 0x947B0001, 0x570075D2, - 0xF9BB88F8, 0x8942019E, 0x4264A5FF, 0x856302E0, 0x72DBD92B, 0xEE971B69, - 0x6EA22FDE, 0x5F08AE2B, 0xAF7A616D, 0xE5C98767, 0xCF1FEBD2, 0x61EFC8C2, - 0xF1AC2571, 0xCC8239C2, 0x67214CB8, 0xB1E583D1, 0xB7DC3E62, 0x7F10BDCE, - 0xF90A5C38, 0x0FF0443D, 0x606E6DC6, 0x60543A49, 0x5727C148, 0x2BE98A1D, - 0x8AB41738, 0x20E1BE24, 0xAF96DA0F, 0x68458425, 0x99833BE5, 0x600D457D, - 0x282F9350, 0x8334B362, 0xD91D1120, 0x2B6D8DA0, 0x642B1E31, 0x9C305A00, - 0x52BCE688, 0x1B03588A, 0xF7BAEFD5, 0x4142ED9C, 0xA4315C11, 0x83323EC5, - 0xDFEF4636, 0xA133C501, 0xE9D3531C, 0xEE353783 }; - -const u32bit CAST_SBOX4[256] = { - 0x9DB30420, 0x1FB6E9DE, 0xA7BE7BEF, 0xD273A298, 0x4A4F7BDB, 0x64AD8C57, - 0x85510443, 0xFA020ED1, 0x7E287AFF, 0xE60FB663, 0x095F35A1, 0x79EBF120, - 0xFD059D43, 0x6497B7B1, 0xF3641F63, 0x241E4ADF, 0x28147F5F, 0x4FA2B8CD, - 0xC9430040, 0x0CC32220, 0xFDD30B30, 0xC0A5374F, 0x1D2D00D9, 0x24147B15, - 0xEE4D111A, 0x0FCA5167, 0x71FF904C, 0x2D195FFE, 0x1A05645F, 0x0C13FEFE, - 0x081B08CA, 0x05170121, 0x80530100, 0xE83E5EFE, 0xAC9AF4F8, 0x7FE72701, - 0xD2B8EE5F, 0x06DF4261, 0xBB9E9B8A, 0x7293EA25, 0xCE84FFDF, 0xF5718801, - 0x3DD64B04, 0xA26F263B, 0x7ED48400, 0x547EEBE6, 0x446D4CA0, 0x6CF3D6F5, - 0x2649ABDF, 0xAEA0C7F5, 0x36338CC1, 0x503F7E93, 0xD3772061, 0x11B638E1, - 0x72500E03, 0xF80EB2BB, 0xABE0502E, 0xEC8D77DE, 0x57971E81, 0xE14F6746, - 0xC9335400, 0x6920318F, 0x081DBB99, 0xFFC304A5, 0x4D351805, 0x7F3D5CE3, - 0xA6C866C6, 0x5D5BCCA9, 0xDAEC6FEA, 0x9F926F91, 0x9F46222F, 0x3991467D, - 0xA5BF6D8E, 0x1143C44F, 0x43958302, 0xD0214EEB, 0x022083B8, 0x3FB6180C, - 0x18F8931E, 0x281658E6, 0x26486E3E, 0x8BD78A70, 0x7477E4C1, 0xB506E07C, - 0xF32D0A25, 0x79098B02, 0xE4EABB81, 0x28123B23, 0x69DEAD38, 0x1574CA16, - 0xDF871B62, 0x211C40B7, 0xA51A9EF9, 0x0014377B, 0x041E8AC8, 0x09114003, - 0xBD59E4D2, 0xE3D156D5, 0x4FE876D5, 0x2F91A340, 0x557BE8DE, 0x00EAE4A7, - 0x0CE5C2EC, 0x4DB4BBA6, 0xE756BDFF, 0xDD3369AC, 0xEC17B035, 0x06572327, - 0x99AFC8B0, 0x56C8C391, 0x6B65811C, 0x5E146119, 0x6E85CB75, 0xBE07C002, - 0xC2325577, 0x893FF4EC, 0x5BBFC92D, 0xD0EC3B25, 0xB7801AB7, 0x8D6D3B24, - 0x20C763EF, 0xC366A5FC, 0x9C382880, 0x0ACE3205, 0xAAC9548A, 0xECA1D7C7, - 0x041AFA32, 0x1D16625A, 0x6701902C, 0x9B757A54, 0x31D477F7, 0x9126B031, - 0x36CC6FDB, 0xC70B8B46, 0xD9E66A48, 0x56E55A79, 0x026A4CEB, 0x52437EFF, - 0x2F8F76B4, 0x0DF980A5, 0x8674CDE3, 0xEDDA04EB, 0x17A9BE04, 0x2C18F4DF, - 0xB7747F9D, 0xAB2AF7B4, 0xEFC34D20, 0x2E096B7C, 0x1741A254, 0xE5B6A035, - 0x213D42F6, 0x2C1C7C26, 0x61C2F50F, 0x6552DAF9, 0xD2C231F8, 0x25130F69, - 0xD8167FA2, 0x0418F2C8, 0x001A96A6, 0x0D1526AB, 0x63315C21, 0x5E0A72EC, - 0x49BAFEFD, 0x187908D9, 0x8D0DBD86, 0x311170A7, 0x3E9B640C, 0xCC3E10D7, - 0xD5CAD3B6, 0x0CAEC388, 0xF73001E1, 0x6C728AFF, 0x71EAE2A1, 0x1F9AF36E, - 0xCFCBD12F, 0xC1DE8417, 0xAC07BE6B, 0xCB44A1D8, 0x8B9B0F56, 0x013988C3, - 0xB1C52FCA, 0xB4BE31CD, 0xD8782806, 0x12A3A4E2, 0x6F7DE532, 0x58FD7EB6, - 0xD01EE900, 0x24ADFFC2, 0xF4990FC5, 0x9711AAC5, 0x001D7B95, 0x82E5E7D2, - 0x109873F6, 0x00613096, 0xC32D9521, 0xADA121FF, 0x29908415, 0x7FBB977F, - 0xAF9EB3DB, 0x29C9ED2A, 0x5CE2A465, 0xA730F32C, 0xD0AA3FE8, 0x8A5CC091, - 0xD49E2CE7, 0x0CE454A9, 0xD60ACD86, 0x015F1919, 0x77079103, 0xDEA03AF6, - 0x78A8565E, 0xDEE356DF, 0x21F05CBE, 0x8B75E387, 0xB3C50651, 0xB8A5C3EF, - 0xD8EEB6D2, 0xE523BE77, 0xC2154529, 0x2F69EFDF, 0xAFE67AFB, 0xF470C4B2, - 0xF3E0EB5B, 0xD6CC9876, 0x39E4460C, 0x1FDA8538, 0x1987832F, 0xCA007367, - 0xA99144F8, 0x296B299E, 0x492FC295, 0x9266BEAB, 0xB5676E69, 0x9BD3DDDA, - 0xDF7E052F, 0xDB25701C, 0x1B5E51EE, 0xF65324E6, 0x6AFCE36C, 0x0316CC04, - 0x8644213E, 0xB7DC59D0, 0x7965291F, 0xCCD6FD43, 0x41823979, 0x932BCDF6, - 0xB657C34D, 0x4EDFD282, 0x7AE5290C, 0x3CB9536B, 0x851E20FE, 0x9833557E, - 0x13ECF0B0, 0xD3FFB372, 0x3F85C5C1, 0x0AEF7ED2 }; - -const u32bit CAST_128::S5[256] = { - 0x7EC90C04, 0x2C6E74B9, 0x9B0E66DF, 0xA6337911, 0xB86A7FFF, 0x1DD358F5, - 0x44DD9D44, 0x1731167F, 0x08FBF1FA, 0xE7F511CC, 0xD2051B00, 0x735ABA00, - 0x2AB722D8, 0x386381CB, 0xACF6243A, 0x69BEFD7A, 0xE6A2E77F, 0xF0C720CD, - 0xC4494816, 0xCCF5C180, 0x38851640, 0x15B0A848, 0xE68B18CB, 0x4CAADEFF, - 0x5F480A01, 0x0412B2AA, 0x259814FC, 0x41D0EFE2, 0x4E40B48D, 0x248EB6FB, - 0x8DBA1CFE, 0x41A99B02, 0x1A550A04, 0xBA8F65CB, 0x7251F4E7, 0x95A51725, - 0xC106ECD7, 0x97A5980A, 0xC539B9AA, 0x4D79FE6A, 0xF2F3F763, 0x68AF8040, - 0xED0C9E56, 0x11B4958B, 0xE1EB5A88, 0x8709E6B0, 0xD7E07156, 0x4E29FEA7, - 0x6366E52D, 0x02D1C000, 0xC4AC8E05, 0x9377F571, 0x0C05372A, 0x578535F2, - 0x2261BE02, 0xD642A0C9, 0xDF13A280, 0x74B55BD2, 0x682199C0, 0xD421E5EC, - 0x53FB3CE8, 0xC8ADEDB3, 0x28A87FC9, 0x3D959981, 0x5C1FF900, 0xFE38D399, - 0x0C4EFF0B, 0x062407EA, 0xAA2F4FB1, 0x4FB96976, 0x90C79505, 0xB0A8A774, - 0xEF55A1FF, 0xE59CA2C2, 0xA6B62D27, 0xE66A4263, 0xDF65001F, 0x0EC50966, - 0xDFDD55BC, 0x29DE0655, 0x911E739A, 0x17AF8975, 0x32C7911C, 0x89F89468, - 0x0D01E980, 0x524755F4, 0x03B63CC9, 0x0CC844B2, 0xBCF3F0AA, 0x87AC36E9, - 0xE53A7426, 0x01B3D82B, 0x1A9E7449, 0x64EE2D7E, 0xCDDBB1DA, 0x01C94910, - 0xB868BF80, 0x0D26F3FD, 0x9342EDE7, 0x04A5C284, 0x636737B6, 0x50F5B616, - 0xF24766E3, 0x8ECA36C1, 0x136E05DB, 0xFEF18391, 0xFB887A37, 0xD6E7F7D4, - 0xC7FB7DC9, 0x3063FCDF, 0xB6F589DE, 0xEC2941DA, 0x26E46695, 0xB7566419, - 0xF654EFC5, 0xD08D58B7, 0x48925401, 0xC1BACB7F, 0xE5FF550F, 0xB6083049, - 0x5BB5D0E8, 0x87D72E5A, 0xAB6A6EE1, 0x223A66CE, 0xC62BF3CD, 0x9E0885F9, - 0x68CB3E47, 0x086C010F, 0xA21DE820, 0xD18B69DE, 0xF3F65777, 0xFA02C3F6, - 0x407EDAC3, 0xCBB3D550, 0x1793084D, 0xB0D70EBA, 0x0AB378D5, 0xD951FB0C, - 0xDED7DA56, 0x4124BBE4, 0x94CA0B56, 0x0F5755D1, 0xE0E1E56E, 0x6184B5BE, - 0x580A249F, 0x94F74BC0, 0xE327888E, 0x9F7B5561, 0xC3DC0280, 0x05687715, - 0x646C6BD7, 0x44904DB3, 0x66B4F0A3, 0xC0F1648A, 0x697ED5AF, 0x49E92FF6, - 0x309E374F, 0x2CB6356A, 0x85808573, 0x4991F840, 0x76F0AE02, 0x083BE84D, - 0x28421C9A, 0x44489406, 0x736E4CB8, 0xC1092910, 0x8BC95FC6, 0x7D869CF4, - 0x134F616F, 0x2E77118D, 0xB31B2BE1, 0xAA90B472, 0x3CA5D717, 0x7D161BBA, - 0x9CAD9010, 0xAF462BA2, 0x9FE459D2, 0x45D34559, 0xD9F2DA13, 0xDBC65487, - 0xF3E4F94E, 0x176D486F, 0x097C13EA, 0x631DA5C7, 0x445F7382, 0x175683F4, - 0xCDC66A97, 0x70BE0288, 0xB3CDCF72, 0x6E5DD2F3, 0x20936079, 0x459B80A5, - 0xBE60E2DB, 0xA9C23101, 0xEBA5315C, 0x224E42F2, 0x1C5C1572, 0xF6721B2C, - 0x1AD2FFF3, 0x8C25404E, 0x324ED72F, 0x4067B7FD, 0x0523138E, 0x5CA3BC78, - 0xDC0FD66E, 0x75922283, 0x784D6B17, 0x58EBB16E, 0x44094F85, 0x3F481D87, - 0xFCFEAE7B, 0x77B5FF76, 0x8C2302BF, 0xAAF47556, 0x5F46B02A, 0x2B092801, - 0x3D38F5F7, 0x0CA81F36, 0x52AF4A8A, 0x66D5E7C0, 0xDF3B0874, 0x95055110, - 0x1B5AD7A8, 0xF61ED5AD, 0x6CF6E479, 0x20758184, 0xD0CEFA65, 0x88F7BE58, - 0x4A046826, 0x0FF6F8F3, 0xA09C7F70, 0x5346ABA0, 0x5CE96C28, 0xE176EDA3, - 0x6BAC307F, 0x376829D2, 0x85360FA9, 0x17E3FE2A, 0x24B79767, 0xF5A96B20, - 0xD6CD2595, 0x68FF1EBF, 0x7555442C, 0xF19F06BE, 0xF9E0659A, 0xEEB9491D, - 0x34010718, 0xBB30CAB8, 0xE822FE15, 0x88570983, 0x750E6249, 0xDA627E55, - 0x5E76FFA8, 0xB1534546, 0x6D47DE08, 0xEFE9E7D4 }; - -const u32bit CAST_128::S6[256] = { - 0xF6FA8F9D, 0x2CAC6CE1, 0x4CA34867, 0xE2337F7C, 0x95DB08E7, 0x016843B4, - 0xECED5CBC, 0x325553AC, 0xBF9F0960, 0xDFA1E2ED, 0x83F0579D, 0x63ED86B9, - 0x1AB6A6B8, 0xDE5EBE39, 0xF38FF732, 0x8989B138, 0x33F14961, 0xC01937BD, - 0xF506C6DA, 0xE4625E7E, 0xA308EA99, 0x4E23E33C, 0x79CBD7CC, 0x48A14367, - 0xA3149619, 0xFEC94BD5, 0xA114174A, 0xEAA01866, 0xA084DB2D, 0x09A8486F, - 0xA888614A, 0x2900AF98, 0x01665991, 0xE1992863, 0xC8F30C60, 0x2E78EF3C, - 0xD0D51932, 0xCF0FEC14, 0xF7CA07D2, 0xD0A82072, 0xFD41197E, 0x9305A6B0, - 0xE86BE3DA, 0x74BED3CD, 0x372DA53C, 0x4C7F4448, 0xDAB5D440, 0x6DBA0EC3, - 0x083919A7, 0x9FBAEED9, 0x49DBCFB0, 0x4E670C53, 0x5C3D9C01, 0x64BDB941, - 0x2C0E636A, 0xBA7DD9CD, 0xEA6F7388, 0xE70BC762, 0x35F29ADB, 0x5C4CDD8D, - 0xF0D48D8C, 0xB88153E2, 0x08A19866, 0x1AE2EAC8, 0x284CAF89, 0xAA928223, - 0x9334BE53, 0x3B3A21BF, 0x16434BE3, 0x9AEA3906, 0xEFE8C36E, 0xF890CDD9, - 0x80226DAE, 0xC340A4A3, 0xDF7E9C09, 0xA694A807, 0x5B7C5ECC, 0x221DB3A6, - 0x9A69A02F, 0x68818A54, 0xCEB2296F, 0x53C0843A, 0xFE893655, 0x25BFE68A, - 0xB4628ABC, 0xCF222EBF, 0x25AC6F48, 0xA9A99387, 0x53BDDB65, 0xE76FFBE7, - 0xE967FD78, 0x0BA93563, 0x8E342BC1, 0xE8A11BE9, 0x4980740D, 0xC8087DFC, - 0x8DE4BF99, 0xA11101A0, 0x7FD37975, 0xDA5A26C0, 0xE81F994F, 0x9528CD89, - 0xFD339FED, 0xB87834BF, 0x5F04456D, 0x22258698, 0xC9C4C83B, 0x2DC156BE, - 0x4F628DAA, 0x57F55EC5, 0xE2220ABE, 0xD2916EBF, 0x4EC75B95, 0x24F2C3C0, - 0x42D15D99, 0xCD0D7FA0, 0x7B6E27FF, 0xA8DC8AF0, 0x7345C106, 0xF41E232F, - 0x35162386, 0xE6EA8926, 0x3333B094, 0x157EC6F2, 0x372B74AF, 0x692573E4, - 0xE9A9D848, 0xF3160289, 0x3A62EF1D, 0xA787E238, 0xF3A5F676, 0x74364853, - 0x20951063, 0x4576698D, 0xB6FAD407, 0x592AF950, 0x36F73523, 0x4CFB6E87, - 0x7DA4CEC0, 0x6C152DAA, 0xCB0396A8, 0xC50DFE5D, 0xFCD707AB, 0x0921C42F, - 0x89DFF0BB, 0x5FE2BE78, 0x448F4F33, 0x754613C9, 0x2B05D08D, 0x48B9D585, - 0xDC049441, 0xC8098F9B, 0x7DEDE786, 0xC39A3373, 0x42410005, 0x6A091751, - 0x0EF3C8A6, 0x890072D6, 0x28207682, 0xA9A9F7BE, 0xBF32679D, 0xD45B5B75, - 0xB353FD00, 0xCBB0E358, 0x830F220A, 0x1F8FB214, 0xD372CF08, 0xCC3C4A13, - 0x8CF63166, 0x061C87BE, 0x88C98F88, 0x6062E397, 0x47CF8E7A, 0xB6C85283, - 0x3CC2ACFB, 0x3FC06976, 0x4E8F0252, 0x64D8314D, 0xDA3870E3, 0x1E665459, - 0xC10908F0, 0x513021A5, 0x6C5B68B7, 0x822F8AA0, 0x3007CD3E, 0x74719EEF, - 0xDC872681, 0x073340D4, 0x7E432FD9, 0x0C5EC241, 0x8809286C, 0xF592D891, - 0x08A930F6, 0x957EF305, 0xB7FBFFBD, 0xC266E96F, 0x6FE4AC98, 0xB173ECC0, - 0xBC60B42A, 0x953498DA, 0xFBA1AE12, 0x2D4BD736, 0x0F25FAAB, 0xA4F3FCEB, - 0xE2969123, 0x257F0C3D, 0x9348AF49, 0x361400BC, 0xE8816F4A, 0x3814F200, - 0xA3F94043, 0x9C7A54C2, 0xBC704F57, 0xDA41E7F9, 0xC25AD33A, 0x54F4A084, - 0xB17F5505, 0x59357CBE, 0xEDBD15C8, 0x7F97C5AB, 0xBA5AC7B5, 0xB6F6DEAF, - 0x3A479C3A, 0x5302DA25, 0x653D7E6A, 0x54268D49, 0x51A477EA, 0x5017D55B, - 0xD7D25D88, 0x44136C76, 0x0404A8C8, 0xB8E5A121, 0xB81A928A, 0x60ED5869, - 0x97C55B96, 0xEAEC991B, 0x29935913, 0x01FDB7F1, 0x088E8DFA, 0x9AB6F6F5, - 0x3B4CBF9F, 0x4A5DE3AB, 0xE6051D35, 0xA0E1D855, 0xD36B4CF1, 0xF544EDEB, - 0xB0E93524, 0xBEBB8FBD, 0xA2D762CF, 0x49C92F54, 0x38B5F331, 0x7128A454, - 0x48392905, 0xA65B1DB8, 0x851C97BD, 0xD675CF2F }; - -const u32bit CAST_128::S7[256] = { - 0x85E04019, 0x332BF567, 0x662DBFFF, 0xCFC65693, 0x2A8D7F6F, 0xAB9BC912, - 0xDE6008A1, 0x2028DA1F, 0x0227BCE7, 0x4D642916, 0x18FAC300, 0x50F18B82, - 0x2CB2CB11, 0xB232E75C, 0x4B3695F2, 0xB28707DE, 0xA05FBCF6, 0xCD4181E9, - 0xE150210C, 0xE24EF1BD, 0xB168C381, 0xFDE4E789, 0x5C79B0D8, 0x1E8BFD43, - 0x4D495001, 0x38BE4341, 0x913CEE1D, 0x92A79C3F, 0x089766BE, 0xBAEEADF4, - 0x1286BECF, 0xB6EACB19, 0x2660C200, 0x7565BDE4, 0x64241F7A, 0x8248DCA9, - 0xC3B3AD66, 0x28136086, 0x0BD8DFA8, 0x356D1CF2, 0x107789BE, 0xB3B2E9CE, - 0x0502AA8F, 0x0BC0351E, 0x166BF52A, 0xEB12FF82, 0xE3486911, 0xD34D7516, - 0x4E7B3AFF, 0x5F43671B, 0x9CF6E037, 0x4981AC83, 0x334266CE, 0x8C9341B7, - 0xD0D854C0, 0xCB3A6C88, 0x47BC2829, 0x4725BA37, 0xA66AD22B, 0x7AD61F1E, - 0x0C5CBAFA, 0x4437F107, 0xB6E79962, 0x42D2D816, 0x0A961288, 0xE1A5C06E, - 0x13749E67, 0x72FC081A, 0xB1D139F7, 0xF9583745, 0xCF19DF58, 0xBEC3F756, - 0xC06EBA30, 0x07211B24, 0x45C28829, 0xC95E317F, 0xBC8EC511, 0x38BC46E9, - 0xC6E6FA14, 0xBAE8584A, 0xAD4EBC46, 0x468F508B, 0x7829435F, 0xF124183B, - 0x821DBA9F, 0xAFF60FF4, 0xEA2C4E6D, 0x16E39264, 0x92544A8B, 0x009B4FC3, - 0xABA68CED, 0x9AC96F78, 0x06A5B79A, 0xB2856E6E, 0x1AEC3CA9, 0xBE838688, - 0x0E0804E9, 0x55F1BE56, 0xE7E5363B, 0xB3A1F25D, 0xF7DEBB85, 0x61FE033C, - 0x16746233, 0x3C034C28, 0xDA6D0C74, 0x79AAC56C, 0x3CE4E1AD, 0x51F0C802, - 0x98F8F35A, 0x1626A49F, 0xEED82B29, 0x1D382FE3, 0x0C4FB99A, 0xBB325778, - 0x3EC6D97B, 0x6E77A6A9, 0xCB658B5C, 0xD45230C7, 0x2BD1408B, 0x60C03EB7, - 0xB9068D78, 0xA33754F4, 0xF430C87D, 0xC8A71302, 0xB96D8C32, 0xEBD4E7BE, - 0xBE8B9D2D, 0x7979FB06, 0xE7225308, 0x8B75CF77, 0x11EF8DA4, 0xE083C858, - 0x8D6B786F, 0x5A6317A6, 0xFA5CF7A0, 0x5DDA0033, 0xF28EBFB0, 0xF5B9C310, - 0xA0EAC280, 0x08B9767A, 0xA3D9D2B0, 0x79D34217, 0x021A718D, 0x9AC6336A, - 0x2711FD60, 0x438050E3, 0x069908A8, 0x3D7FEDC4, 0x826D2BEF, 0x4EEB8476, - 0x488DCF25, 0x36C9D566, 0x28E74E41, 0xC2610ACA, 0x3D49A9CF, 0xBAE3B9DF, - 0xB65F8DE6, 0x92AEAF64, 0x3AC7D5E6, 0x9EA80509, 0xF22B017D, 0xA4173F70, - 0xDD1E16C3, 0x15E0D7F9, 0x50B1B887, 0x2B9F4FD5, 0x625ABA82, 0x6A017962, - 0x2EC01B9C, 0x15488AA9, 0xD716E740, 0x40055A2C, 0x93D29A22, 0xE32DBF9A, - 0x058745B9, 0x3453DC1E, 0xD699296E, 0x496CFF6F, 0x1C9F4986, 0xDFE2ED07, - 0xB87242D1, 0x19DE7EAE, 0x053E561A, 0x15AD6F8C, 0x66626C1C, 0x7154C24C, - 0xEA082B2A, 0x93EB2939, 0x17DCB0F0, 0x58D4F2AE, 0x9EA294FB, 0x52CF564C, - 0x9883FE66, 0x2EC40581, 0x763953C3, 0x01D6692E, 0xD3A0C108, 0xA1E7160E, - 0xE4F2DFA6, 0x693ED285, 0x74904698, 0x4C2B0EDD, 0x4F757656, 0x5D393378, - 0xA132234F, 0x3D321C5D, 0xC3F5E194, 0x4B269301, 0xC79F022F, 0x3C997E7E, - 0x5E4F9504, 0x3FFAFBBD, 0x76F7AD0E, 0x296693F4, 0x3D1FCE6F, 0xC61E45BE, - 0xD3B5AB34, 0xF72BF9B7, 0x1B0434C0, 0x4E72B567, 0x5592A33D, 0xB5229301, - 0xCFD2A87F, 0x60AEB767, 0x1814386B, 0x30BCC33D, 0x38A0C07D, 0xFD1606F2, - 0xC363519B, 0x589DD390, 0x5479F8E6, 0x1CB8D647, 0x97FD61A9, 0xEA7759F4, - 0x2D57539D, 0x569A58CF, 0xE84E63AD, 0x462E1B78, 0x6580F87E, 0xF3817914, - 0x91DA55F4, 0x40A230F3, 0xD1988F35, 0xB6E318D2, 0x3FFA50BC, 0x3D40F021, - 0xC3C0BDAE, 0x4958C24C, 0x518F36B2, 0x84B1D370, 0x0FEDCE83, 0x878DDADA, - 0xF2A279C7, 0x94E01BE8, 0x90716F4B, 0x954B8AA3 }; - -const u32bit CAST_128::S8[256] = { - 0xE216300D, 0xBBDDFFFC, 0xA7EBDABD, 0x35648095, 0x7789F8B7, 0xE6C1121B, - 0x0E241600, 0x052CE8B5, 0x11A9CFB0, 0xE5952F11, 0xECE7990A, 0x9386D174, - 0x2A42931C, 0x76E38111, 0xB12DEF3A, 0x37DDDDFC, 0xDE9ADEB1, 0x0A0CC32C, - 0xBE197029, 0x84A00940, 0xBB243A0F, 0xB4D137CF, 0xB44E79F0, 0x049EEDFD, - 0x0B15A15D, 0x480D3168, 0x8BBBDE5A, 0x669DED42, 0xC7ECE831, 0x3F8F95E7, - 0x72DF191B, 0x7580330D, 0x94074251, 0x5C7DCDFA, 0xABBE6D63, 0xAA402164, - 0xB301D40A, 0x02E7D1CA, 0x53571DAE, 0x7A3182A2, 0x12A8DDEC, 0xFDAA335D, - 0x176F43E8, 0x71FB46D4, 0x38129022, 0xCE949AD4, 0xB84769AD, 0x965BD862, - 0x82F3D055, 0x66FB9767, 0x15B80B4E, 0x1D5B47A0, 0x4CFDE06F, 0xC28EC4B8, - 0x57E8726E, 0x647A78FC, 0x99865D44, 0x608BD593, 0x6C200E03, 0x39DC5FF6, - 0x5D0B00A3, 0xAE63AFF2, 0x7E8BD632, 0x70108C0C, 0xBBD35049, 0x2998DF04, - 0x980CF42A, 0x9B6DF491, 0x9E7EDD53, 0x06918548, 0x58CB7E07, 0x3B74EF2E, - 0x522FFFB1, 0xD24708CC, 0x1C7E27CD, 0xA4EB215B, 0x3CF1D2E2, 0x19B47A38, - 0x424F7618, 0x35856039, 0x9D17DEE7, 0x27EB35E6, 0xC9AFF67B, 0x36BAF5B8, - 0x09C467CD, 0xC18910B1, 0xE11DBF7B, 0x06CD1AF8, 0x7170C608, 0x2D5E3354, - 0xD4DE495A, 0x64C6D006, 0xBCC0C62C, 0x3DD00DB3, 0x708F8F34, 0x77D51B42, - 0x264F620F, 0x24B8D2BF, 0x15C1B79E, 0x46A52564, 0xF8D7E54E, 0x3E378160, - 0x7895CDA5, 0x859C15A5, 0xE6459788, 0xC37BC75F, 0xDB07BA0C, 0x0676A3AB, - 0x7F229B1E, 0x31842E7B, 0x24259FD7, 0xF8BEF472, 0x835FFCB8, 0x6DF4C1F2, - 0x96F5B195, 0xFD0AF0FC, 0xB0FE134C, 0xE2506D3D, 0x4F9B12EA, 0xF215F225, - 0xA223736F, 0x9FB4C428, 0x25D04979, 0x34C713F8, 0xC4618187, 0xEA7A6E98, - 0x7CD16EFC, 0x1436876C, 0xF1544107, 0xBEDEEE14, 0x56E9AF27, 0xA04AA441, - 0x3CF7C899, 0x92ECBAE6, 0xDD67016D, 0x151682EB, 0xA842EEDF, 0xFDBA60B4, - 0xF1907B75, 0x20E3030F, 0x24D8C29E, 0xE139673B, 0xEFA63FB8, 0x71873054, - 0xB6F2CF3B, 0x9F326442, 0xCB15A4CC, 0xB01A4504, 0xF1E47D8D, 0x844A1BE5, - 0xBAE7DFDC, 0x42CBDA70, 0xCD7DAE0A, 0x57E85B7A, 0xD53F5AF6, 0x20CF4D8C, - 0xCEA4D428, 0x79D130A4, 0x3486EBFB, 0x33D3CDDC, 0x77853B53, 0x37EFFCB5, - 0xC5068778, 0xE580B3E6, 0x4E68B8F4, 0xC5C8B37E, 0x0D809EA2, 0x398FEB7C, - 0x132A4F94, 0x43B7950E, 0x2FEE7D1C, 0x223613BD, 0xDD06CAA2, 0x37DF932B, - 0xC4248289, 0xACF3EBC3, 0x5715F6B7, 0xEF3478DD, 0xF267616F, 0xC148CBE4, - 0x9052815E, 0x5E410FAB, 0xB48A2465, 0x2EDA7FA4, 0xE87B40E4, 0xE98EA084, - 0x5889E9E1, 0xEFD390FC, 0xDD07D35B, 0xDB485694, 0x38D7E5B2, 0x57720101, - 0x730EDEBC, 0x5B643113, 0x94917E4F, 0x503C2FBA, 0x646F1282, 0x7523D24A, - 0xE0779695, 0xF9C17A8F, 0x7A5B2121, 0xD187B896, 0x29263A4D, 0xBA510CDF, - 0x81F47C9F, 0xAD1163ED, 0xEA7B5965, 0x1A00726E, 0x11403092, 0x00DA6D77, - 0x4A0CDD61, 0xAD1F4603, 0x605BDFB0, 0x9EEDC364, 0x22EBE6A8, 0xCEE7D28A, - 0xA0E736A0, 0x5564A6B9, 0x10853209, 0xC7EB8F37, 0x2DE705CA, 0x8951570F, - 0xDF09822B, 0xBD691A6C, 0xAA12E4F2, 0x87451C0F, 0xE0F6A27A, 0x3ADA4819, - 0x4CF1764F, 0x0D771C2B, 0x67CDB156, 0x350D8384, 0x5938FA0F, 0x42399EF3, - 0x36997B07, 0x0E84093D, 0x4AA93E61, 0x8360D87B, 0x1FA98B0C, 0x1149382C, - 0xE97625A5, 0x0614D1B7, 0x0E25244B, 0x0C768347, 0x589E8D82, 0x0D2059D1, - 0xA466BB1E, 0xF8DA0A82, 0x04F19130, 0xBA6E4EC0, 0x99265164, 0x1EE7230D, - 0x50B2AD80, 0xEAEE6801, 0x8DB2A283, 0xEA8BF59E }; - -const u32bit CAST_256::KEY_MASK[192] = { - 0x5A827999, 0xC95C653A, 0x383650DB, 0xA7103C7C, 0x15EA281D, 0x84C413BE, - 0xF39DFF5F, 0x6277EB00, 0xD151D6A1, 0x402BC242, 0xAF05ADE3, 0x1DDF9984, - 0x8CB98525, 0xFB9370C6, 0x6A6D5C67, 0xD9474808, 0x482133A9, 0xB6FB1F4A, - 0x25D50AEB, 0x94AEF68C, 0x0388E22D, 0x7262CDCE, 0xE13CB96F, 0x5016A510, - 0xBEF090B1, 0x2DCA7C52, 0x9CA467F3, 0x0B7E5394, 0x7A583F35, 0xE9322AD6, - 0x580C1677, 0xC6E60218, 0x35BFEDB9, 0xA499D95A, 0x1373C4FB, 0x824DB09C, - 0xF1279C3D, 0x600187DE, 0xCEDB737F, 0x3DB55F20, 0xAC8F4AC1, 0x1B693662, - 0x8A432203, 0xF91D0DA4, 0x67F6F945, 0xD6D0E4E6, 0x45AAD087, 0xB484BC28, - 0x235EA7C9, 0x9238936A, 0x01127F0B, 0x6FEC6AAC, 0xDEC6564D, 0x4DA041EE, - 0xBC7A2D8F, 0x2B541930, 0x9A2E04D1, 0x0907F072, 0x77E1DC13, 0xE6BBC7B4, - 0x5595B355, 0xC46F9EF6, 0x33498A97, 0xA2237638, 0x10FD61D9, 0x7FD74D7A, - 0xEEB1391B, 0x5D8B24BC, 0xCC65105D, 0x3B3EFBFE, 0xAA18E79F, 0x18F2D340, - 0x87CCBEE1, 0xF6A6AA82, 0x65809623, 0xD45A81C4, 0x43346D65, 0xB20E5906, - 0x20E844A7, 0x8FC23048, 0xFE9C1BE9, 0x6D76078A, 0xDC4FF32B, 0x4B29DECC, - 0xBA03CA6D, 0x28DDB60E, 0x97B7A1AF, 0x06918D50, 0x756B78F1, 0xE4456492, - 0x531F5033, 0xC1F93BD4, 0x30D32775, 0x9FAD1316, 0x0E86FEB7, 0x7D60EA58, - 0xEC3AD5F9, 0x5B14C19A, 0xC9EEAD3B, 0x38C898DC, 0xA7A2847D, 0x167C701E, - 0x85565BBF, 0xF4304760, 0x630A3301, 0xD1E41EA2, 0x40BE0A43, 0xAF97F5E4, - 0x1E71E185, 0x8D4BCD26, 0xFC25B8C7, 0x6AFFA468, 0xD9D99009, 0x48B37BAA, - 0xB78D674B, 0x266752EC, 0x95413E8D, 0x041B2A2E, 0x72F515CF, 0xE1CF0170, - 0x50A8ED11, 0xBF82D8B2, 0x2E5CC453, 0x9D36AFF4, 0x0C109B95, 0x7AEA8736, - 0xE9C472D7, 0x589E5E78, 0xC7784A19, 0x365235BA, 0xA52C215B, 0x14060CFC, - 0x82DFF89D, 0xF1B9E43E, 0x6093CFDF, 0xCF6DBB80, 0x3E47A721, 0xAD2192C2, - 0x1BFB7E63, 0x8AD56A04, 0xF9AF55A5, 0x68894146, 0xD7632CE7, 0x463D1888, - 0xB5170429, 0x23F0EFCA, 0x92CADB6B, 0x01A4C70C, 0x707EB2AD, 0xDF589E4E, - 0x4E3289EF, 0xBD0C7590, 0x2BE66131, 0x9AC04CD2, 0x099A3873, 0x78742414, - 0xE74E0FB5, 0x5627FB56, 0xC501E6F7, 0x33DBD298, 0xA2B5BE39, 0x118FA9DA, - 0x8069957B, 0xEF43811C, 0x5E1D6CBD, 0xCCF7585E, 0x3BD143FF, 0xAAAB2FA0, - 0x19851B41, 0x885F06E2, 0xF738F283, 0x6612DE24, 0xD4ECC9C5, 0x43C6B566, - 0xB2A0A107, 0x217A8CA8, 0x90547849, 0xFF2E63EA, 0x6E084F8B, 0xDCE23B2C, - 0x4BBC26CD, 0xBA96126E, 0x296FFE0F, 0x9849E9B0, 0x0723D551, 0x75FDC0F2, - 0xE4D7AC93, 0x53B19834, 0xC28B83D5, 0x31656F76, 0xA03F5B17, 0x0F1946B8 }; - -const byte CAST_256::KEY_ROT[32] = { - 0x13, 0x04, 0x15, 0x06, 0x17, 0x08, 0x19, 0x0A, 0x1B, 0x0C, 0x1D, 0x0E, - 0x1F, 0x10, 0x01, 0x12, 0x03, 0x14, 0x05, 0x16, 0x07, 0x18, 0x09, 0x1A, - 0x0B, 0x1C, 0x0D, 0x1E, 0x0F, 0x00, 0x11, 0x02 }; - -} -/* -* DES -* (C) 1999-2008 Jack Lloyd -* -* Based on a public domain implemenation by Phil Karn (who in turn -* credited Richard Outerbridge and Jim Gillogly) -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -namespace { - -/* -* DES Key Schedule -*/ -void des_key_schedule(u32bit round_key[32], const byte key[8]) - { - static const byte ROT[16] = { 1, 1, 2, 2, 2, 2, 2, 2, - 1, 2, 2, 2, 2, 2, 2, 1 }; - - u32bit C = ((key[7] & 0x80) << 20) | ((key[6] & 0x80) << 19) | - ((key[5] & 0x80) << 18) | ((key[4] & 0x80) << 17) | - ((key[3] & 0x80) << 16) | ((key[2] & 0x80) << 15) | - ((key[1] & 0x80) << 14) | ((key[0] & 0x80) << 13) | - ((key[7] & 0x40) << 13) | ((key[6] & 0x40) << 12) | - ((key[5] & 0x40) << 11) | ((key[4] & 0x40) << 10) | - ((key[3] & 0x40) << 9) | ((key[2] & 0x40) << 8) | - ((key[1] & 0x40) << 7) | ((key[0] & 0x40) << 6) | - ((key[7] & 0x20) << 6) | ((key[6] & 0x20) << 5) | - ((key[5] & 0x20) << 4) | ((key[4] & 0x20) << 3) | - ((key[3] & 0x20) << 2) | ((key[2] & 0x20) << 1) | - ((key[1] & 0x20) ) | ((key[0] & 0x20) >> 1) | - ((key[7] & 0x10) >> 1) | ((key[6] & 0x10) >> 2) | - ((key[5] & 0x10) >> 3) | ((key[4] & 0x10) >> 4); - u32bit D = ((key[7] & 0x02) << 26) | ((key[6] & 0x02) << 25) | - ((key[5] & 0x02) << 24) | ((key[4] & 0x02) << 23) | - ((key[3] & 0x02) << 22) | ((key[2] & 0x02) << 21) | - ((key[1] & 0x02) << 20) | ((key[0] & 0x02) << 19) | - ((key[7] & 0x04) << 17) | ((key[6] & 0x04) << 16) | - ((key[5] & 0x04) << 15) | ((key[4] & 0x04) << 14) | - ((key[3] & 0x04) << 13) | ((key[2] & 0x04) << 12) | - ((key[1] & 0x04) << 11) | ((key[0] & 0x04) << 10) | - ((key[7] & 0x08) << 8) | ((key[6] & 0x08) << 7) | - ((key[5] & 0x08) << 6) | ((key[4] & 0x08) << 5) | - ((key[3] & 0x08) << 4) | ((key[2] & 0x08) << 3) | - ((key[1] & 0x08) << 2) | ((key[0] & 0x08) << 1) | - ((key[3] & 0x10) >> 1) | ((key[2] & 0x10) >> 2) | - ((key[1] & 0x10) >> 3) | ((key[0] & 0x10) >> 4); - - for(size_t i = 0; i != 16; ++i) - { - C = ((C << ROT[i]) | (C >> (28-ROT[i]))) & 0x0FFFFFFF; - D = ((D << ROT[i]) | (D >> (28-ROT[i]))) & 0x0FFFFFFF; - round_key[2*i ] = ((C & 0x00000010) << 22) | ((C & 0x00000800) << 17) | - ((C & 0x00000020) << 16) | ((C & 0x00004004) << 15) | - ((C & 0x00000200) << 11) | ((C & 0x00020000) << 10) | - ((C & 0x01000000) >> 6) | ((C & 0x00100000) >> 4) | - ((C & 0x00010000) << 3) | ((C & 0x08000000) >> 2) | - ((C & 0x00800000) << 1) | ((D & 0x00000010) << 8) | - ((D & 0x00000002) << 7) | ((D & 0x00000001) << 2) | - ((D & 0x00000200) ) | ((D & 0x00008000) >> 2) | - ((D & 0x00000088) >> 3) | ((D & 0x00001000) >> 7) | - ((D & 0x00080000) >> 9) | ((D & 0x02020000) >> 14) | - ((D & 0x00400000) >> 21); - round_key[2*i+1] = ((C & 0x00000001) << 28) | ((C & 0x00000082) << 18) | - ((C & 0x00002000) << 14) | ((C & 0x00000100) << 10) | - ((C & 0x00001000) << 9) | ((C & 0x00040000) << 6) | - ((C & 0x02400000) << 4) | ((C & 0x00008000) << 2) | - ((C & 0x00200000) >> 1) | ((C & 0x04000000) >> 10) | - ((D & 0x00000020) << 6) | ((D & 0x00000100) ) | - ((D & 0x00000800) >> 1) | ((D & 0x00000040) >> 3) | - ((D & 0x00010000) >> 4) | ((D & 0x00000400) >> 5) | - ((D & 0x00004000) >> 10) | ((D & 0x04000000) >> 13) | - ((D & 0x00800000) >> 14) | ((D & 0x00100000) >> 18) | - ((D & 0x01000000) >> 24) | ((D & 0x08000000) >> 26); - } - } - -/* -* DES Encryption -*/ -void des_encrypt(u32bit& L, u32bit& R, - const u32bit round_key[32]) - { - for(size_t i = 0; i != 16; i += 2) - { - u32bit T0, T1; - - T0 = rotate_right(R, 4) ^ round_key[2*i]; - T1 = R ^ round_key[2*i + 1]; - - L ^= DES_SPBOX1[get_byte(0, T0)] ^ DES_SPBOX2[get_byte(0, T1)] ^ - DES_SPBOX3[get_byte(1, T0)] ^ DES_SPBOX4[get_byte(1, T1)] ^ - DES_SPBOX5[get_byte(2, T0)] ^ DES_SPBOX6[get_byte(2, T1)] ^ - DES_SPBOX7[get_byte(3, T0)] ^ DES_SPBOX8[get_byte(3, T1)]; - - T0 = rotate_right(L, 4) ^ round_key[2*i + 2]; - T1 = L ^ round_key[2*i + 3]; - - R ^= DES_SPBOX1[get_byte(0, T0)] ^ DES_SPBOX2[get_byte(0, T1)] ^ - DES_SPBOX3[get_byte(1, T0)] ^ DES_SPBOX4[get_byte(1, T1)] ^ - DES_SPBOX5[get_byte(2, T0)] ^ DES_SPBOX6[get_byte(2, T1)] ^ - DES_SPBOX7[get_byte(3, T0)] ^ DES_SPBOX8[get_byte(3, T1)]; - } - } - -/* -* DES Decryption -*/ -void des_decrypt(u32bit& L, u32bit& R, - const u32bit round_key[32]) - { - for(size_t i = 16; i != 0; i -= 2) - { - u32bit T0, T1; - - T0 = rotate_right(R, 4) ^ round_key[2*i - 2]; - T1 = R ^ round_key[2*i - 1]; - - L ^= DES_SPBOX1[get_byte(0, T0)] ^ DES_SPBOX2[get_byte(0, T1)] ^ - DES_SPBOX3[get_byte(1, T0)] ^ DES_SPBOX4[get_byte(1, T1)] ^ - DES_SPBOX5[get_byte(2, T0)] ^ DES_SPBOX6[get_byte(2, T1)] ^ - DES_SPBOX7[get_byte(3, T0)] ^ DES_SPBOX8[get_byte(3, T1)]; - - T0 = rotate_right(L, 4) ^ round_key[2*i - 4]; - T1 = L ^ round_key[2*i - 3]; - - R ^= DES_SPBOX1[get_byte(0, T0)] ^ DES_SPBOX2[get_byte(0, T1)] ^ - DES_SPBOX3[get_byte(1, T0)] ^ DES_SPBOX4[get_byte(1, T1)] ^ - DES_SPBOX5[get_byte(2, T0)] ^ DES_SPBOX6[get_byte(2, T1)] ^ - DES_SPBOX7[get_byte(3, T0)] ^ DES_SPBOX8[get_byte(3, T1)]; - } - } - -} - -/* -* DES Encryption -*/ -void DES::encrypt_n(const byte in[], byte out[], size_t blocks) const - { - for(size_t i = 0; i != blocks; ++i) - { - u64bit T = (DES_IPTAB1[in[0]] ) | (DES_IPTAB1[in[1]] << 1) | - (DES_IPTAB1[in[2]] << 2) | (DES_IPTAB1[in[3]] << 3) | - (DES_IPTAB1[in[4]] << 4) | (DES_IPTAB1[in[5]] << 5) | - (DES_IPTAB1[in[6]] << 6) | (DES_IPTAB2[in[7]] ); - - u32bit L = static_cast(T >> 32); - u32bit R = static_cast(T); - - des_encrypt(L, R, &round_key[0]); - - T = (DES_FPTAB1[get_byte(0, L)] << 5) | (DES_FPTAB1[get_byte(1, L)] << 3) | - (DES_FPTAB1[get_byte(2, L)] << 1) | (DES_FPTAB2[get_byte(3, L)] << 1) | - (DES_FPTAB1[get_byte(0, R)] << 4) | (DES_FPTAB1[get_byte(1, R)] << 2) | - (DES_FPTAB1[get_byte(2, R)] ) | (DES_FPTAB2[get_byte(3, R)] ); - T = rotate_left(T, 32); - - store_be(T, out); - - in += BLOCK_SIZE; - out += BLOCK_SIZE; - } - } - -/* -* DES Decryption -*/ -void DES::decrypt_n(const byte in[], byte out[], size_t blocks) const - { - for(size_t i = 0; i != blocks; ++i) - { - u64bit T = (DES_IPTAB1[in[0]] ) | (DES_IPTAB1[in[1]] << 1) | - (DES_IPTAB1[in[2]] << 2) | (DES_IPTAB1[in[3]] << 3) | - (DES_IPTAB1[in[4]] << 4) | (DES_IPTAB1[in[5]] << 5) | - (DES_IPTAB1[in[6]] << 6) | (DES_IPTAB2[in[7]] ); - - u32bit L = static_cast(T >> 32); - u32bit R = static_cast(T); - - des_decrypt(L, R, &round_key[0]); - - T = (DES_FPTAB1[get_byte(0, L)] << 5) | (DES_FPTAB1[get_byte(1, L)] << 3) | - (DES_FPTAB1[get_byte(2, L)] << 1) | (DES_FPTAB2[get_byte(3, L)] << 1) | - (DES_FPTAB1[get_byte(0, R)] << 4) | (DES_FPTAB1[get_byte(1, R)] << 2) | - (DES_FPTAB1[get_byte(2, R)] ) | (DES_FPTAB2[get_byte(3, R)] ); - - T = rotate_left(T, 32); - - store_be(T, out); - - in += BLOCK_SIZE; - out += BLOCK_SIZE; - } - } - -/* -* DES Key Schedule -*/ -void DES::key_schedule(const byte key[], size_t) - { - des_key_schedule(&round_key[0], key); - } - -/* -* TripleDES Encryption -*/ -void TripleDES::encrypt_n(const byte in[], byte out[], size_t blocks) const - { - for(size_t i = 0; i != blocks; ++i) - { - u64bit T = (DES_IPTAB1[in[0]] ) | (DES_IPTAB1[in[1]] << 1) | - (DES_IPTAB1[in[2]] << 2) | (DES_IPTAB1[in[3]] << 3) | - (DES_IPTAB1[in[4]] << 4) | (DES_IPTAB1[in[5]] << 5) | - (DES_IPTAB1[in[6]] << 6) | (DES_IPTAB2[in[7]] ); - - u32bit L = static_cast(T >> 32); - u32bit R = static_cast(T); - - des_encrypt(L, R, &round_key[0]); - des_decrypt(R, L, &round_key[32]); - des_encrypt(L, R, &round_key[64]); - - T = (DES_FPTAB1[get_byte(0, L)] << 5) | (DES_FPTAB1[get_byte(1, L)] << 3) | - (DES_FPTAB1[get_byte(2, L)] << 1) | (DES_FPTAB2[get_byte(3, L)] << 1) | - (DES_FPTAB1[get_byte(0, R)] << 4) | (DES_FPTAB1[get_byte(1, R)] << 2) | - (DES_FPTAB1[get_byte(2, R)] ) | (DES_FPTAB2[get_byte(3, R)] ); - - T = rotate_left(T, 32); - - store_be(T, out); - - in += BLOCK_SIZE; - out += BLOCK_SIZE; - } - } - -/* -* TripleDES Decryption -*/ -void TripleDES::decrypt_n(const byte in[], byte out[], size_t blocks) const - { - for(size_t i = 0; i != blocks; ++i) - { - u64bit T = (DES_IPTAB1[in[0]] ) | (DES_IPTAB1[in[1]] << 1) | - (DES_IPTAB1[in[2]] << 2) | (DES_IPTAB1[in[3]] << 3) | - (DES_IPTAB1[in[4]] << 4) | (DES_IPTAB1[in[5]] << 5) | - (DES_IPTAB1[in[6]] << 6) | (DES_IPTAB2[in[7]] ); - - u32bit L = static_cast(T >> 32); - u32bit R = static_cast(T); - - des_decrypt(L, R, &round_key[64]); - des_encrypt(R, L, &round_key[32]); - des_decrypt(L, R, &round_key[0]); - - T = (DES_FPTAB1[get_byte(0, L)] << 5) | (DES_FPTAB1[get_byte(1, L)] << 3) | - (DES_FPTAB1[get_byte(2, L)] << 1) | (DES_FPTAB2[get_byte(3, L)] << 1) | - (DES_FPTAB1[get_byte(0, R)] << 4) | (DES_FPTAB1[get_byte(1, R)] << 2) | - (DES_FPTAB1[get_byte(2, R)] ) | (DES_FPTAB2[get_byte(3, R)] ); - - T = rotate_left(T, 32); - - store_be(T, out); - - in += BLOCK_SIZE; - out += BLOCK_SIZE; - } - } - -/* -* TripleDES Key Schedule -*/ -void TripleDES::key_schedule(const byte key[], size_t length) - { - des_key_schedule(&round_key[0], key); - des_key_schedule(&round_key[32], key + 8); - - if(length == 24) - des_key_schedule(&round_key[64], key + 16); - else - copy_mem(&round_key[64], &round_key[0], 32); - } - -} -/* -* Substitution/Permutation Tables for DES -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -const u32bit DES_SPBOX1[256] = { - 0x01010400, 0x00000000, 0x00010000, 0x01010404, 0x01010004, 0x00010404, - 0x00000004, 0x00010000, 0x00000400, 0x01010400, 0x01010404, 0x00000400, - 0x01000404, 0x01010004, 0x01000000, 0x00000004, 0x00000404, 0x01000400, - 0x01000400, 0x00010400, 0x00010400, 0x01010000, 0x01010000, 0x01000404, - 0x00010004, 0x01000004, 0x01000004, 0x00010004, 0x00000000, 0x00000404, - 0x00010404, 0x01000000, 0x00010000, 0x01010404, 0x00000004, 0x01010000, - 0x01010400, 0x01000000, 0x01000000, 0x00000400, 0x01010004, 0x00010000, - 0x00010400, 0x01000004, 0x00000400, 0x00000004, 0x01000404, 0x00010404, - 0x01010404, 0x00010004, 0x01010000, 0x01000404, 0x01000004, 0x00000404, - 0x00010404, 0x01010400, 0x00000404, 0x01000400, 0x01000400, 0x00000000, - 0x00010004, 0x00010400, 0x00000000, 0x01010004, 0x01010400, 0x00000000, - 0x00010000, 0x01010404, 0x01010004, 0x00010404, 0x00000004, 0x00010000, - 0x00000400, 0x01010400, 0x01010404, 0x00000400, 0x01000404, 0x01010004, - 0x01000000, 0x00000004, 0x00000404, 0x01000400, 0x01000400, 0x00010400, - 0x00010400, 0x01010000, 0x01010000, 0x01000404, 0x00010004, 0x01000004, - 0x01000004, 0x00010004, 0x00000000, 0x00000404, 0x00010404, 0x01000000, - 0x00010000, 0x01010404, 0x00000004, 0x01010000, 0x01010400, 0x01000000, - 0x01000000, 0x00000400, 0x01010004, 0x00010000, 0x00010400, 0x01000004, - 0x00000400, 0x00000004, 0x01000404, 0x00010404, 0x01010404, 0x00010004, - 0x01010000, 0x01000404, 0x01000004, 0x00000404, 0x00010404, 0x01010400, - 0x00000404, 0x01000400, 0x01000400, 0x00000000, 0x00010004, 0x00010400, - 0x00000000, 0x01010004, 0x01010400, 0x00000000, 0x00010000, 0x01010404, - 0x01010004, 0x00010404, 0x00000004, 0x00010000, 0x00000400, 0x01010400, - 0x01010404, 0x00000400, 0x01000404, 0x01010004, 0x01000000, 0x00000004, - 0x00000404, 0x01000400, 0x01000400, 0x00010400, 0x00010400, 0x01010000, - 0x01010000, 0x01000404, 0x00010004, 0x01000004, 0x01000004, 0x00010004, - 0x00000000, 0x00000404, 0x00010404, 0x01000000, 0x00010000, 0x01010404, - 0x00000004, 0x01010000, 0x01010400, 0x01000000, 0x01000000, 0x00000400, - 0x01010004, 0x00010000, 0x00010400, 0x01000004, 0x00000400, 0x00000004, - 0x01000404, 0x00010404, 0x01010404, 0x00010004, 0x01010000, 0x01000404, - 0x01000004, 0x00000404, 0x00010404, 0x01010400, 0x00000404, 0x01000400, - 0x01000400, 0x00000000, 0x00010004, 0x00010400, 0x00000000, 0x01010004, - 0x01010400, 0x00000000, 0x00010000, 0x01010404, 0x01010004, 0x00010404, - 0x00000004, 0x00010000, 0x00000400, 0x01010400, 0x01010404, 0x00000400, - 0x01000404, 0x01010004, 0x01000000, 0x00000004, 0x00000404, 0x01000400, - 0x01000400, 0x00010400, 0x00010400, 0x01010000, 0x01010000, 0x01000404, - 0x00010004, 0x01000004, 0x01000004, 0x00010004, 0x00000000, 0x00000404, - 0x00010404, 0x01000000, 0x00010000, 0x01010404, 0x00000004, 0x01010000, - 0x01010400, 0x01000000, 0x01000000, 0x00000400, 0x01010004, 0x00010000, - 0x00010400, 0x01000004, 0x00000400, 0x00000004, 0x01000404, 0x00010404, - 0x01010404, 0x00010004, 0x01010000, 0x01000404, 0x01000004, 0x00000404, - 0x00010404, 0x01010400, 0x00000404, 0x01000400, 0x01000400, 0x00000000, - 0x00010004, 0x00010400, 0x00000000, 0x01010004 }; - -const u32bit DES_SPBOX2[256] = { - 0x80108020, 0x80008000, 0x00008000, 0x00108020, 0x00100000, 0x00000020, - 0x80100020, 0x80008020, 0x80000020, 0x80108020, 0x80108000, 0x80000000, - 0x80008000, 0x00100000, 0x00000020, 0x80100020, 0x00108000, 0x00100020, - 0x80008020, 0x00000000, 0x80000000, 0x00008000, 0x00108020, 0x80100000, - 0x00100020, 0x80000020, 0x00000000, 0x00108000, 0x00008020, 0x80108000, - 0x80100000, 0x00008020, 0x00000000, 0x00108020, 0x80100020, 0x00100000, - 0x80008020, 0x80100000, 0x80108000, 0x00008000, 0x80100000, 0x80008000, - 0x00000020, 0x80108020, 0x00108020, 0x00000020, 0x00008000, 0x80000000, - 0x00008020, 0x80108000, 0x00100000, 0x80000020, 0x00100020, 0x80008020, - 0x80000020, 0x00100020, 0x00108000, 0x00000000, 0x80008000, 0x00008020, - 0x80000000, 0x80100020, 0x80108020, 0x00108000, 0x80108020, 0x80008000, - 0x00008000, 0x00108020, 0x00100000, 0x00000020, 0x80100020, 0x80008020, - 0x80000020, 0x80108020, 0x80108000, 0x80000000, 0x80008000, 0x00100000, - 0x00000020, 0x80100020, 0x00108000, 0x00100020, 0x80008020, 0x00000000, - 0x80000000, 0x00008000, 0x00108020, 0x80100000, 0x00100020, 0x80000020, - 0x00000000, 0x00108000, 0x00008020, 0x80108000, 0x80100000, 0x00008020, - 0x00000000, 0x00108020, 0x80100020, 0x00100000, 0x80008020, 0x80100000, - 0x80108000, 0x00008000, 0x80100000, 0x80008000, 0x00000020, 0x80108020, - 0x00108020, 0x00000020, 0x00008000, 0x80000000, 0x00008020, 0x80108000, - 0x00100000, 0x80000020, 0x00100020, 0x80008020, 0x80000020, 0x00100020, - 0x00108000, 0x00000000, 0x80008000, 0x00008020, 0x80000000, 0x80100020, - 0x80108020, 0x00108000, 0x80108020, 0x80008000, 0x00008000, 0x00108020, - 0x00100000, 0x00000020, 0x80100020, 0x80008020, 0x80000020, 0x80108020, - 0x80108000, 0x80000000, 0x80008000, 0x00100000, 0x00000020, 0x80100020, - 0x00108000, 0x00100020, 0x80008020, 0x00000000, 0x80000000, 0x00008000, - 0x00108020, 0x80100000, 0x00100020, 0x80000020, 0x00000000, 0x00108000, - 0x00008020, 0x80108000, 0x80100000, 0x00008020, 0x00000000, 0x00108020, - 0x80100020, 0x00100000, 0x80008020, 0x80100000, 0x80108000, 0x00008000, - 0x80100000, 0x80008000, 0x00000020, 0x80108020, 0x00108020, 0x00000020, - 0x00008000, 0x80000000, 0x00008020, 0x80108000, 0x00100000, 0x80000020, - 0x00100020, 0x80008020, 0x80000020, 0x00100020, 0x00108000, 0x00000000, - 0x80008000, 0x00008020, 0x80000000, 0x80100020, 0x80108020, 0x00108000, - 0x80108020, 0x80008000, 0x00008000, 0x00108020, 0x00100000, 0x00000020, - 0x80100020, 0x80008020, 0x80000020, 0x80108020, 0x80108000, 0x80000000, - 0x80008000, 0x00100000, 0x00000020, 0x80100020, 0x00108000, 0x00100020, - 0x80008020, 0x00000000, 0x80000000, 0x00008000, 0x00108020, 0x80100000, - 0x00100020, 0x80000020, 0x00000000, 0x00108000, 0x00008020, 0x80108000, - 0x80100000, 0x00008020, 0x00000000, 0x00108020, 0x80100020, 0x00100000, - 0x80008020, 0x80100000, 0x80108000, 0x00008000, 0x80100000, 0x80008000, - 0x00000020, 0x80108020, 0x00108020, 0x00000020, 0x00008000, 0x80000000, - 0x00008020, 0x80108000, 0x00100000, 0x80000020, 0x00100020, 0x80008020, - 0x80000020, 0x00100020, 0x00108000, 0x00000000, 0x80008000, 0x00008020, - 0x80000000, 0x80100020, 0x80108020, 0x00108000 }; - -const u32bit DES_SPBOX3[256] = { - 0x00000208, 0x08020200, 0x00000000, 0x08020008, 0x08000200, 0x00000000, - 0x00020208, 0x08000200, 0x00020008, 0x08000008, 0x08000008, 0x00020000, - 0x08020208, 0x00020008, 0x08020000, 0x00000208, 0x08000000, 0x00000008, - 0x08020200, 0x00000200, 0x00020200, 0x08020000, 0x08020008, 0x00020208, - 0x08000208, 0x00020200, 0x00020000, 0x08000208, 0x00000008, 0x08020208, - 0x00000200, 0x08000000, 0x08020200, 0x08000000, 0x00020008, 0x00000208, - 0x00020000, 0x08020200, 0x08000200, 0x00000000, 0x00000200, 0x00020008, - 0x08020208, 0x08000200, 0x08000008, 0x00000200, 0x00000000, 0x08020008, - 0x08000208, 0x00020000, 0x08000000, 0x08020208, 0x00000008, 0x00020208, - 0x00020200, 0x08000008, 0x08020000, 0x08000208, 0x00000208, 0x08020000, - 0x00020208, 0x00000008, 0x08020008, 0x00020200, 0x00000208, 0x08020200, - 0x00000000, 0x08020008, 0x08000200, 0x00000000, 0x00020208, 0x08000200, - 0x00020008, 0x08000008, 0x08000008, 0x00020000, 0x08020208, 0x00020008, - 0x08020000, 0x00000208, 0x08000000, 0x00000008, 0x08020200, 0x00000200, - 0x00020200, 0x08020000, 0x08020008, 0x00020208, 0x08000208, 0x00020200, - 0x00020000, 0x08000208, 0x00000008, 0x08020208, 0x00000200, 0x08000000, - 0x08020200, 0x08000000, 0x00020008, 0x00000208, 0x00020000, 0x08020200, - 0x08000200, 0x00000000, 0x00000200, 0x00020008, 0x08020208, 0x08000200, - 0x08000008, 0x00000200, 0x00000000, 0x08020008, 0x08000208, 0x00020000, - 0x08000000, 0x08020208, 0x00000008, 0x00020208, 0x00020200, 0x08000008, - 0x08020000, 0x08000208, 0x00000208, 0x08020000, 0x00020208, 0x00000008, - 0x08020008, 0x00020200, 0x00000208, 0x08020200, 0x00000000, 0x08020008, - 0x08000200, 0x00000000, 0x00020208, 0x08000200, 0x00020008, 0x08000008, - 0x08000008, 0x00020000, 0x08020208, 0x00020008, 0x08020000, 0x00000208, - 0x08000000, 0x00000008, 0x08020200, 0x00000200, 0x00020200, 0x08020000, - 0x08020008, 0x00020208, 0x08000208, 0x00020200, 0x00020000, 0x08000208, - 0x00000008, 0x08020208, 0x00000200, 0x08000000, 0x08020200, 0x08000000, - 0x00020008, 0x00000208, 0x00020000, 0x08020200, 0x08000200, 0x00000000, - 0x00000200, 0x00020008, 0x08020208, 0x08000200, 0x08000008, 0x00000200, - 0x00000000, 0x08020008, 0x08000208, 0x00020000, 0x08000000, 0x08020208, - 0x00000008, 0x00020208, 0x00020200, 0x08000008, 0x08020000, 0x08000208, - 0x00000208, 0x08020000, 0x00020208, 0x00000008, 0x08020008, 0x00020200, - 0x00000208, 0x08020200, 0x00000000, 0x08020008, 0x08000200, 0x00000000, - 0x00020208, 0x08000200, 0x00020008, 0x08000008, 0x08000008, 0x00020000, - 0x08020208, 0x00020008, 0x08020000, 0x00000208, 0x08000000, 0x00000008, - 0x08020200, 0x00000200, 0x00020200, 0x08020000, 0x08020008, 0x00020208, - 0x08000208, 0x00020200, 0x00020000, 0x08000208, 0x00000008, 0x08020208, - 0x00000200, 0x08000000, 0x08020200, 0x08000000, 0x00020008, 0x00000208, - 0x00020000, 0x08020200, 0x08000200, 0x00000000, 0x00000200, 0x00020008, - 0x08020208, 0x08000200, 0x08000008, 0x00000200, 0x00000000, 0x08020008, - 0x08000208, 0x00020000, 0x08000000, 0x08020208, 0x00000008, 0x00020208, - 0x00020200, 0x08000008, 0x08020000, 0x08000208, 0x00000208, 0x08020000, - 0x00020208, 0x00000008, 0x08020008, 0x00020200 }; - -const u32bit DES_SPBOX4[256] = { - 0x00802001, 0x00002081, 0x00002081, 0x00000080, 0x00802080, 0x00800081, - 0x00800001, 0x00002001, 0x00000000, 0x00802000, 0x00802000, 0x00802081, - 0x00000081, 0x00000000, 0x00800080, 0x00800001, 0x00000001, 0x00002000, - 0x00800000, 0x00802001, 0x00000080, 0x00800000, 0x00002001, 0x00002080, - 0x00800081, 0x00000001, 0x00002080, 0x00800080, 0x00002000, 0x00802080, - 0x00802081, 0x00000081, 0x00800080, 0x00800001, 0x00802000, 0x00802081, - 0x00000081, 0x00000000, 0x00000000, 0x00802000, 0x00002080, 0x00800080, - 0x00800081, 0x00000001, 0x00802001, 0x00002081, 0x00002081, 0x00000080, - 0x00802081, 0x00000081, 0x00000001, 0x00002000, 0x00800001, 0x00002001, - 0x00802080, 0x00800081, 0x00002001, 0x00002080, 0x00800000, 0x00802001, - 0x00000080, 0x00800000, 0x00002000, 0x00802080, 0x00802001, 0x00002081, - 0x00002081, 0x00000080, 0x00802080, 0x00800081, 0x00800001, 0x00002001, - 0x00000000, 0x00802000, 0x00802000, 0x00802081, 0x00000081, 0x00000000, - 0x00800080, 0x00800001, 0x00000001, 0x00002000, 0x00800000, 0x00802001, - 0x00000080, 0x00800000, 0x00002001, 0x00002080, 0x00800081, 0x00000001, - 0x00002080, 0x00800080, 0x00002000, 0x00802080, 0x00802081, 0x00000081, - 0x00800080, 0x00800001, 0x00802000, 0x00802081, 0x00000081, 0x00000000, - 0x00000000, 0x00802000, 0x00002080, 0x00800080, 0x00800081, 0x00000001, - 0x00802001, 0x00002081, 0x00002081, 0x00000080, 0x00802081, 0x00000081, - 0x00000001, 0x00002000, 0x00800001, 0x00002001, 0x00802080, 0x00800081, - 0x00002001, 0x00002080, 0x00800000, 0x00802001, 0x00000080, 0x00800000, - 0x00002000, 0x00802080, 0x00802001, 0x00002081, 0x00002081, 0x00000080, - 0x00802080, 0x00800081, 0x00800001, 0x00002001, 0x00000000, 0x00802000, - 0x00802000, 0x00802081, 0x00000081, 0x00000000, 0x00800080, 0x00800001, - 0x00000001, 0x00002000, 0x00800000, 0x00802001, 0x00000080, 0x00800000, - 0x00002001, 0x00002080, 0x00800081, 0x00000001, 0x00002080, 0x00800080, - 0x00002000, 0x00802080, 0x00802081, 0x00000081, 0x00800080, 0x00800001, - 0x00802000, 0x00802081, 0x00000081, 0x00000000, 0x00000000, 0x00802000, - 0x00002080, 0x00800080, 0x00800081, 0x00000001, 0x00802001, 0x00002081, - 0x00002081, 0x00000080, 0x00802081, 0x00000081, 0x00000001, 0x00002000, - 0x00800001, 0x00002001, 0x00802080, 0x00800081, 0x00002001, 0x00002080, - 0x00800000, 0x00802001, 0x00000080, 0x00800000, 0x00002000, 0x00802080, - 0x00802001, 0x00002081, 0x00002081, 0x00000080, 0x00802080, 0x00800081, - 0x00800001, 0x00002001, 0x00000000, 0x00802000, 0x00802000, 0x00802081, - 0x00000081, 0x00000000, 0x00800080, 0x00800001, 0x00000001, 0x00002000, - 0x00800000, 0x00802001, 0x00000080, 0x00800000, 0x00002001, 0x00002080, - 0x00800081, 0x00000001, 0x00002080, 0x00800080, 0x00002000, 0x00802080, - 0x00802081, 0x00000081, 0x00800080, 0x00800001, 0x00802000, 0x00802081, - 0x00000081, 0x00000000, 0x00000000, 0x00802000, 0x00002080, 0x00800080, - 0x00800081, 0x00000001, 0x00802001, 0x00002081, 0x00002081, 0x00000080, - 0x00802081, 0x00000081, 0x00000001, 0x00002000, 0x00800001, 0x00002001, - 0x00802080, 0x00800081, 0x00002001, 0x00002080, 0x00800000, 0x00802001, - 0x00000080, 0x00800000, 0x00002000, 0x00802080 }; - -const u32bit DES_SPBOX5[256] = { - 0x00000100, 0x02080100, 0x02080000, 0x42000100, 0x00080000, 0x00000100, - 0x40000000, 0x02080000, 0x40080100, 0x00080000, 0x02000100, 0x40080100, - 0x42000100, 0x42080000, 0x00080100, 0x40000000, 0x02000000, 0x40080000, - 0x40080000, 0x00000000, 0x40000100, 0x42080100, 0x42080100, 0x02000100, - 0x42080000, 0x40000100, 0x00000000, 0x42000000, 0x02080100, 0x02000000, - 0x42000000, 0x00080100, 0x00080000, 0x42000100, 0x00000100, 0x02000000, - 0x40000000, 0x02080000, 0x42000100, 0x40080100, 0x02000100, 0x40000000, - 0x42080000, 0x02080100, 0x40080100, 0x00000100, 0x02000000, 0x42080000, - 0x42080100, 0x00080100, 0x42000000, 0x42080100, 0x02080000, 0x00000000, - 0x40080000, 0x42000000, 0x00080100, 0x02000100, 0x40000100, 0x00080000, - 0x00000000, 0x40080000, 0x02080100, 0x40000100, 0x00000100, 0x02080100, - 0x02080000, 0x42000100, 0x00080000, 0x00000100, 0x40000000, 0x02080000, - 0x40080100, 0x00080000, 0x02000100, 0x40080100, 0x42000100, 0x42080000, - 0x00080100, 0x40000000, 0x02000000, 0x40080000, 0x40080000, 0x00000000, - 0x40000100, 0x42080100, 0x42080100, 0x02000100, 0x42080000, 0x40000100, - 0x00000000, 0x42000000, 0x02080100, 0x02000000, 0x42000000, 0x00080100, - 0x00080000, 0x42000100, 0x00000100, 0x02000000, 0x40000000, 0x02080000, - 0x42000100, 0x40080100, 0x02000100, 0x40000000, 0x42080000, 0x02080100, - 0x40080100, 0x00000100, 0x02000000, 0x42080000, 0x42080100, 0x00080100, - 0x42000000, 0x42080100, 0x02080000, 0x00000000, 0x40080000, 0x42000000, - 0x00080100, 0x02000100, 0x40000100, 0x00080000, 0x00000000, 0x40080000, - 0x02080100, 0x40000100, 0x00000100, 0x02080100, 0x02080000, 0x42000100, - 0x00080000, 0x00000100, 0x40000000, 0x02080000, 0x40080100, 0x00080000, - 0x02000100, 0x40080100, 0x42000100, 0x42080000, 0x00080100, 0x40000000, - 0x02000000, 0x40080000, 0x40080000, 0x00000000, 0x40000100, 0x42080100, - 0x42080100, 0x02000100, 0x42080000, 0x40000100, 0x00000000, 0x42000000, - 0x02080100, 0x02000000, 0x42000000, 0x00080100, 0x00080000, 0x42000100, - 0x00000100, 0x02000000, 0x40000000, 0x02080000, 0x42000100, 0x40080100, - 0x02000100, 0x40000000, 0x42080000, 0x02080100, 0x40080100, 0x00000100, - 0x02000000, 0x42080000, 0x42080100, 0x00080100, 0x42000000, 0x42080100, - 0x02080000, 0x00000000, 0x40080000, 0x42000000, 0x00080100, 0x02000100, - 0x40000100, 0x00080000, 0x00000000, 0x40080000, 0x02080100, 0x40000100, - 0x00000100, 0x02080100, 0x02080000, 0x42000100, 0x00080000, 0x00000100, - 0x40000000, 0x02080000, 0x40080100, 0x00080000, 0x02000100, 0x40080100, - 0x42000100, 0x42080000, 0x00080100, 0x40000000, 0x02000000, 0x40080000, - 0x40080000, 0x00000000, 0x40000100, 0x42080100, 0x42080100, 0x02000100, - 0x42080000, 0x40000100, 0x00000000, 0x42000000, 0x02080100, 0x02000000, - 0x42000000, 0x00080100, 0x00080000, 0x42000100, 0x00000100, 0x02000000, - 0x40000000, 0x02080000, 0x42000100, 0x40080100, 0x02000100, 0x40000000, - 0x42080000, 0x02080100, 0x40080100, 0x00000100, 0x02000000, 0x42080000, - 0x42080100, 0x00080100, 0x42000000, 0x42080100, 0x02080000, 0x00000000, - 0x40080000, 0x42000000, 0x00080100, 0x02000100, 0x40000100, 0x00080000, - 0x00000000, 0x40080000, 0x02080100, 0x40000100 }; - -const u32bit DES_SPBOX6[256] = { - 0x20000010, 0x20400000, 0x00004000, 0x20404010, 0x20400000, 0x00000010, - 0x20404010, 0x00400000, 0x20004000, 0x00404010, 0x00400000, 0x20000010, - 0x00400010, 0x20004000, 0x20000000, 0x00004010, 0x00000000, 0x00400010, - 0x20004010, 0x00004000, 0x00404000, 0x20004010, 0x00000010, 0x20400010, - 0x20400010, 0x00000000, 0x00404010, 0x20404000, 0x00004010, 0x00404000, - 0x20404000, 0x20000000, 0x20004000, 0x00000010, 0x20400010, 0x00404000, - 0x20404010, 0x00400000, 0x00004010, 0x20000010, 0x00400000, 0x20004000, - 0x20000000, 0x00004010, 0x20000010, 0x20404010, 0x00404000, 0x20400000, - 0x00404010, 0x20404000, 0x00000000, 0x20400010, 0x00000010, 0x00004000, - 0x20400000, 0x00404010, 0x00004000, 0x00400010, 0x20004010, 0x00000000, - 0x20404000, 0x20000000, 0x00400010, 0x20004010, 0x20000010, 0x20400000, - 0x00004000, 0x20404010, 0x20400000, 0x00000010, 0x20404010, 0x00400000, - 0x20004000, 0x00404010, 0x00400000, 0x20000010, 0x00400010, 0x20004000, - 0x20000000, 0x00004010, 0x00000000, 0x00400010, 0x20004010, 0x00004000, - 0x00404000, 0x20004010, 0x00000010, 0x20400010, 0x20400010, 0x00000000, - 0x00404010, 0x20404000, 0x00004010, 0x00404000, 0x20404000, 0x20000000, - 0x20004000, 0x00000010, 0x20400010, 0x00404000, 0x20404010, 0x00400000, - 0x00004010, 0x20000010, 0x00400000, 0x20004000, 0x20000000, 0x00004010, - 0x20000010, 0x20404010, 0x00404000, 0x20400000, 0x00404010, 0x20404000, - 0x00000000, 0x20400010, 0x00000010, 0x00004000, 0x20400000, 0x00404010, - 0x00004000, 0x00400010, 0x20004010, 0x00000000, 0x20404000, 0x20000000, - 0x00400010, 0x20004010, 0x20000010, 0x20400000, 0x00004000, 0x20404010, - 0x20400000, 0x00000010, 0x20404010, 0x00400000, 0x20004000, 0x00404010, - 0x00400000, 0x20000010, 0x00400010, 0x20004000, 0x20000000, 0x00004010, - 0x00000000, 0x00400010, 0x20004010, 0x00004000, 0x00404000, 0x20004010, - 0x00000010, 0x20400010, 0x20400010, 0x00000000, 0x00404010, 0x20404000, - 0x00004010, 0x00404000, 0x20404000, 0x20000000, 0x20004000, 0x00000010, - 0x20400010, 0x00404000, 0x20404010, 0x00400000, 0x00004010, 0x20000010, - 0x00400000, 0x20004000, 0x20000000, 0x00004010, 0x20000010, 0x20404010, - 0x00404000, 0x20400000, 0x00404010, 0x20404000, 0x00000000, 0x20400010, - 0x00000010, 0x00004000, 0x20400000, 0x00404010, 0x00004000, 0x00400010, - 0x20004010, 0x00000000, 0x20404000, 0x20000000, 0x00400010, 0x20004010, - 0x20000010, 0x20400000, 0x00004000, 0x20404010, 0x20400000, 0x00000010, - 0x20404010, 0x00400000, 0x20004000, 0x00404010, 0x00400000, 0x20000010, - 0x00400010, 0x20004000, 0x20000000, 0x00004010, 0x00000000, 0x00400010, - 0x20004010, 0x00004000, 0x00404000, 0x20004010, 0x00000010, 0x20400010, - 0x20400010, 0x00000000, 0x00404010, 0x20404000, 0x00004010, 0x00404000, - 0x20404000, 0x20000000, 0x20004000, 0x00000010, 0x20400010, 0x00404000, - 0x20404010, 0x00400000, 0x00004010, 0x20000010, 0x00400000, 0x20004000, - 0x20000000, 0x00004010, 0x20000010, 0x20404010, 0x00404000, 0x20400000, - 0x00404010, 0x20404000, 0x00000000, 0x20400010, 0x00000010, 0x00004000, - 0x20400000, 0x00404010, 0x00004000, 0x00400010, 0x20004010, 0x00000000, - 0x20404000, 0x20000000, 0x00400010, 0x20004010 }; - -const u32bit DES_SPBOX7[256] = { - 0x00200000, 0x04200002, 0x04000802, 0x00000000, 0x00000800, 0x04000802, - 0x00200802, 0x04200800, 0x04200802, 0x00200000, 0x00000000, 0x04000002, - 0x00000002, 0x04000000, 0x04200002, 0x00000802, 0x04000800, 0x00200802, - 0x00200002, 0x04000800, 0x04000002, 0x04200000, 0x04200800, 0x00200002, - 0x04200000, 0x00000800, 0x00000802, 0x04200802, 0x00200800, 0x00000002, - 0x04000000, 0x00200800, 0x04000000, 0x00200800, 0x00200000, 0x04000802, - 0x04000802, 0x04200002, 0x04200002, 0x00000002, 0x00200002, 0x04000000, - 0x04000800, 0x00200000, 0x04200800, 0x00000802, 0x00200802, 0x04200800, - 0x00000802, 0x04000002, 0x04200802, 0x04200000, 0x00200800, 0x00000000, - 0x00000002, 0x04200802, 0x00000000, 0x00200802, 0x04200000, 0x00000800, - 0x04000002, 0x04000800, 0x00000800, 0x00200002, 0x00200000, 0x04200002, - 0x04000802, 0x00000000, 0x00000800, 0x04000802, 0x00200802, 0x04200800, - 0x04200802, 0x00200000, 0x00000000, 0x04000002, 0x00000002, 0x04000000, - 0x04200002, 0x00000802, 0x04000800, 0x00200802, 0x00200002, 0x04000800, - 0x04000002, 0x04200000, 0x04200800, 0x00200002, 0x04200000, 0x00000800, - 0x00000802, 0x04200802, 0x00200800, 0x00000002, 0x04000000, 0x00200800, - 0x04000000, 0x00200800, 0x00200000, 0x04000802, 0x04000802, 0x04200002, - 0x04200002, 0x00000002, 0x00200002, 0x04000000, 0x04000800, 0x00200000, - 0x04200800, 0x00000802, 0x00200802, 0x04200800, 0x00000802, 0x04000002, - 0x04200802, 0x04200000, 0x00200800, 0x00000000, 0x00000002, 0x04200802, - 0x00000000, 0x00200802, 0x04200000, 0x00000800, 0x04000002, 0x04000800, - 0x00000800, 0x00200002, 0x00200000, 0x04200002, 0x04000802, 0x00000000, - 0x00000800, 0x04000802, 0x00200802, 0x04200800, 0x04200802, 0x00200000, - 0x00000000, 0x04000002, 0x00000002, 0x04000000, 0x04200002, 0x00000802, - 0x04000800, 0x00200802, 0x00200002, 0x04000800, 0x04000002, 0x04200000, - 0x04200800, 0x00200002, 0x04200000, 0x00000800, 0x00000802, 0x04200802, - 0x00200800, 0x00000002, 0x04000000, 0x00200800, 0x04000000, 0x00200800, - 0x00200000, 0x04000802, 0x04000802, 0x04200002, 0x04200002, 0x00000002, - 0x00200002, 0x04000000, 0x04000800, 0x00200000, 0x04200800, 0x00000802, - 0x00200802, 0x04200800, 0x00000802, 0x04000002, 0x04200802, 0x04200000, - 0x00200800, 0x00000000, 0x00000002, 0x04200802, 0x00000000, 0x00200802, - 0x04200000, 0x00000800, 0x04000002, 0x04000800, 0x00000800, 0x00200002, - 0x00200000, 0x04200002, 0x04000802, 0x00000000, 0x00000800, 0x04000802, - 0x00200802, 0x04200800, 0x04200802, 0x00200000, 0x00000000, 0x04000002, - 0x00000002, 0x04000000, 0x04200002, 0x00000802, 0x04000800, 0x00200802, - 0x00200002, 0x04000800, 0x04000002, 0x04200000, 0x04200800, 0x00200002, - 0x04200000, 0x00000800, 0x00000802, 0x04200802, 0x00200800, 0x00000002, - 0x04000000, 0x00200800, 0x04000000, 0x00200800, 0x00200000, 0x04000802, - 0x04000802, 0x04200002, 0x04200002, 0x00000002, 0x00200002, 0x04000000, - 0x04000800, 0x00200000, 0x04200800, 0x00000802, 0x00200802, 0x04200800, - 0x00000802, 0x04000002, 0x04200802, 0x04200000, 0x00200800, 0x00000000, - 0x00000002, 0x04200802, 0x00000000, 0x00200802, 0x04200000, 0x00000800, - 0x04000002, 0x04000800, 0x00000800, 0x00200002 }; - -const u32bit DES_SPBOX8[256] = { - 0x10001040, 0x00001000, 0x00040000, 0x10041040, 0x10000000, 0x10001040, - 0x00000040, 0x10000000, 0x00040040, 0x10040000, 0x10041040, 0x00041000, - 0x10041000, 0x00041040, 0x00001000, 0x00000040, 0x10040000, 0x10000040, - 0x10001000, 0x00001040, 0x00041000, 0x00040040, 0x10040040, 0x10041000, - 0x00001040, 0x00000000, 0x00000000, 0x10040040, 0x10000040, 0x10001000, - 0x00041040, 0x00040000, 0x00041040, 0x00040000, 0x10041000, 0x00001000, - 0x00000040, 0x10040040, 0x00001000, 0x00041040, 0x10001000, 0x00000040, - 0x10000040, 0x10040000, 0x10040040, 0x10000000, 0x00040000, 0x10001040, - 0x00000000, 0x10041040, 0x00040040, 0x10000040, 0x10040000, 0x10001000, - 0x10001040, 0x00000000, 0x10041040, 0x00041000, 0x00041000, 0x00001040, - 0x00001040, 0x00040040, 0x10000000, 0x10041000, 0x10001040, 0x00001000, - 0x00040000, 0x10041040, 0x10000000, 0x10001040, 0x00000040, 0x10000000, - 0x00040040, 0x10040000, 0x10041040, 0x00041000, 0x10041000, 0x00041040, - 0x00001000, 0x00000040, 0x10040000, 0x10000040, 0x10001000, 0x00001040, - 0x00041000, 0x00040040, 0x10040040, 0x10041000, 0x00001040, 0x00000000, - 0x00000000, 0x10040040, 0x10000040, 0x10001000, 0x00041040, 0x00040000, - 0x00041040, 0x00040000, 0x10041000, 0x00001000, 0x00000040, 0x10040040, - 0x00001000, 0x00041040, 0x10001000, 0x00000040, 0x10000040, 0x10040000, - 0x10040040, 0x10000000, 0x00040000, 0x10001040, 0x00000000, 0x10041040, - 0x00040040, 0x10000040, 0x10040000, 0x10001000, 0x10001040, 0x00000000, - 0x10041040, 0x00041000, 0x00041000, 0x00001040, 0x00001040, 0x00040040, - 0x10000000, 0x10041000, 0x10001040, 0x00001000, 0x00040000, 0x10041040, - 0x10000000, 0x10001040, 0x00000040, 0x10000000, 0x00040040, 0x10040000, - 0x10041040, 0x00041000, 0x10041000, 0x00041040, 0x00001000, 0x00000040, - 0x10040000, 0x10000040, 0x10001000, 0x00001040, 0x00041000, 0x00040040, - 0x10040040, 0x10041000, 0x00001040, 0x00000000, 0x00000000, 0x10040040, - 0x10000040, 0x10001000, 0x00041040, 0x00040000, 0x00041040, 0x00040000, - 0x10041000, 0x00001000, 0x00000040, 0x10040040, 0x00001000, 0x00041040, - 0x10001000, 0x00000040, 0x10000040, 0x10040000, 0x10040040, 0x10000000, - 0x00040000, 0x10001040, 0x00000000, 0x10041040, 0x00040040, 0x10000040, - 0x10040000, 0x10001000, 0x10001040, 0x00000000, 0x10041040, 0x00041000, - 0x00041000, 0x00001040, 0x00001040, 0x00040040, 0x10000000, 0x10041000, - 0x10001040, 0x00001000, 0x00040000, 0x10041040, 0x10000000, 0x10001040, - 0x00000040, 0x10000000, 0x00040040, 0x10040000, 0x10041040, 0x00041000, - 0x10041000, 0x00041040, 0x00001000, 0x00000040, 0x10040000, 0x10000040, - 0x10001000, 0x00001040, 0x00041000, 0x00040040, 0x10040040, 0x10041000, - 0x00001040, 0x00000000, 0x00000000, 0x10040040, 0x10000040, 0x10001000, - 0x00041040, 0x00040000, 0x00041040, 0x00040000, 0x10041000, 0x00001000, - 0x00000040, 0x10040040, 0x00001000, 0x00041040, 0x10001000, 0x00000040, - 0x10000040, 0x10040000, 0x10040040, 0x10000000, 0x00040000, 0x10001040, - 0x00000000, 0x10041040, 0x00040040, 0x10000040, 0x10040000, 0x10001000, - 0x10001040, 0x00000000, 0x10041040, 0x00041000, 0x00041000, 0x00001040, - 0x00001040, 0x00040040, 0x10000000, 0x10041000 }; - -const u64bit DES_IPTAB1[256] = { -0x0000000000000000ULL, 0x0000000200000000ULL, 0x0000000000000002ULL, 0x0000000200000002ULL, -0x0000020000000000ULL, 0x0000020200000000ULL, 0x0000020000000002ULL, 0x0000020200000002ULL, -0x0000000000000200ULL, 0x0000000200000200ULL, 0x0000000000000202ULL, 0x0000000200000202ULL, -0x0000020000000200ULL, 0x0000020200000200ULL, 0x0000020000000202ULL, 0x0000020200000202ULL, -0x0002000000000000ULL, 0x0002000200000000ULL, 0x0002000000000002ULL, 0x0002000200000002ULL, -0x0002020000000000ULL, 0x0002020200000000ULL, 0x0002020000000002ULL, 0x0002020200000002ULL, -0x0002000000000200ULL, 0x0002000200000200ULL, 0x0002000000000202ULL, 0x0002000200000202ULL, -0x0002020000000200ULL, 0x0002020200000200ULL, 0x0002020000000202ULL, 0x0002020200000202ULL, -0x0000000000020000ULL, 0x0000000200020000ULL, 0x0000000000020002ULL, 0x0000000200020002ULL, -0x0000020000020000ULL, 0x0000020200020000ULL, 0x0000020000020002ULL, 0x0000020200020002ULL, -0x0000000000020200ULL, 0x0000000200020200ULL, 0x0000000000020202ULL, 0x0000000200020202ULL, -0x0000020000020200ULL, 0x0000020200020200ULL, 0x0000020000020202ULL, 0x0000020200020202ULL, -0x0002000000020000ULL, 0x0002000200020000ULL, 0x0002000000020002ULL, 0x0002000200020002ULL, -0x0002020000020000ULL, 0x0002020200020000ULL, 0x0002020000020002ULL, 0x0002020200020002ULL, -0x0002000000020200ULL, 0x0002000200020200ULL, 0x0002000000020202ULL, 0x0002000200020202ULL, -0x0002020000020200ULL, 0x0002020200020200ULL, 0x0002020000020202ULL, 0x0002020200020202ULL, -0x0200000000000000ULL, 0x0200000200000000ULL, 0x0200000000000002ULL, 0x0200000200000002ULL, -0x0200020000000000ULL, 0x0200020200000000ULL, 0x0200020000000002ULL, 0x0200020200000002ULL, -0x0200000000000200ULL, 0x0200000200000200ULL, 0x0200000000000202ULL, 0x0200000200000202ULL, -0x0200020000000200ULL, 0x0200020200000200ULL, 0x0200020000000202ULL, 0x0200020200000202ULL, -0x0202000000000000ULL, 0x0202000200000000ULL, 0x0202000000000002ULL, 0x0202000200000002ULL, -0x0202020000000000ULL, 0x0202020200000000ULL, 0x0202020000000002ULL, 0x0202020200000002ULL, -0x0202000000000200ULL, 0x0202000200000200ULL, 0x0202000000000202ULL, 0x0202000200000202ULL, -0x0202020000000200ULL, 0x0202020200000200ULL, 0x0202020000000202ULL, 0x0202020200000202ULL, -0x0200000000020000ULL, 0x0200000200020000ULL, 0x0200000000020002ULL, 0x0200000200020002ULL, -0x0200020000020000ULL, 0x0200020200020000ULL, 0x0200020000020002ULL, 0x0200020200020002ULL, -0x0200000000020200ULL, 0x0200000200020200ULL, 0x0200000000020202ULL, 0x0200000200020202ULL, -0x0200020000020200ULL, 0x0200020200020200ULL, 0x0200020000020202ULL, 0x0200020200020202ULL, -0x0202000000020000ULL, 0x0202000200020000ULL, 0x0202000000020002ULL, 0x0202000200020002ULL, -0x0202020000020000ULL, 0x0202020200020000ULL, 0x0202020000020002ULL, 0x0202020200020002ULL, -0x0202000000020200ULL, 0x0202000200020200ULL, 0x0202000000020202ULL, 0x0202000200020202ULL, -0x0202020000020200ULL, 0x0202020200020200ULL, 0x0202020000020202ULL, 0x0202020200020202ULL, -0x0000000002000000ULL, 0x0000000202000000ULL, 0x0000000002000002ULL, 0x0000000202000002ULL, -0x0000020002000000ULL, 0x0000020202000000ULL, 0x0000020002000002ULL, 0x0000020202000002ULL, -0x0000000002000200ULL, 0x0000000202000200ULL, 0x0000000002000202ULL, 0x0000000202000202ULL, -0x0000020002000200ULL, 0x0000020202000200ULL, 0x0000020002000202ULL, 0x0000020202000202ULL, -0x0002000002000000ULL, 0x0002000202000000ULL, 0x0002000002000002ULL, 0x0002000202000002ULL, -0x0002020002000000ULL, 0x0002020202000000ULL, 0x0002020002000002ULL, 0x0002020202000002ULL, -0x0002000002000200ULL, 0x0002000202000200ULL, 0x0002000002000202ULL, 0x0002000202000202ULL, -0x0002020002000200ULL, 0x0002020202000200ULL, 0x0002020002000202ULL, 0x0002020202000202ULL, -0x0000000002020000ULL, 0x0000000202020000ULL, 0x0000000002020002ULL, 0x0000000202020002ULL, -0x0000020002020000ULL, 0x0000020202020000ULL, 0x0000020002020002ULL, 0x0000020202020002ULL, -0x0000000002020200ULL, 0x0000000202020200ULL, 0x0000000002020202ULL, 0x0000000202020202ULL, -0x0000020002020200ULL, 0x0000020202020200ULL, 0x0000020002020202ULL, 0x0000020202020202ULL, -0x0002000002020000ULL, 0x0002000202020000ULL, 0x0002000002020002ULL, 0x0002000202020002ULL, -0x0002020002020000ULL, 0x0002020202020000ULL, 0x0002020002020002ULL, 0x0002020202020002ULL, -0x0002000002020200ULL, 0x0002000202020200ULL, 0x0002000002020202ULL, 0x0002000202020202ULL, -0x0002020002020200ULL, 0x0002020202020200ULL, 0x0002020002020202ULL, 0x0002020202020202ULL, -0x0200000002000000ULL, 0x0200000202000000ULL, 0x0200000002000002ULL, 0x0200000202000002ULL, -0x0200020002000000ULL, 0x0200020202000000ULL, 0x0200020002000002ULL, 0x0200020202000002ULL, -0x0200000002000200ULL, 0x0200000202000200ULL, 0x0200000002000202ULL, 0x0200000202000202ULL, -0x0200020002000200ULL, 0x0200020202000200ULL, 0x0200020002000202ULL, 0x0200020202000202ULL, -0x0202000002000000ULL, 0x0202000202000000ULL, 0x0202000002000002ULL, 0x0202000202000002ULL, -0x0202020002000000ULL, 0x0202020202000000ULL, 0x0202020002000002ULL, 0x0202020202000002ULL, -0x0202000002000200ULL, 0x0202000202000200ULL, 0x0202000002000202ULL, 0x0202000202000202ULL, -0x0202020002000200ULL, 0x0202020202000200ULL, 0x0202020002000202ULL, 0x0202020202000202ULL, -0x0200000002020000ULL, 0x0200000202020000ULL, 0x0200000002020002ULL, 0x0200000202020002ULL, -0x0200020002020000ULL, 0x0200020202020000ULL, 0x0200020002020002ULL, 0x0200020202020002ULL, -0x0200000002020200ULL, 0x0200000202020200ULL, 0x0200000002020202ULL, 0x0200000202020202ULL, -0x0200020002020200ULL, 0x0200020202020200ULL, 0x0200020002020202ULL, 0x0200020202020202ULL, -0x0202000002020000ULL, 0x0202000202020000ULL, 0x0202000002020002ULL, 0x0202000202020002ULL, -0x0202020002020000ULL, 0x0202020202020000ULL, 0x0202020002020002ULL, 0x0202020202020002ULL, -0x0202000002020200ULL, 0x0202000202020200ULL, 0x0202000002020202ULL, 0x0202000202020202ULL, -0x0202020002020200ULL, 0x0202020202020200ULL, 0x0202020002020202ULL, 0x0202020202020202ULL }; - -const u64bit DES_IPTAB2[256] = { -0x0000000000000000ULL, 0x0000010000000000ULL, 0x0000000000000100ULL, 0x0000010000000100ULL, -0x0001000000000000ULL, 0x0001010000000000ULL, 0x0001000000000100ULL, 0x0001010000000100ULL, -0x0000000000010000ULL, 0x0000010000010000ULL, 0x0000000000010100ULL, 0x0000010000010100ULL, -0x0001000000010000ULL, 0x0001010000010000ULL, 0x0001000000010100ULL, 0x0001010000010100ULL, -0x0100000000000000ULL, 0x0100010000000000ULL, 0x0100000000000100ULL, 0x0100010000000100ULL, -0x0101000000000000ULL, 0x0101010000000000ULL, 0x0101000000000100ULL, 0x0101010000000100ULL, -0x0100000000010000ULL, 0x0100010000010000ULL, 0x0100000000010100ULL, 0x0100010000010100ULL, -0x0101000000010000ULL, 0x0101010000010000ULL, 0x0101000000010100ULL, 0x0101010000010100ULL, -0x0000000001000000ULL, 0x0000010001000000ULL, 0x0000000001000100ULL, 0x0000010001000100ULL, -0x0001000001000000ULL, 0x0001010001000000ULL, 0x0001000001000100ULL, 0x0001010001000100ULL, -0x0000000001010000ULL, 0x0000010001010000ULL, 0x0000000001010100ULL, 0x0000010001010100ULL, -0x0001000001010000ULL, 0x0001010001010000ULL, 0x0001000001010100ULL, 0x0001010001010100ULL, -0x0100000001000000ULL, 0x0100010001000000ULL, 0x0100000001000100ULL, 0x0100010001000100ULL, -0x0101000001000000ULL, 0x0101010001000000ULL, 0x0101000001000100ULL, 0x0101010001000100ULL, -0x0100000001010000ULL, 0x0100010001010000ULL, 0x0100000001010100ULL, 0x0100010001010100ULL, -0x0101000001010000ULL, 0x0101010001010000ULL, 0x0101000001010100ULL, 0x0101010001010100ULL, -0x0000000100000000ULL, 0x0000010100000000ULL, 0x0000000100000100ULL, 0x0000010100000100ULL, -0x0001000100000000ULL, 0x0001010100000000ULL, 0x0001000100000100ULL, 0x0001010100000100ULL, -0x0000000100010000ULL, 0x0000010100010000ULL, 0x0000000100010100ULL, 0x0000010100010100ULL, -0x0001000100010000ULL, 0x0001010100010000ULL, 0x0001000100010100ULL, 0x0001010100010100ULL, -0x0100000100000000ULL, 0x0100010100000000ULL, 0x0100000100000100ULL, 0x0100010100000100ULL, -0x0101000100000000ULL, 0x0101010100000000ULL, 0x0101000100000100ULL, 0x0101010100000100ULL, -0x0100000100010000ULL, 0x0100010100010000ULL, 0x0100000100010100ULL, 0x0100010100010100ULL, -0x0101000100010000ULL, 0x0101010100010000ULL, 0x0101000100010100ULL, 0x0101010100010100ULL, -0x0000000101000000ULL, 0x0000010101000000ULL, 0x0000000101000100ULL, 0x0000010101000100ULL, -0x0001000101000000ULL, 0x0001010101000000ULL, 0x0001000101000100ULL, 0x0001010101000100ULL, -0x0000000101010000ULL, 0x0000010101010000ULL, 0x0000000101010100ULL, 0x0000010101010100ULL, -0x0001000101010000ULL, 0x0001010101010000ULL, 0x0001000101010100ULL, 0x0001010101010100ULL, -0x0100000101000000ULL, 0x0100010101000000ULL, 0x0100000101000100ULL, 0x0100010101000100ULL, -0x0101000101000000ULL, 0x0101010101000000ULL, 0x0101000101000100ULL, 0x0101010101000100ULL, -0x0100000101010000ULL, 0x0100010101010000ULL, 0x0100000101010100ULL, 0x0100010101010100ULL, -0x0101000101010000ULL, 0x0101010101010000ULL, 0x0101000101010100ULL, 0x0101010101010100ULL, -0x0000000000000001ULL, 0x0000010000000001ULL, 0x0000000000000101ULL, 0x0000010000000101ULL, -0x0001000000000001ULL, 0x0001010000000001ULL, 0x0001000000000101ULL, 0x0001010000000101ULL, -0x0000000000010001ULL, 0x0000010000010001ULL, 0x0000000000010101ULL, 0x0000010000010101ULL, -0x0001000000010001ULL, 0x0001010000010001ULL, 0x0001000000010101ULL, 0x0001010000010101ULL, -0x0100000000000001ULL, 0x0100010000000001ULL, 0x0100000000000101ULL, 0x0100010000000101ULL, -0x0101000000000001ULL, 0x0101010000000001ULL, 0x0101000000000101ULL, 0x0101010000000101ULL, -0x0100000000010001ULL, 0x0100010000010001ULL, 0x0100000000010101ULL, 0x0100010000010101ULL, -0x0101000000010001ULL, 0x0101010000010001ULL, 0x0101000000010101ULL, 0x0101010000010101ULL, -0x0000000001000001ULL, 0x0000010001000001ULL, 0x0000000001000101ULL, 0x0000010001000101ULL, -0x0001000001000001ULL, 0x0001010001000001ULL, 0x0001000001000101ULL, 0x0001010001000101ULL, -0x0000000001010001ULL, 0x0000010001010001ULL, 0x0000000001010101ULL, 0x0000010001010101ULL, -0x0001000001010001ULL, 0x0001010001010001ULL, 0x0001000001010101ULL, 0x0001010001010101ULL, -0x0100000001000001ULL, 0x0100010001000001ULL, 0x0100000001000101ULL, 0x0100010001000101ULL, -0x0101000001000001ULL, 0x0101010001000001ULL, 0x0101000001000101ULL, 0x0101010001000101ULL, -0x0100000001010001ULL, 0x0100010001010001ULL, 0x0100000001010101ULL, 0x0100010001010101ULL, -0x0101000001010001ULL, 0x0101010001010001ULL, 0x0101000001010101ULL, 0x0101010001010101ULL, -0x0000000100000001ULL, 0x0000010100000001ULL, 0x0000000100000101ULL, 0x0000010100000101ULL, -0x0001000100000001ULL, 0x0001010100000001ULL, 0x0001000100000101ULL, 0x0001010100000101ULL, -0x0000000100010001ULL, 0x0000010100010001ULL, 0x0000000100010101ULL, 0x0000010100010101ULL, -0x0001000100010001ULL, 0x0001010100010001ULL, 0x0001000100010101ULL, 0x0001010100010101ULL, -0x0100000100000001ULL, 0x0100010100000001ULL, 0x0100000100000101ULL, 0x0100010100000101ULL, -0x0101000100000001ULL, 0x0101010100000001ULL, 0x0101000100000101ULL, 0x0101010100000101ULL, -0x0100000100010001ULL, 0x0100010100010001ULL, 0x0100000100010101ULL, 0x0100010100010101ULL, -0x0101000100010001ULL, 0x0101010100010001ULL, 0x0101000100010101ULL, 0x0101010100010101ULL, -0x0000000101000001ULL, 0x0000010101000001ULL, 0x0000000101000101ULL, 0x0000010101000101ULL, -0x0001000101000001ULL, 0x0001010101000001ULL, 0x0001000101000101ULL, 0x0001010101000101ULL, -0x0000000101010001ULL, 0x0000010101010001ULL, 0x0000000101010101ULL, 0x0000010101010101ULL, -0x0001000101010001ULL, 0x0001010101010001ULL, 0x0001000101010101ULL, 0x0001010101010101ULL, -0x0100000101000001ULL, 0x0100010101000001ULL, 0x0100000101000101ULL, 0x0100010101000101ULL, -0x0101000101000001ULL, 0x0101010101000001ULL, 0x0101000101000101ULL, 0x0101010101000101ULL, -0x0100000101010001ULL, 0x0100010101010001ULL, 0x0100000101010101ULL, 0x0100010101010101ULL, -0x0101000101010001ULL, 0x0101010101010001ULL, 0x0101000101010101ULL, 0x0101010101010101ULL }; - -const u64bit DES_FPTAB1[256] = { -0x0000000000000000ULL, 0x0000000100000000ULL, 0x0000000004000000ULL, 0x0000000104000000ULL, -0x0000000000040000ULL, 0x0000000100040000ULL, 0x0000000004040000ULL, 0x0000000104040000ULL, -0x0000000000000400ULL, 0x0000000100000400ULL, 0x0000000004000400ULL, 0x0000000104000400ULL, -0x0000000000040400ULL, 0x0000000100040400ULL, 0x0000000004040400ULL, 0x0000000104040400ULL, -0x0000000000000004ULL, 0x0000000100000004ULL, 0x0000000004000004ULL, 0x0000000104000004ULL, -0x0000000000040004ULL, 0x0000000100040004ULL, 0x0000000004040004ULL, 0x0000000104040004ULL, -0x0000000000000404ULL, 0x0000000100000404ULL, 0x0000000004000404ULL, 0x0000000104000404ULL, -0x0000000000040404ULL, 0x0000000100040404ULL, 0x0000000004040404ULL, 0x0000000104040404ULL, -0x0400000000000000ULL, 0x0400000100000000ULL, 0x0400000004000000ULL, 0x0400000104000000ULL, -0x0400000000040000ULL, 0x0400000100040000ULL, 0x0400000004040000ULL, 0x0400000104040000ULL, -0x0400000000000400ULL, 0x0400000100000400ULL, 0x0400000004000400ULL, 0x0400000104000400ULL, -0x0400000000040400ULL, 0x0400000100040400ULL, 0x0400000004040400ULL, 0x0400000104040400ULL, -0x0400000000000004ULL, 0x0400000100000004ULL, 0x0400000004000004ULL, 0x0400000104000004ULL, -0x0400000000040004ULL, 0x0400000100040004ULL, 0x0400000004040004ULL, 0x0400000104040004ULL, -0x0400000000000404ULL, 0x0400000100000404ULL, 0x0400000004000404ULL, 0x0400000104000404ULL, -0x0400000000040404ULL, 0x0400000100040404ULL, 0x0400000004040404ULL, 0x0400000104040404ULL, -0x0004000000000000ULL, 0x0004000100000000ULL, 0x0004000004000000ULL, 0x0004000104000000ULL, -0x0004000000040000ULL, 0x0004000100040000ULL, 0x0004000004040000ULL, 0x0004000104040000ULL, -0x0004000000000400ULL, 0x0004000100000400ULL, 0x0004000004000400ULL, 0x0004000104000400ULL, -0x0004000000040400ULL, 0x0004000100040400ULL, 0x0004000004040400ULL, 0x0004000104040400ULL, -0x0004000000000004ULL, 0x0004000100000004ULL, 0x0004000004000004ULL, 0x0004000104000004ULL, -0x0004000000040004ULL, 0x0004000100040004ULL, 0x0004000004040004ULL, 0x0004000104040004ULL, -0x0004000000000404ULL, 0x0004000100000404ULL, 0x0004000004000404ULL, 0x0004000104000404ULL, -0x0004000000040404ULL, 0x0004000100040404ULL, 0x0004000004040404ULL, 0x0004000104040404ULL, -0x0404000000000000ULL, 0x0404000100000000ULL, 0x0404000004000000ULL, 0x0404000104000000ULL, -0x0404000000040000ULL, 0x0404000100040000ULL, 0x0404000004040000ULL, 0x0404000104040000ULL, -0x0404000000000400ULL, 0x0404000100000400ULL, 0x0404000004000400ULL, 0x0404000104000400ULL, -0x0404000000040400ULL, 0x0404000100040400ULL, 0x0404000004040400ULL, 0x0404000104040400ULL, -0x0404000000000004ULL, 0x0404000100000004ULL, 0x0404000004000004ULL, 0x0404000104000004ULL, -0x0404000000040004ULL, 0x0404000100040004ULL, 0x0404000004040004ULL, 0x0404000104040004ULL, -0x0404000000000404ULL, 0x0404000100000404ULL, 0x0404000004000404ULL, 0x0404000104000404ULL, -0x0404000000040404ULL, 0x0404000100040404ULL, 0x0404000004040404ULL, 0x0404000104040404ULL, -0x0000040000000000ULL, 0x0000040100000000ULL, 0x0000040004000000ULL, 0x0000040104000000ULL, -0x0000040000040000ULL, 0x0000040100040000ULL, 0x0000040004040000ULL, 0x0000040104040000ULL, -0x0000040000000400ULL, 0x0000040100000400ULL, 0x0000040004000400ULL, 0x0000040104000400ULL, -0x0000040000040400ULL, 0x0000040100040400ULL, 0x0000040004040400ULL, 0x0000040104040400ULL, -0x0000040000000004ULL, 0x0000040100000004ULL, 0x0000040004000004ULL, 0x0000040104000004ULL, -0x0000040000040004ULL, 0x0000040100040004ULL, 0x0000040004040004ULL, 0x0000040104040004ULL, -0x0000040000000404ULL, 0x0000040100000404ULL, 0x0000040004000404ULL, 0x0000040104000404ULL, -0x0000040000040404ULL, 0x0000040100040404ULL, 0x0000040004040404ULL, 0x0000040104040404ULL, -0x0400040000000000ULL, 0x0400040100000000ULL, 0x0400040004000000ULL, 0x0400040104000000ULL, -0x0400040000040000ULL, 0x0400040100040000ULL, 0x0400040004040000ULL, 0x0400040104040000ULL, -0x0400040000000400ULL, 0x0400040100000400ULL, 0x0400040004000400ULL, 0x0400040104000400ULL, -0x0400040000040400ULL, 0x0400040100040400ULL, 0x0400040004040400ULL, 0x0400040104040400ULL, -0x0400040000000004ULL, 0x0400040100000004ULL, 0x0400040004000004ULL, 0x0400040104000004ULL, -0x0400040000040004ULL, 0x0400040100040004ULL, 0x0400040004040004ULL, 0x0400040104040004ULL, -0x0400040000000404ULL, 0x0400040100000404ULL, 0x0400040004000404ULL, 0x0400040104000404ULL, -0x0400040000040404ULL, 0x0400040100040404ULL, 0x0400040004040404ULL, 0x0400040104040404ULL, -0x0004040000000000ULL, 0x0004040100000000ULL, 0x0004040004000000ULL, 0x0004040104000000ULL, -0x0004040000040000ULL, 0x0004040100040000ULL, 0x0004040004040000ULL, 0x0004040104040000ULL, -0x0004040000000400ULL, 0x0004040100000400ULL, 0x0004040004000400ULL, 0x0004040104000400ULL, -0x0004040000040400ULL, 0x0004040100040400ULL, 0x0004040004040400ULL, 0x0004040104040400ULL, -0x0004040000000004ULL, 0x0004040100000004ULL, 0x0004040004000004ULL, 0x0004040104000004ULL, -0x0004040000040004ULL, 0x0004040100040004ULL, 0x0004040004040004ULL, 0x0004040104040004ULL, -0x0004040000000404ULL, 0x0004040100000404ULL, 0x0004040004000404ULL, 0x0004040104000404ULL, -0x0004040000040404ULL, 0x0004040100040404ULL, 0x0004040004040404ULL, 0x0004040104040404ULL, -0x0404040000000000ULL, 0x0404040100000000ULL, 0x0404040004000000ULL, 0x0404040104000000ULL, -0x0404040000040000ULL, 0x0404040100040000ULL, 0x0404040004040000ULL, 0x0404040104040000ULL, -0x0404040000000400ULL, 0x0404040100000400ULL, 0x0404040004000400ULL, 0x0404040104000400ULL, -0x0404040000040400ULL, 0x0404040100040400ULL, 0x0404040004040400ULL, 0x0404040104040400ULL, -0x0404040000000004ULL, 0x0404040100000004ULL, 0x0404040004000004ULL, 0x0404040104000004ULL, -0x0404040000040004ULL, 0x0404040100040004ULL, 0x0404040004040004ULL, 0x0404040104040004ULL, -0x0404040000000404ULL, 0x0404040100000404ULL, 0x0404040004000404ULL, 0x0404040104000404ULL, -0x0404040000040404ULL, 0x0404040100040404ULL, 0x0404040004040404ULL, 0x0404040104040404ULL }; - -const u64bit DES_FPTAB2[256] = { -0x0000000000000000ULL, 0x0000004000000000ULL, 0x0000000001000000ULL, 0x0000004001000000ULL, -0x0000000000010000ULL, 0x0000004000010000ULL, 0x0000000001010000ULL, 0x0000004001010000ULL, -0x0000000000000100ULL, 0x0000004000000100ULL, 0x0000000001000100ULL, 0x0000004001000100ULL, -0x0000000000010100ULL, 0x0000004000010100ULL, 0x0000000001010100ULL, 0x0000004001010100ULL, -0x0000000000000001ULL, 0x0000004000000001ULL, 0x0000000001000001ULL, 0x0000004001000001ULL, -0x0000000000010001ULL, 0x0000004000010001ULL, 0x0000000001010001ULL, 0x0000004001010001ULL, -0x0000000000000101ULL, 0x0000004000000101ULL, 0x0000000001000101ULL, 0x0000004001000101ULL, -0x0000000000010101ULL, 0x0000004000010101ULL, 0x0000000001010101ULL, 0x0000004001010101ULL, -0x0100000000000000ULL, 0x0100004000000000ULL, 0x0100000001000000ULL, 0x0100004001000000ULL, -0x0100000000010000ULL, 0x0100004000010000ULL, 0x0100000001010000ULL, 0x0100004001010000ULL, -0x0100000000000100ULL, 0x0100004000000100ULL, 0x0100000001000100ULL, 0x0100004001000100ULL, -0x0100000000010100ULL, 0x0100004000010100ULL, 0x0100000001010100ULL, 0x0100004001010100ULL, -0x0100000000000001ULL, 0x0100004000000001ULL, 0x0100000001000001ULL, 0x0100004001000001ULL, -0x0100000000010001ULL, 0x0100004000010001ULL, 0x0100000001010001ULL, 0x0100004001010001ULL, -0x0100000000000101ULL, 0x0100004000000101ULL, 0x0100000001000101ULL, 0x0100004001000101ULL, -0x0100000000010101ULL, 0x0100004000010101ULL, 0x0100000001010101ULL, 0x0100004001010101ULL, -0x0001000000000000ULL, 0x0001004000000000ULL, 0x0001000001000000ULL, 0x0001004001000000ULL, -0x0001000000010000ULL, 0x0001004000010000ULL, 0x0001000001010000ULL, 0x0001004001010000ULL, -0x0001000000000100ULL, 0x0001004000000100ULL, 0x0001000001000100ULL, 0x0001004001000100ULL, -0x0001000000010100ULL, 0x0001004000010100ULL, 0x0001000001010100ULL, 0x0001004001010100ULL, -0x0001000000000001ULL, 0x0001004000000001ULL, 0x0001000001000001ULL, 0x0001004001000001ULL, -0x0001000000010001ULL, 0x0001004000010001ULL, 0x0001000001010001ULL, 0x0001004001010001ULL, -0x0001000000000101ULL, 0x0001004000000101ULL, 0x0001000001000101ULL, 0x0001004001000101ULL, -0x0001000000010101ULL, 0x0001004000010101ULL, 0x0001000001010101ULL, 0x0001004001010101ULL, -0x0101000000000000ULL, 0x0101004000000000ULL, 0x0101000001000000ULL, 0x0101004001000000ULL, -0x0101000000010000ULL, 0x0101004000010000ULL, 0x0101000001010000ULL, 0x0101004001010000ULL, -0x0101000000000100ULL, 0x0101004000000100ULL, 0x0101000001000100ULL, 0x0101004001000100ULL, -0x0101000000010100ULL, 0x0101004000010100ULL, 0x0101000001010100ULL, 0x0101004001010100ULL, -0x0101000000000001ULL, 0x0101004000000001ULL, 0x0101000001000001ULL, 0x0101004001000001ULL, -0x0101000000010001ULL, 0x0101004000010001ULL, 0x0101000001010001ULL, 0x0101004001010001ULL, -0x0101000000000101ULL, 0x0101004000000101ULL, 0x0101000001000101ULL, 0x0101004001000101ULL, -0x0101000000010101ULL, 0x0101004000010101ULL, 0x0101000001010101ULL, 0x0101004001010101ULL, -0x0000010000000000ULL, 0x0000014000000000ULL, 0x0000010001000000ULL, 0x0000014001000000ULL, -0x0000010000010000ULL, 0x0000014000010000ULL, 0x0000010001010000ULL, 0x0000014001010000ULL, -0x0000010000000100ULL, 0x0000014000000100ULL, 0x0000010001000100ULL, 0x0000014001000100ULL, -0x0000010000010100ULL, 0x0000014000010100ULL, 0x0000010001010100ULL, 0x0000014001010100ULL, -0x0000010000000001ULL, 0x0000014000000001ULL, 0x0000010001000001ULL, 0x0000014001000001ULL, -0x0000010000010001ULL, 0x0000014000010001ULL, 0x0000010001010001ULL, 0x0000014001010001ULL, -0x0000010000000101ULL, 0x0000014000000101ULL, 0x0000010001000101ULL, 0x0000014001000101ULL, -0x0000010000010101ULL, 0x0000014000010101ULL, 0x0000010001010101ULL, 0x0000014001010101ULL, -0x0100010000000000ULL, 0x0100014000000000ULL, 0x0100010001000000ULL, 0x0100014001000000ULL, -0x0100010000010000ULL, 0x0100014000010000ULL, 0x0100010001010000ULL, 0x0100014001010000ULL, -0x0100010000000100ULL, 0x0100014000000100ULL, 0x0100010001000100ULL, 0x0100014001000100ULL, -0x0100010000010100ULL, 0x0100014000010100ULL, 0x0100010001010100ULL, 0x0100014001010100ULL, -0x0100010000000001ULL, 0x0100014000000001ULL, 0x0100010001000001ULL, 0x0100014001000001ULL, -0x0100010000010001ULL, 0x0100014000010001ULL, 0x0100010001010001ULL, 0x0100014001010001ULL, -0x0100010000000101ULL, 0x0100014000000101ULL, 0x0100010001000101ULL, 0x0100014001000101ULL, -0x0100010000010101ULL, 0x0100014000010101ULL, 0x0100010001010101ULL, 0x0100014001010101ULL, -0x0001010000000000ULL, 0x0001014000000000ULL, 0x0001010001000000ULL, 0x0001014001000000ULL, -0x0001010000010000ULL, 0x0001014000010000ULL, 0x0001010001010000ULL, 0x0001014001010000ULL, -0x0001010000000100ULL, 0x0001014000000100ULL, 0x0001010001000100ULL, 0x0001014001000100ULL, -0x0001010000010100ULL, 0x0001014000010100ULL, 0x0001010001010100ULL, 0x0001014001010100ULL, -0x0001010000000001ULL, 0x0001014000000001ULL, 0x0001010001000001ULL, 0x0001014001000001ULL, -0x0001010000010001ULL, 0x0001014000010001ULL, 0x0001010001010001ULL, 0x0001014001010001ULL, -0x0001010000000101ULL, 0x0001014000000101ULL, 0x0001010001000101ULL, 0x0001014001000101ULL, -0x0001010000010101ULL, 0x0001014000010101ULL, 0x0001010001010101ULL, 0x0001014001010101ULL, -0x0101010000000000ULL, 0x0101014000000000ULL, 0x0101010001000000ULL, 0x0101014001000000ULL, -0x0101010000010000ULL, 0x0101014000010000ULL, 0x0101010001010000ULL, 0x0101014001010000ULL, -0x0101010000000100ULL, 0x0101014000000100ULL, 0x0101010001000100ULL, 0x0101014001000100ULL, -0x0101010000010100ULL, 0x0101014000010100ULL, 0x0101010001010100ULL, 0x0101014001010100ULL, -0x0101010000000001ULL, 0x0101014000000001ULL, 0x0101010001000001ULL, 0x0101014001000001ULL, -0x0101010000010001ULL, 0x0101014000010001ULL, 0x0101010001010001ULL, 0x0101014001010001ULL, -0x0101010000000101ULL, 0x0101014000000101ULL, 0x0101010001000101ULL, 0x0101014001000101ULL, -0x0101010000010101ULL, 0x0101014000010101ULL, 0x0101010001010101ULL, 0x0101014001010101ULL }; - -} -/* -* DES -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -/* -* DESX Encryption -*/ -void DESX::encrypt_n(const byte in[], byte out[], size_t blocks) const - { - for(size_t i = 0; i != blocks; ++i) - { - xor_buf(out, in, &K1[0], BLOCK_SIZE); - des.encrypt(out); - xor_buf(out, &K2[0], BLOCK_SIZE); - - in += BLOCK_SIZE; - out += BLOCK_SIZE; - } - } - -/* -* DESX Decryption -*/ -void DESX::decrypt_n(const byte in[], byte out[], size_t blocks) const - { - for(size_t i = 0; i != blocks; ++i) - { - xor_buf(out, in, &K2[0], BLOCK_SIZE); - des.decrypt(out); - xor_buf(out, &K1[0], BLOCK_SIZE); - - in += BLOCK_SIZE; - out += BLOCK_SIZE; - } - } - -/* -* DESX Key Schedule -*/ -void DESX::key_schedule(const byte key[], size_t) - { - K1.copy(key, 8); - des.set_key(key + 8, 8); - K2.copy(key + 16, 8); - } - -} -/* -* GOST 28147-89 -* (C) 1999-2009,2011 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -byte GOST_28147_89_Params::sbox_entry(size_t row, size_t col) const - { - byte x = sboxes[4 * col + (row / 2)]; - - return (row % 2 == 0) ? (x >> 4) : (x & 0x0F); - } - -GOST_28147_89_Params::GOST_28147_89_Params(const std::string& n) : name(n) - { - // Encoded in the packed fromat from RFC 4357 - - // GostR3411_94_TestParamSet (OID 1.2.643.2.2.31.0) - static const byte GOST_R_3411_TEST_PARAMS[64] = { - 0x4E, 0x57, 0x64, 0xD1, 0xAB, 0x8D, 0xCB, 0xBF, 0x94, 0x1A, 0x7A, - 0x4D, 0x2C, 0xD1, 0x10, 0x10, 0xD6, 0xA0, 0x57, 0x35, 0x8D, 0x38, - 0xF2, 0xF7, 0x0F, 0x49, 0xD1, 0x5A, 0xEA, 0x2F, 0x8D, 0x94, 0x62, - 0xEE, 0x43, 0x09, 0xB3, 0xF4, 0xA6, 0xA2, 0x18, 0xC6, 0x98, 0xE3, - 0xC1, 0x7C, 0xE5, 0x7E, 0x70, 0x6B, 0x09, 0x66, 0xF7, 0x02, 0x3C, - 0x8B, 0x55, 0x95, 0xBF, 0x28, 0x39, 0xB3, 0x2E, 0xCC }; - - // GostR3411-94-CryptoProParamSet (OID 1.2.643.2.2.31.1) - static const byte GOST_R_3411_CRYPTOPRO_PARAMS[64] = { - 0xA5, 0x74, 0x77, 0xD1, 0x4F, 0xFA, 0x66, 0xE3, 0x54, 0xC7, 0x42, - 0x4A, 0x60, 0xEC, 0xB4, 0x19, 0x82, 0x90, 0x9D, 0x75, 0x1D, 0x4F, - 0xC9, 0x0B, 0x3B, 0x12, 0x2F, 0x54, 0x79, 0x08, 0xA0, 0xAF, 0xD1, - 0x3E, 0x1A, 0x38, 0xC7, 0xB1, 0x81, 0xC6, 0xE6, 0x56, 0x05, 0x87, - 0x03, 0x25, 0xEB, 0xFE, 0x9C, 0x6D, 0xF8, 0x6D, 0x2E, 0xAB, 0xDE, - 0x20, 0xBA, 0x89, 0x3C, 0x92, 0xF8, 0xD3, 0x53, 0xBC }; - - if(name == "R3411_94_TestParam") - sboxes = GOST_R_3411_TEST_PARAMS; - else if(name == "R3411_CryptoPro") - sboxes = GOST_R_3411_CRYPTOPRO_PARAMS; - else - throw Invalid_Argument("GOST_28147_89_Params: Unknown " + name); - } - -/* -* GOST Constructor -*/ -GOST_28147_89::GOST_28147_89(const GOST_28147_89_Params& param) : - SBOX(1024), EK(8) - { - // Convert the parallel 4x4 sboxes into larger word-based sboxes - for(size_t i = 0; i != 4; ++i) - for(size_t j = 0; j != 256; ++j) - { - const u32bit T = (param.sbox_entry(2*i , j % 16)) | - (param.sbox_entry(2*i+1, j / 16) << 4); - SBOX[256*i+j] = rotate_left(T, (11+8*i) % 32); - } - } - -std::string GOST_28147_89::name() const - { - /* - 'Guess' the right name for the sbox on the basis of the values. - This would need to be updated if support for other sbox parameters - is added. Preferably, we would just store the string value in the - constructor, but can't break binary compat. - */ - std::string sbox_name = ""; - if(SBOX[0] == 0x00072000) - sbox_name = "R3411_94_TestParam"; - else if(SBOX[0] == 0x0002D000) - sbox_name = "R3411_CryptoPro"; - else - throw Internal_Error("GOST-28147 unrecognized sbox value"); - - return "GOST-28147-89(" + sbox_name + ")"; - } - -/* -* Two rounds of GOST -*/ -#define GOST_2ROUND(N1, N2, R1, R2) \ - do { \ - u32bit T0 = N1 + EK[R1]; \ - N2 ^= SBOX[get_byte(3, T0)] | \ - SBOX[get_byte(2, T0)+256] | \ - SBOX[get_byte(1, T0)+512] | \ - SBOX[get_byte(0, T0)+768]; \ - \ - u32bit T1 = N2 + EK[R2]; \ - N1 ^= SBOX[get_byte(3, T1)] | \ - SBOX[get_byte(2, T1)+256] | \ - SBOX[get_byte(1, T1)+512] | \ - SBOX[get_byte(0, T1)+768]; \ - } while(0) - -/* -* GOST Encryption -*/ -void GOST_28147_89::encrypt_n(const byte in[], byte out[], size_t blocks) const - { - for(size_t i = 0; i != blocks; ++i) - { - u32bit N1 = load_le(in, 0); - u32bit N2 = load_le(in, 1); - - for(size_t j = 0; j != 3; ++j) - { - GOST_2ROUND(N1, N2, 0, 1); - GOST_2ROUND(N1, N2, 2, 3); - GOST_2ROUND(N1, N2, 4, 5); - GOST_2ROUND(N1, N2, 6, 7); - } - - GOST_2ROUND(N1, N2, 7, 6); - GOST_2ROUND(N1, N2, 5, 4); - GOST_2ROUND(N1, N2, 3, 2); - GOST_2ROUND(N1, N2, 1, 0); - - store_le(out, N2, N1); - - in += BLOCK_SIZE; - out += BLOCK_SIZE; - } - } - -/* -* GOST Decryption -*/ -void GOST_28147_89::decrypt_n(const byte in[], byte out[], size_t blocks) const - { - for(size_t i = 0; i != blocks; ++i) - { - u32bit N1 = load_le(in, 0); - u32bit N2 = load_le(in, 1); - - GOST_2ROUND(N1, N2, 0, 1); - GOST_2ROUND(N1, N2, 2, 3); - GOST_2ROUND(N1, N2, 4, 5); - GOST_2ROUND(N1, N2, 6, 7); - - for(size_t j = 0; j != 3; ++j) - { - GOST_2ROUND(N1, N2, 7, 6); - GOST_2ROUND(N1, N2, 5, 4); - GOST_2ROUND(N1, N2, 3, 2); - GOST_2ROUND(N1, N2, 1, 0); - } - - store_le(out, N2, N1); - in += BLOCK_SIZE; - out += BLOCK_SIZE; - } - } - -/* -* GOST Key Schedule -*/ -void GOST_28147_89::key_schedule(const byte key[], size_t) - { - for(size_t i = 0; i != 8; ++i) - EK[i] = load_le(key, i); - } - -} -/* -* IDEA -* (C) 1999-2010 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -namespace { - -/* -* Multiplication modulo 65537 -*/ -inline u16bit mul(u16bit x, u16bit y) - { - const u32bit P = static_cast(x) * y; - - // P ? 0xFFFF : 0 - const u16bit P_mask = !P - 1; - - const u32bit P_hi = P >> 16; - const u32bit P_lo = P & 0xFFFF; - - const u16bit r_1 = (P_lo - P_hi) + (P_lo < P_hi); - const u16bit r_2 = 1 - x - y; - - return (r_1 & P_mask) | (r_2 & ~P_mask); - } - -/* -* Find multiplicative inverses modulo 65537 -* -* 65537 is prime; thus Fermat's little theorem tells us that -* x^65537 == x modulo 65537, which means -* x^(65537-2) == x^-1 modulo 65537 since -* x^(65537-2) * x == 1 mod 65537 -* -* Do the exponentiation with a basic square and multiply: all bits are -* of exponent are 1 so we always multiply -*/ -u16bit mul_inv(u16bit x) - { - u16bit y = x; - - for(size_t i = 0; i != 15; ++i) - { - y = mul(y, y); // square - y = mul(y, x); - } - - return y; - } - -/** -* IDEA is involutional, depending only on the key schedule -*/ -void idea_op(const byte in[], byte out[], size_t blocks, const u16bit K[52]) - { - const size_t BLOCK_SIZE = 8; - - for(size_t i = 0; i != blocks; ++i) - { - u16bit X1 = load_be(in, 0); - u16bit X2 = load_be(in, 1); - u16bit X3 = load_be(in, 2); - u16bit X4 = load_be(in, 3); - - for(size_t j = 0; j != 8; ++j) - { - X1 = mul(X1, K[6*j+0]); - X2 += K[6*j+1]; - X3 += K[6*j+2]; - X4 = mul(X4, K[6*j+3]); - - u16bit T0 = X3; - X3 = mul(X3 ^ X1, K[6*j+4]); - - u16bit T1 = X2; - X2 = mul((X2 ^ X4) + X3, K[6*j+5]); - X3 += X2; - - X1 ^= X2; - X4 ^= X3; - X2 ^= T0; - X3 ^= T1; - } - - X1 = mul(X1, K[48]); - X2 += K[50]; - X3 += K[49]; - X4 = mul(X4, K[51]); - - store_be(out, X1, X3, X2, X4); - - in += BLOCK_SIZE; - out += BLOCK_SIZE; - } - } - -} - -/* -* IDEA Encryption -*/ -void IDEA::encrypt_n(const byte in[], byte out[], size_t blocks) const - { - idea_op(in, out, blocks, &EK[0]); - } - -/* -* IDEA Decryption -*/ -void IDEA::decrypt_n(const byte in[], byte out[], size_t blocks) const - { - idea_op(in, out, blocks, &DK[0]); - } - -/* -* IDEA Key Schedule -*/ -void IDEA::key_schedule(const byte key[], size_t) - { - for(size_t i = 0; i != 8; ++i) - EK[i] = load_be(key, i); - - for(size_t i = 1, j = 8, offset = 0; j != 52; i %= 8, ++i, ++j) - { - EK[i+7+offset] = static_cast((EK[(i % 8) + offset] << 9) | - (EK[((i+1) % 8) + offset] >> 7)); - offset += (i == 8) ? 8 : 0; - } - - DK[51] = mul_inv(EK[3]); - DK[50] = -EK[2]; - DK[49] = -EK[1]; - DK[48] = mul_inv(EK[0]); - - for(size_t i = 1, j = 4, counter = 47; i != 8; ++i, j += 6) - { - DK[counter--] = EK[j+1]; - DK[counter--] = EK[j]; - DK[counter--] = mul_inv(EK[j+5]); - DK[counter--] = -EK[j+3]; - DK[counter--] = -EK[j+4]; - DK[counter--] = mul_inv(EK[j+2]); - } - - DK[5] = EK[47]; - DK[4] = EK[46]; - DK[3] = mul_inv(EK[51]); - DK[2] = -EK[50]; - DK[1] = -EK[49]; - DK[0] = mul_inv(EK[48]); - } - -} -/* -* KASUMI -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -namespace { - -/* -* KASUMI S-Boxes -*/ -const byte KASUMI_SBOX_S7[128] = { - 0x36, 0x32, 0x3E, 0x38, 0x16, 0x22, 0x5E, 0x60, 0x26, 0x06, 0x3F, 0x5D, - 0x02, 0x12, 0x7B, 0x21, 0x37, 0x71, 0x27, 0x72, 0x15, 0x43, 0x41, 0x0C, - 0x2F, 0x49, 0x2E, 0x1B, 0x19, 0x6F, 0x7C, 0x51, 0x35, 0x09, 0x79, 0x4F, - 0x34, 0x3C, 0x3A, 0x30, 0x65, 0x7F, 0x28, 0x78, 0x68, 0x46, 0x47, 0x2B, - 0x14, 0x7A, 0x48, 0x3D, 0x17, 0x6D, 0x0D, 0x64, 0x4D, 0x01, 0x10, 0x07, - 0x52, 0x0A, 0x69, 0x62, 0x75, 0x74, 0x4C, 0x0B, 0x59, 0x6A, 0x00, 0x7D, - 0x76, 0x63, 0x56, 0x45, 0x1E, 0x39, 0x7E, 0x57, 0x70, 0x33, 0x11, 0x05, - 0x5F, 0x0E, 0x5A, 0x54, 0x5B, 0x08, 0x23, 0x67, 0x20, 0x61, 0x1C, 0x42, - 0x66, 0x1F, 0x1A, 0x2D, 0x4B, 0x04, 0x55, 0x5C, 0x25, 0x4A, 0x50, 0x31, - 0x44, 0x1D, 0x73, 0x2C, 0x40, 0x6B, 0x6C, 0x18, 0x6E, 0x53, 0x24, 0x4E, - 0x2A, 0x13, 0x0F, 0x29, 0x58, 0x77, 0x3B, 0x03 }; - -const u16bit KASUMI_SBOX_S9[512] = { - 0x00A7, 0x00EF, 0x00A1, 0x017B, 0x0187, 0x014E, 0x0009, 0x0152, 0x0026, - 0x00E2, 0x0030, 0x0166, 0x01C4, 0x0181, 0x005A, 0x018D, 0x00B7, 0x00FD, - 0x0093, 0x014B, 0x019F, 0x0154, 0x0033, 0x016A, 0x0132, 0x01F4, 0x0106, - 0x0052, 0x00D8, 0x009F, 0x0164, 0x00B1, 0x00AF, 0x00F1, 0x01E9, 0x0025, - 0x00CE, 0x0011, 0x0000, 0x014D, 0x002C, 0x00FE, 0x017A, 0x003A, 0x008F, - 0x00DC, 0x0051, 0x0190, 0x005F, 0x0003, 0x013B, 0x00F5, 0x0036, 0x00EB, - 0x00DA, 0x0195, 0x01D8, 0x0108, 0x00AC, 0x01EE, 0x0173, 0x0122, 0x018F, - 0x004C, 0x00A5, 0x00C5, 0x018B, 0x0079, 0x0101, 0x01E0, 0x01A7, 0x00D4, - 0x00F0, 0x001C, 0x01CE, 0x00B0, 0x0196, 0x01FB, 0x0120, 0x00DF, 0x01F5, - 0x0197, 0x00F9, 0x0109, 0x0059, 0x00BA, 0x00DD, 0x01AC, 0x00A4, 0x004A, - 0x01B8, 0x00C4, 0x01CA, 0x01A5, 0x015E, 0x00A3, 0x00E8, 0x009E, 0x0086, - 0x0162, 0x000D, 0x00FA, 0x01EB, 0x008E, 0x00BF, 0x0045, 0x00C1, 0x01A9, - 0x0098, 0x00E3, 0x016E, 0x0087, 0x0158, 0x012C, 0x0114, 0x00F2, 0x01B5, - 0x0140, 0x0071, 0x0116, 0x000B, 0x00F3, 0x0057, 0x013D, 0x0024, 0x005D, - 0x01F0, 0x001B, 0x01E7, 0x01BE, 0x01E2, 0x0029, 0x0044, 0x009C, 0x01C9, - 0x0083, 0x0146, 0x0193, 0x0153, 0x0014, 0x0027, 0x0073, 0x01BA, 0x007C, - 0x01DB, 0x0180, 0x01FC, 0x0035, 0x0070, 0x00AA, 0x01DF, 0x0097, 0x007E, - 0x00A9, 0x0049, 0x010C, 0x0117, 0x0141, 0x00A8, 0x016C, 0x016B, 0x0124, - 0x002E, 0x01F3, 0x0189, 0x0147, 0x0144, 0x0018, 0x01C8, 0x010B, 0x009D, - 0x01CC, 0x01E8, 0x01AA, 0x0135, 0x00E5, 0x01B7, 0x01FA, 0x00D0, 0x010F, - 0x015D, 0x0191, 0x01B2, 0x00EC, 0x0010, 0x00D1, 0x0167, 0x0034, 0x0038, - 0x0078, 0x00C7, 0x0115, 0x01D1, 0x01A0, 0x00FC, 0x011F, 0x00F6, 0x0006, - 0x0053, 0x0131, 0x01A4, 0x0159, 0x0099, 0x01F6, 0x0041, 0x003D, 0x00F4, - 0x011A, 0x00AD, 0x00DE, 0x01A2, 0x0043, 0x0182, 0x0170, 0x0105, 0x0065, - 0x01DC, 0x0123, 0x00C3, 0x01AE, 0x0031, 0x004F, 0x00A6, 0x014A, 0x0118, - 0x017F, 0x0175, 0x0080, 0x017E, 0x0198, 0x009B, 0x01EF, 0x016F, 0x0184, - 0x0112, 0x006B, 0x01CB, 0x01A1, 0x003E, 0x01C6, 0x0084, 0x00E1, 0x00CB, - 0x013C, 0x00EA, 0x000E, 0x012D, 0x005B, 0x01F7, 0x011E, 0x01A8, 0x00D3, - 0x015B, 0x0133, 0x008C, 0x0176, 0x0023, 0x0067, 0x007D, 0x01AB, 0x0013, - 0x00D6, 0x01C5, 0x0092, 0x01F2, 0x013A, 0x01BC, 0x00E6, 0x0100, 0x0149, - 0x00C6, 0x011D, 0x0032, 0x0074, 0x004E, 0x019A, 0x000A, 0x00CD, 0x01FE, - 0x00AB, 0x00E7, 0x002D, 0x008B, 0x01D3, 0x001D, 0x0056, 0x01F9, 0x0020, - 0x0048, 0x001A, 0x0156, 0x0096, 0x0139, 0x01EA, 0x01AF, 0x00EE, 0x019B, - 0x0145, 0x0095, 0x01D9, 0x0028, 0x0077, 0x00AE, 0x0163, 0x00B9, 0x00E9, - 0x0185, 0x0047, 0x01C0, 0x0111, 0x0174, 0x0037, 0x006E, 0x00B2, 0x0142, - 0x000C, 0x01D5, 0x0188, 0x0171, 0x00BE, 0x0001, 0x006D, 0x0177, 0x0089, - 0x00B5, 0x0058, 0x004B, 0x0134, 0x0104, 0x01E4, 0x0062, 0x0110, 0x0172, - 0x0113, 0x019C, 0x006F, 0x0150, 0x013E, 0x0004, 0x01F8, 0x01EC, 0x0103, - 0x0130, 0x004D, 0x0151, 0x01B3, 0x0015, 0x0165, 0x012F, 0x014C, 0x01E3, - 0x0012, 0x002F, 0x0055, 0x0019, 0x01F1, 0x01DA, 0x0121, 0x0064, 0x010D, - 0x0128, 0x01DE, 0x010E, 0x006A, 0x001F, 0x0068, 0x01B1, 0x0054, 0x019E, - 0x01E6, 0x018A, 0x0060, 0x0063, 0x009A, 0x01FF, 0x0094, 0x019D, 0x0169, - 0x0199, 0x00FF, 0x00A2, 0x00D7, 0x012E, 0x00C9, 0x010A, 0x015F, 0x0157, - 0x0090, 0x01B9, 0x016D, 0x006C, 0x012A, 0x00FB, 0x0022, 0x00B6, 0x01FD, - 0x008A, 0x00D2, 0x014F, 0x0085, 0x0137, 0x0160, 0x0148, 0x008D, 0x018C, - 0x015A, 0x007B, 0x013F, 0x01C2, 0x0119, 0x01AD, 0x00E4, 0x01BB, 0x01E1, - 0x005C, 0x0194, 0x01E5, 0x01A6, 0x00F8, 0x0129, 0x0017, 0x00D5, 0x0082, - 0x01D2, 0x0016, 0x00D9, 0x011B, 0x0046, 0x0126, 0x0168, 0x01A3, 0x007F, - 0x0138, 0x0179, 0x0007, 0x01D4, 0x00C2, 0x0002, 0x0075, 0x0127, 0x01CF, - 0x0102, 0x00E0, 0x01BF, 0x00F7, 0x00BB, 0x0050, 0x018E, 0x011C, 0x0161, - 0x0069, 0x0186, 0x012B, 0x01D7, 0x01D6, 0x00B8, 0x0039, 0x00C8, 0x015C, - 0x003F, 0x00CC, 0x00BC, 0x0021, 0x01C3, 0x0061, 0x001E, 0x0136, 0x00DB, - 0x005E, 0x00A0, 0x0081, 0x01ED, 0x0040, 0x00B3, 0x0107, 0x0066, 0x00BD, - 0x00CF, 0x0072, 0x0192, 0x01B6, 0x01DD, 0x0183, 0x007A, 0x00C0, 0x002A, - 0x017D, 0x0005, 0x0091, 0x0076, 0x00B4, 0x01C1, 0x0125, 0x0143, 0x0088, - 0x017C, 0x002B, 0x0042, 0x003C, 0x01C7, 0x0155, 0x01BD, 0x00CA, 0x01B0, - 0x0008, 0x00ED, 0x000F, 0x0178, 0x01B4, 0x01D0, 0x003B, 0x01CD }; - -/* -* KASUMI FI Function -*/ -u16bit FI(u16bit I, u16bit K) - { - u16bit D9 = (I >> 7); - byte D7 = (I & 0x7F); - D9 = KASUMI_SBOX_S9[D9] ^ D7; - D7 = KASUMI_SBOX_S7[D7] ^ (D9 & 0x7F); - - D7 ^= (K >> 9); - D9 = KASUMI_SBOX_S9[D9 ^ (K & 0x1FF)] ^ D7; - D7 = KASUMI_SBOX_S7[D7] ^ (D9 & 0x7F); - return (D7 << 9) | D9; - } - -} - -/* -* KASUMI Encryption -*/ -void KASUMI::encrypt_n(const byte in[], byte out[], size_t blocks) const - { - for(size_t i = 0; i != blocks; ++i) - { - u16bit B0 = load_be(in, 0); - u16bit B1 = load_be(in, 1); - u16bit B2 = load_be(in, 2); - u16bit B3 = load_be(in, 3); - - for(size_t j = 0; j != 8; j += 2) - { - const u16bit* K = &EK[8*j]; - - u16bit R = B1 ^ (rotate_left(B0, 1) & K[0]); - u16bit L = B0 ^ (rotate_left(R, 1) | K[1]); - - L = FI(L ^ K[ 2], K[ 3]) ^ R; - R = FI(R ^ K[ 4], K[ 5]) ^ L; - L = FI(L ^ K[ 6], K[ 7]) ^ R; - - R = B2 ^= R; - L = B3 ^= L; - - R = FI(R ^ K[10], K[11]) ^ L; - L = FI(L ^ K[12], K[13]) ^ R; - R = FI(R ^ K[14], K[15]) ^ L; - - R ^= (rotate_left(L, 1) & K[8]); - L ^= (rotate_left(R, 1) | K[9]); - - B0 ^= L; - B1 ^= R; - } - - store_be(out, B0, B1, B2, B3); - - in += BLOCK_SIZE; - out += BLOCK_SIZE; - } - } - -/* -* KASUMI Decryption -*/ -void KASUMI::decrypt_n(const byte in[], byte out[], size_t blocks) const - { - for(size_t i = 0; i != blocks; ++i) - { - u16bit B0 = load_be(in, 0); - u16bit B1 = load_be(in, 1); - u16bit B2 = load_be(in, 2); - u16bit B3 = load_be(in, 3); - - for(size_t j = 0; j != 8; j += 2) - { - const u16bit* K = &EK[8*(6-j)]; - - u16bit L = B2, R = B3; - - L = FI(L ^ K[10], K[11]) ^ R; - R = FI(R ^ K[12], K[13]) ^ L; - L = FI(L ^ K[14], K[15]) ^ R; - - L ^= (rotate_left(R, 1) & K[8]); - R ^= (rotate_left(L, 1) | K[9]); - - R = B0 ^= R; - L = B1 ^= L; - - L ^= (rotate_left(R, 1) & K[0]); - R ^= (rotate_left(L, 1) | K[1]); - - R = FI(R ^ K[2], K[3]) ^ L; - L = FI(L ^ K[4], K[5]) ^ R; - R = FI(R ^ K[6], K[7]) ^ L; - - B2 ^= L; - B3 ^= R; - } - - store_be(out, B0, B1, B2, B3); - - in += BLOCK_SIZE; - out += BLOCK_SIZE; - } - } - -/* -* KASUMI Key Schedule -*/ -void KASUMI::key_schedule(const byte key[], size_t) - { - static const u16bit RC[] = { 0x0123, 0x4567, 0x89AB, 0xCDEF, - 0xFEDC, 0xBA98, 0x7654, 0x3210 }; - - SecureVector K(16); - for(size_t i = 0; i != 8; ++i) - { - K[i] = load_be(key, i); - K[i+8] = K[i] ^ RC[i]; - } - - for(size_t i = 0; i != 8; ++i) - { - EK[8*i ] = rotate_left(K[(i+0) % 8 ], 2); - EK[8*i+1] = rotate_left(K[(i+2) % 8 + 8], 1); - EK[8*i+2] = rotate_left(K[(i+1) % 8 ], 5); - EK[8*i+3] = K[(i+4) % 8 + 8]; - EK[8*i+4] = rotate_left(K[(i+5) % 8 ], 8); - EK[8*i+5] = K[(i+3) % 8 + 8]; - EK[8*i+6] = rotate_left(K[(i+6) % 8 ], 13); - EK[8*i+7] = K[(i+7) % 8 + 8]; - } - } - -} -/* -* Lion -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -/* -* Lion Encryption -*/ -void Lion::encrypt_n(const byte in[], byte out[], size_t blocks) const - { - SecureVector buffer_vec(LEFT_SIZE); - byte* buffer = &buffer_vec[0]; - - for(size_t i = 0; i != blocks; ++i) - { - xor_buf(buffer, in, &key1[0], LEFT_SIZE); - cipher->set_key(buffer, LEFT_SIZE); - cipher->cipher(in + LEFT_SIZE, out + LEFT_SIZE, RIGHT_SIZE); - - hash->update(out + LEFT_SIZE, RIGHT_SIZE); - hash->final(buffer); - xor_buf(out, in, buffer, LEFT_SIZE); - - xor_buf(buffer, out, &key2[0], LEFT_SIZE); - cipher->set_key(buffer, LEFT_SIZE); - cipher->cipher1(out + LEFT_SIZE, RIGHT_SIZE); - - in += BLOCK_SIZE; - out += BLOCK_SIZE; - } - } - -/* -* Lion Decryption -*/ -void Lion::decrypt_n(const byte in[], byte out[], size_t blocks) const - { - SecureVector buffer_vec(LEFT_SIZE); - byte* buffer = &buffer_vec[0]; - - for(size_t i = 0; i != blocks; ++i) - { - xor_buf(buffer, in, &key2[0], LEFT_SIZE); - cipher->set_key(buffer, LEFT_SIZE); - cipher->cipher(in + LEFT_SIZE, out + LEFT_SIZE, RIGHT_SIZE); - - hash->update(out + LEFT_SIZE, RIGHT_SIZE); - hash->final(buffer); - xor_buf(out, in, buffer, LEFT_SIZE); - - xor_buf(buffer, out, &key1[0], LEFT_SIZE); - cipher->set_key(buffer, LEFT_SIZE); - cipher->cipher1(out + LEFT_SIZE, RIGHT_SIZE); - - in += BLOCK_SIZE; - out += BLOCK_SIZE; - } - } - -/* -* Lion Key Schedule -*/ -void Lion::key_schedule(const byte key[], size_t length) - { - clear(); - - key1.copy(key, length / 2); - key2.copy(key + length / 2, length / 2); - } - -/* -* Return the name of this type -*/ -std::string Lion::name() const - { - return "Lion(" + hash->name() + "," + - cipher->name() + "," + - to_string(BLOCK_SIZE) + ")"; - } - -/* -* Return a clone of this object -*/ -BlockCipher* Lion::clone() const - { - return new Lion(hash->clone(), cipher->clone(), BLOCK_SIZE); - } - -/* -* Clear memory of sensitive data -*/ -void Lion::clear() - { - hash->clear(); - cipher->clear(); - zeroise(key1); - zeroise(key2); - } - -/* -* Lion Constructor -*/ -Lion::Lion(HashFunction* hash_in, StreamCipher* sc_in, size_t block_len) : - BLOCK_SIZE(std::max(2*hash_in->output_length() + 1, block_len)), - LEFT_SIZE(hash_in->output_length()), - RIGHT_SIZE(BLOCK_SIZE - LEFT_SIZE), - hash(hash_in), - cipher(sc_in) - { - if(2*LEFT_SIZE + 1 > BLOCK_SIZE) - throw Invalid_Argument(name() + ": Chosen block size is too small"); - - if(!cipher->valid_keylength(LEFT_SIZE)) - throw Invalid_Argument(name() + ": This stream/hash combo is invalid"); - - key1.resize(LEFT_SIZE); - key2.resize(LEFT_SIZE); - } - -} -/* -* Luby-Rackoff -* (C) 1999-2008 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -/* -* Luby-Rackoff Encryption -*/ -void LubyRackoff::encrypt_n(const byte in[], byte out[], size_t blocks) const - { - const size_t len = hash->output_length(); - - SecureVector buffer_vec(len); - byte* buffer = &buffer_vec[0]; - - for(size_t i = 0; i != blocks; ++i) - { - hash->update(K1); - hash->update(in, len); - hash->final(buffer); - xor_buf(out + len, in + len, buffer, len); - - hash->update(K2); - hash->update(out + len, len); - hash->final(buffer); - xor_buf(out, in, buffer, len); - - hash->update(K1); - hash->update(out, len); - hash->final(buffer); - xor_buf(out + len, buffer, len); - - hash->update(K2); - hash->update(out + len, len); - hash->final(buffer); - xor_buf(out, buffer, len); - - in += 2 * len; - out += 2 * len; - } - } - -/* -* Luby-Rackoff Decryption -*/ -void LubyRackoff::decrypt_n(const byte in[], byte out[], size_t blocks) const - { - const size_t len = hash->output_length(); - - SecureVector buffer_vec(len); - byte* buffer = &buffer_vec[0]; - - for(size_t i = 0; i != blocks; ++i) - { - hash->update(K2); - hash->update(in + len, len); - hash->final(buffer); - xor_buf(out, in, buffer, len); - - hash->update(K1); - hash->update(out, len); - hash->final(buffer); - xor_buf(out + len, in + len, buffer, len); - - hash->update(K2); - hash->update(out + len, len); - hash->final(buffer); - xor_buf(out, buffer, len); - - hash->update(K1); - hash->update(out, len); - hash->final(buffer); - xor_buf(out + len, buffer, len); - - in += 2 * len; - out += 2 * len; - } - } - -/* -* Luby-Rackoff Key Schedule -*/ -void LubyRackoff::key_schedule(const byte key[], size_t length) - { - K1.resize(length / 2); - K2.resize(length / 2); - copy_mem(&K1[0], key , length / 2); - copy_mem(&K2[0], key + length / 2, length / 2); - } - -/* -* Clear memory of sensitive data -*/ -void LubyRackoff::clear() - { - zeroise(K1); - zeroise(K2); - hash->clear(); - } - -/* -* Return a clone of this object -*/ -BlockCipher* LubyRackoff::clone() const - { - return new LubyRackoff(hash->clone()); - } - -/* -* Return the name of this type -*/ -std::string LubyRackoff::name() const - { - return "Luby-Rackoff(" + hash->name() + ")"; - } - -/* -* Luby-Rackoff Constructor -*/ -LubyRackoff::LubyRackoff(HashFunction* h) : hash(h) - { - } - -} -/* -* MARS -* (C) 1999-2009 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -namespace { - -/** -* The MARS sbox -*/ -const u32bit SBOX[512] = { - 0x09D0C479, 0x28C8FFE0, 0x84AA6C39, 0x9DAD7287, 0x7DFF9BE3, 0xD4268361, - 0xC96DA1D4, 0x7974CC93, 0x85D0582E, 0x2A4B5705, 0x1CA16A62, 0xC3BD279D, - 0x0F1F25E5, 0x5160372F, 0xC695C1FB, 0x4D7FF1E4, 0xAE5F6BF4, 0x0D72EE46, - 0xFF23DE8A, 0xB1CF8E83, 0xF14902E2, 0x3E981E42, 0x8BF53EB6, 0x7F4BF8AC, - 0x83631F83, 0x25970205, 0x76AFE784, 0x3A7931D4, 0x4F846450, 0x5C64C3F6, - 0x210A5F18, 0xC6986A26, 0x28F4E826, 0x3A60A81C, 0xD340A664, 0x7EA820C4, - 0x526687C5, 0x7EDDD12B, 0x32A11D1D, 0x9C9EF086, 0x80F6E831, 0xAB6F04AD, - 0x56FB9B53, 0x8B2E095C, 0xB68556AE, 0xD2250B0D, 0x294A7721, 0xE21FB253, - 0xAE136749, 0xE82AAE86, 0x93365104, 0x99404A66, 0x78A784DC, 0xB69BA84B, - 0x04046793, 0x23DB5C1E, 0x46CAE1D6, 0x2FE28134, 0x5A223942, 0x1863CD5B, - 0xC190C6E3, 0x07DFB846, 0x6EB88816, 0x2D0DCC4A, 0xA4CCAE59, 0x3798670D, - 0xCBFA9493, 0x4F481D45, 0xEAFC8CA8, 0xDB1129D6, 0xB0449E20, 0x0F5407FB, - 0x6167D9A8, 0xD1F45763, 0x4DAA96C3, 0x3BEC5958, 0xABABA014, 0xB6CCD201, - 0x38D6279F, 0x02682215, 0x8F376CD5, 0x092C237E, 0xBFC56593, 0x32889D2C, - 0x854B3E95, 0x05BB9B43, 0x7DCD5DCD, 0xA02E926C, 0xFAE527E5, 0x36A1C330, - 0x3412E1AE, 0xF257F462, 0x3C4F1D71, 0x30A2E809, 0x68E5F551, 0x9C61BA44, - 0x5DED0AB8, 0x75CE09C8, 0x9654F93E, 0x698C0CCA, 0x243CB3E4, 0x2B062B97, - 0x0F3B8D9E, 0x00E050DF, 0xFC5D6166, 0xE35F9288, 0xC079550D, 0x0591AEE8, - 0x8E531E74, 0x75FE3578, 0x2F6D829A, 0xF60B21AE, 0x95E8EB8D, 0x6699486B, - 0x901D7D9B, 0xFD6D6E31, 0x1090ACEF, 0xE0670DD8, 0xDAB2E692, 0xCD6D4365, - 0xE5393514, 0x3AF345F0, 0x6241FC4D, 0x460DA3A3, 0x7BCF3729, 0x8BF1D1E0, - 0x14AAC070, 0x1587ED55, 0x3AFD7D3E, 0xD2F29E01, 0x29A9D1F6, 0xEFB10C53, - 0xCF3B870F, 0xB414935C, 0x664465ED, 0x024ACAC7, 0x59A744C1, 0x1D2936A7, - 0xDC580AA6, 0xCF574CA8, 0x040A7A10, 0x6CD81807, 0x8A98BE4C, 0xACCEA063, - 0xC33E92B5, 0xD1E0E03D, 0xB322517E, 0x2092BD13, 0x386B2C4A, 0x52E8DD58, - 0x58656DFB, 0x50820371, 0x41811896, 0xE337EF7E, 0xD39FB119, 0xC97F0DF6, - 0x68FEA01B, 0xA150A6E5, 0x55258962, 0xEB6FF41B, 0xD7C9CD7A, 0xA619CD9E, - 0xBCF09576, 0x2672C073, 0xF003FB3C, 0x4AB7A50B, 0x1484126A, 0x487BA9B1, - 0xA64FC9C6, 0xF6957D49, 0x38B06A75, 0xDD805FCD, 0x63D094CF, 0xF51C999E, - 0x1AA4D343, 0xB8495294, 0xCE9F8E99, 0xBFFCD770, 0xC7C275CC, 0x378453A7, - 0x7B21BE33, 0x397F41BD, 0x4E94D131, 0x92CC1F98, 0x5915EA51, 0x99F861B7, - 0xC9980A88, 0x1D74FD5F, 0xB0A495F8, 0x614DEED0, 0xB5778EEA, 0x5941792D, - 0xFA90C1F8, 0x33F824B4, 0xC4965372, 0x3FF6D550, 0x4CA5FEC0, 0x8630E964, - 0x5B3FBBD6, 0x7DA26A48, 0xB203231A, 0x04297514, 0x2D639306, 0x2EB13149, - 0x16A45272, 0x532459A0, 0x8E5F4872, 0xF966C7D9, 0x07128DC0, 0x0D44DB62, - 0xAFC8D52D, 0x06316131, 0xD838E7CE, 0x1BC41D00, 0x3A2E8C0F, 0xEA83837E, - 0xB984737D, 0x13BA4891, 0xC4F8B949, 0xA6D6ACB3, 0xA215CDCE, 0x8359838B, - 0x6BD1AA31, 0xF579DD52, 0x21B93F93, 0xF5176781, 0x187DFDDE, 0xE94AEB76, - 0x2B38FD54, 0x431DE1DA, 0xAB394825, 0x9AD3048F, 0xDFEA32AA, 0x659473E3, - 0x623F7863, 0xF3346C59, 0xAB3AB685, 0x3346A90B, 0x6B56443E, 0xC6DE01F8, - 0x8D421FC0, 0x9B0ED10C, 0x88F1A1E9, 0x54C1F029, 0x7DEAD57B, 0x8D7BA426, - 0x4CF5178A, 0x551A7CCA, 0x1A9A5F08, 0xFCD651B9, 0x25605182, 0xE11FC6C3, - 0xB6FD9676, 0x337B3027, 0xB7C8EB14, 0x9E5FD030, 0x6B57E354, 0xAD913CF7, - 0x7E16688D, 0x58872A69, 0x2C2FC7DF, 0xE389CCC6, 0x30738DF1, 0x0824A734, - 0xE1797A8B, 0xA4A8D57B, 0x5B5D193B, 0xC8A8309B, 0x73F9A978, 0x73398D32, - 0x0F59573E, 0xE9DF2B03, 0xE8A5B6C8, 0x848D0704, 0x98DF93C2, 0x720A1DC3, - 0x684F259A, 0x943BA848, 0xA6370152, 0x863B5EA3, 0xD17B978B, 0x6D9B58EF, - 0x0A700DD4, 0xA73D36BF, 0x8E6A0829, 0x8695BC14, 0xE35B3447, 0x933AC568, - 0x8894B022, 0x2F511C27, 0xDDFBCC3C, 0x006662B6, 0x117C83FE, 0x4E12B414, - 0xC2BCA766, 0x3A2FEC10, 0xF4562420, 0x55792E2A, 0x46F5D857, 0xCEDA25CE, - 0xC3601D3B, 0x6C00AB46, 0xEFAC9C28, 0xB3C35047, 0x611DFEE3, 0x257C3207, - 0xFDD58482, 0x3B14D84F, 0x23BECB64, 0xA075F3A3, 0x088F8EAD, 0x07ADF158, - 0x7796943C, 0xFACABF3D, 0xC09730CD, 0xF7679969, 0xDA44E9ED, 0x2C854C12, - 0x35935FA3, 0x2F057D9F, 0x690624F8, 0x1CB0BAFD, 0x7B0DBDC6, 0x810F23BB, - 0xFA929A1A, 0x6D969A17, 0x6742979B, 0x74AC7D05, 0x010E65C4, 0x86A3D963, - 0xF907B5A0, 0xD0042BD3, 0x158D7D03, 0x287A8255, 0xBBA8366F, 0x096EDC33, - 0x21916A7B, 0x77B56B86, 0x951622F9, 0xA6C5E650, 0x8CEA17D1, 0xCD8C62BC, - 0xA3D63433, 0x358A68FD, 0x0F9B9D3C, 0xD6AA295B, 0xFE33384A, 0xC000738E, - 0xCD67EB2F, 0xE2EB6DC2, 0x97338B02, 0x06C9F246, 0x419CF1AD, 0x2B83C045, - 0x3723F18A, 0xCB5B3089, 0x160BEAD7, 0x5D494656, 0x35F8A74B, 0x1E4E6C9E, - 0x000399BD, 0x67466880, 0xB4174831, 0xACF423B2, 0xCA815AB3, 0x5A6395E7, - 0x302A67C5, 0x8BDB446B, 0x108F8FA4, 0x10223EDA, 0x92B8B48B, 0x7F38D0EE, - 0xAB2701D4, 0x0262D415, 0xAF224A30, 0xB3D88ABA, 0xF8B2C3AF, 0xDAF7EF70, - 0xCC97D3B7, 0xE9614B6C, 0x2BAEBFF4, 0x70F687CF, 0x386C9156, 0xCE092EE5, - 0x01E87DA6, 0x6CE91E6A, 0xBB7BCC84, 0xC7922C20, 0x9D3B71FD, 0x060E41C6, - 0xD7590F15, 0x4E03BB47, 0x183C198E, 0x63EEB240, 0x2DDBF49A, 0x6D5CBA54, - 0x923750AF, 0xF9E14236, 0x7838162B, 0x59726C72, 0x81B66760, 0xBB2926C1, - 0x48A0CE0D, 0xA6C0496D, 0xAD43507B, 0x718D496A, 0x9DF057AF, 0x44B1BDE6, - 0x054356DC, 0xDE7CED35, 0xD51A138B, 0x62088CC9, 0x35830311, 0xC96EFCA2, - 0x686F86EC, 0x8E77CB68, 0x63E1D6B8, 0xC80F9778, 0x79C491FD, 0x1B4C67F2, - 0x72698D7D, 0x5E368C31, 0xF7D95E2E, 0xA1D3493F, 0xDCD9433E, 0x896F1552, - 0x4BC4CA7A, 0xA6D1BAF4, 0xA5A96DCC, 0x0BEF8B46, 0xA169FDA7, 0x74DF40B7, - 0x4E208804, 0x9A756607, 0x038E87C8, 0x20211E44, 0x8B7AD4BF, 0xC6403F35, - 0x1848E36D, 0x80BDB038, 0x1E62891C, 0x643D2107, 0xBF04D6F8, 0x21092C8C, - 0xF644F389, 0x0778404E, 0x7B78ADB8, 0xA2C52D53, 0x42157ABE, 0xA2253E2E, - 0x7BF3F4AE, 0x80F594F9, 0x953194E7, 0x77EB92ED, 0xB3816930, 0xDA8D9336, - 0xBF447469, 0xF26D9483, 0xEE6FAED5, 0x71371235, 0xDE425F73, 0xB4E59F43, - 0x7DBE2D4E, 0x2D37B185, 0x49DC9A63, 0x98C39D98, 0x1301C9A2, 0x389B1BBF, - 0x0C18588D, 0xA421C1BA, 0x7AA3865C, 0x71E08558, 0x3C5CFCAA, 0x7D239CA4, - 0x0297D9DD, 0xD7DC2830, 0x4B37802B, 0x7428AB54, 0xAEEE0347, 0x4B3FBB85, - 0x692F2F08, 0x134E578E, 0x36D9E0BF, 0xAE8B5FCF, 0xEDB93ECF, 0x2B27248E, - 0x170EB1EF, 0x7DC57FD6, 0x1E760F16, 0xB1136601, 0x864E1B9B, 0xD7EA7319, - 0x3AB871BD, 0xCFA4D76F, 0xE31BD782, 0x0DBEB469, 0xABB96061, 0x5370F85D, - 0xFFB07E37, 0xDA30D0FB, 0xEBC977B6, 0x0B98B40F, 0x3A4D0FE6, 0xDF4FC26B, - 0x159CF22A, 0xC298D6E2, 0x2B78EF6A, 0x61A94AC0, 0xAB561187, 0x14EEA0F0, - 0xDF0D4164, 0x19AF70EE }; - -/* -* MARS Encryption Round -*/ -inline void encrypt_round(u32bit& A, u32bit& B, u32bit& C, u32bit& D, - u32bit EK1, u32bit EK2) - { - const u32bit X = A + EK1; - A = rotate_left(A, 13); - u32bit Y = A * EK2; - u32bit Z = SBOX[X % 512]; - - Y = rotate_left(Y, 5); - Z ^= Y; - C += rotate_left(X, Y % 32); - Y = rotate_left(Y, 5); - Z ^= Y; - D ^= Y; - B += rotate_left(Z, Y % 32); - } - -/* -* MARS Decryption Round -*/ -inline void decrypt_round(u32bit& A, u32bit& B, u32bit& C, u32bit& D, - u32bit EK1, u32bit EK2) - { - u32bit Y = A * EK1; - A = rotate_right(A, 13); - const u32bit X = A + EK2; - u32bit Z = SBOX[X % 512]; - - Y = rotate_left(Y, 5); - Z ^= Y; - C -= rotate_left(X, Y % 32); - Y = rotate_left(Y, 5); - Z ^= Y; - D ^= Y; - B -= rotate_left(Z, Y % 32); - } - -/* -* MARS Forward Mixing Operation -*/ -void forward_mix(u32bit& A, u32bit& B, u32bit& C, u32bit& D) - { - for(size_t j = 0; j != 2; ++j) - { - B ^= SBOX[get_byte(3, A)]; B += SBOX[get_byte(2, A) + 256]; - C += SBOX[get_byte(1, A)]; D ^= SBOX[get_byte(0, A) + 256]; - A = rotate_right(A, 24) + D; - - C ^= SBOX[get_byte(3, B)]; C += SBOX[get_byte(2, B) + 256]; - D += SBOX[get_byte(1, B)]; A ^= SBOX[get_byte(0, B) + 256]; - B = rotate_right(B, 24) + C; - - D ^= SBOX[get_byte(3, C)]; D += SBOX[get_byte(2, C) + 256]; - A += SBOX[get_byte(1, C)]; B ^= SBOX[get_byte(0, C) + 256]; - C = rotate_right(C, 24); - - A ^= SBOX[get_byte(3, D)]; A += SBOX[get_byte(2, D) + 256]; - B += SBOX[get_byte(1, D)]; C ^= SBOX[get_byte(0, D) + 256]; - D = rotate_right(D, 24); - } - } - -/* -* MARS Reverse Mixing Operation -*/ -void reverse_mix(u32bit& A, u32bit& B, u32bit& C, u32bit& D) - { - for(size_t j = 0; j != 2; ++j) - { - B ^= SBOX[get_byte(3, A) + 256]; C -= SBOX[get_byte(0, A)]; - D -= SBOX[get_byte(1, A) + 256]; D ^= SBOX[get_byte(2, A)]; - A = rotate_left(A, 24); - - C ^= SBOX[get_byte(3, B) + 256]; D -= SBOX[get_byte(0, B)]; - A -= SBOX[get_byte(1, B) + 256]; A ^= SBOX[get_byte(2, B)]; - C -= (B = rotate_left(B, 24)); - - D ^= SBOX[get_byte(3, C) + 256]; A -= SBOX[get_byte(0, C)]; - B -= SBOX[get_byte(1, C) + 256]; B ^= SBOX[get_byte(2, C)]; - C = rotate_left(C, 24); - D -= A; - - A ^= SBOX[get_byte(3, D) + 256]; B -= SBOX[get_byte(0, D)]; - C -= SBOX[get_byte(1, D) + 256]; C ^= SBOX[get_byte(2, D)]; - D = rotate_left(D, 24); - } - } - -/* -* Generate a mask for runs of bits -*/ -u32bit gen_mask(u32bit input) - { - u32bit mask = 0; - - for(u32bit j = 2; j != 31; ++j) - { - const u32bit region = (input >> (j-1)) & 0x07; - - if(region == 0x00 || region == 0x07) - { - const u32bit low = (j < 9) ? 0 : (j - 9); - const u32bit high = (j < 23) ? j : 23; - - for(u32bit k = low; k != high; ++k) - { - const u32bit value = (input >> k) & 0x3FF; - - if(value == 0 || value == 0x3FF) - { - mask |= 1 << j; - break; - } - } - } - } - - return mask; - } - -} - -/* -* MARS Encryption -*/ -void MARS::encrypt_n(const byte in[], byte out[], size_t blocks) const - { - for(size_t i = 0; i != blocks; ++i) - { - u32bit A = load_le(in, 0) + EK[0]; - u32bit B = load_le(in, 1) + EK[1]; - u32bit C = load_le(in, 2) + EK[2]; - u32bit D = load_le(in, 3) + EK[3]; - - forward_mix(A, B, C, D); - - encrypt_round(A, B, C, D, EK[ 4], EK[ 5]); - encrypt_round(B, C, D, A, EK[ 6], EK[ 7]); - encrypt_round(C, D, A, B, EK[ 8], EK[ 9]); - encrypt_round(D, A, B, C, EK[10], EK[11]); - encrypt_round(A, B, C, D, EK[12], EK[13]); - encrypt_round(B, C, D, A, EK[14], EK[15]); - encrypt_round(C, D, A, B, EK[16], EK[17]); - encrypt_round(D, A, B, C, EK[18], EK[19]); - - encrypt_round(A, D, C, B, EK[20], EK[21]); - encrypt_round(B, A, D, C, EK[22], EK[23]); - encrypt_round(C, B, A, D, EK[24], EK[25]); - encrypt_round(D, C, B, A, EK[26], EK[27]); - encrypt_round(A, D, C, B, EK[28], EK[29]); - encrypt_round(B, A, D, C, EK[30], EK[31]); - encrypt_round(C, B, A, D, EK[32], EK[33]); - encrypt_round(D, C, B, A, EK[34], EK[35]); - - reverse_mix(A, B, C, D); - - A -= EK[36]; B -= EK[37]; C -= EK[38]; D -= EK[39]; - - store_le(out, A, B, C, D); - - in += BLOCK_SIZE; - out += BLOCK_SIZE; - } - } - -/* -* MARS Decryption -*/ -void MARS::decrypt_n(const byte in[], byte out[], size_t blocks) const - { - for(size_t i = 0; i != blocks; ++i) - { - u32bit A = load_le(in, 3) + EK[39]; - u32bit B = load_le(in, 2) + EK[38]; - u32bit C = load_le(in, 1) + EK[37]; - u32bit D = load_le(in, 0) + EK[36]; - - forward_mix(A, B, C, D); - - decrypt_round(A, B, C, D, EK[35], EK[34]); - decrypt_round(B, C, D, A, EK[33], EK[32]); - decrypt_round(C, D, A, B, EK[31], EK[30]); - decrypt_round(D, A, B, C, EK[29], EK[28]); - decrypt_round(A, B, C, D, EK[27], EK[26]); - decrypt_round(B, C, D, A, EK[25], EK[24]); - decrypt_round(C, D, A, B, EK[23], EK[22]); - decrypt_round(D, A, B, C, EK[21], EK[20]); - - decrypt_round(A, D, C, B, EK[19], EK[18]); - decrypt_round(B, A, D, C, EK[17], EK[16]); - decrypt_round(C, B, A, D, EK[15], EK[14]); - decrypt_round(D, C, B, A, EK[13], EK[12]); - decrypt_round(A, D, C, B, EK[11], EK[10]); - decrypt_round(B, A, D, C, EK[ 9], EK[ 8]); - decrypt_round(C, B, A, D, EK[ 7], EK[ 6]); - decrypt_round(D, C, B, A, EK[ 5], EK[ 4]); - - reverse_mix(A, B, C, D); - - A -= EK[3]; B -= EK[2]; C -= EK[1]; D -= EK[0]; - - store_le(out, D, C, B, A); - - in += BLOCK_SIZE; - out += BLOCK_SIZE; - } - } - -/* -* MARS Key Schedule -*/ -void MARS::key_schedule(const byte key[], size_t length) - { - SecureVector T(15); - for(size_t i = 0; i != length / 4; ++i) - T[i] = load_le(key, i); - - T[length / 4] = static_cast(length) / 4; - - for(u32bit i = 0; i != 4; ++i) - { - T[ 0] ^= rotate_left(T[ 8] ^ T[13], 3) ^ (i ); - T[ 1] ^= rotate_left(T[ 9] ^ T[14], 3) ^ (i + 4); - T[ 2] ^= rotate_left(T[10] ^ T[ 0], 3) ^ (i + 8); - T[ 3] ^= rotate_left(T[11] ^ T[ 1], 3) ^ (i + 12); - T[ 4] ^= rotate_left(T[12] ^ T[ 2], 3) ^ (i + 16); - T[ 5] ^= rotate_left(T[13] ^ T[ 3], 3) ^ (i + 20); - T[ 6] ^= rotate_left(T[14] ^ T[ 4], 3) ^ (i + 24); - T[ 7] ^= rotate_left(T[ 0] ^ T[ 5], 3) ^ (i + 28); - T[ 8] ^= rotate_left(T[ 1] ^ T[ 6], 3) ^ (i + 32); - T[ 9] ^= rotate_left(T[ 2] ^ T[ 7], 3) ^ (i + 36); - T[10] ^= rotate_left(T[ 3] ^ T[ 8], 3) ^ (i + 40); - T[11] ^= rotate_left(T[ 4] ^ T[ 9], 3) ^ (i + 44); - T[12] ^= rotate_left(T[ 5] ^ T[10], 3) ^ (i + 48); - T[13] ^= rotate_left(T[ 6] ^ T[11], 3) ^ (i + 52); - T[14] ^= rotate_left(T[ 7] ^ T[12], 3) ^ (i + 56); - - for(size_t j = 0; j != 4; ++j) - { - T[ 0] = rotate_left(T[ 0] + SBOX[T[14] % 512], 9); - T[ 1] = rotate_left(T[ 1] + SBOX[T[ 0] % 512], 9); - T[ 2] = rotate_left(T[ 2] + SBOX[T[ 1] % 512], 9); - T[ 3] = rotate_left(T[ 3] + SBOX[T[ 2] % 512], 9); - T[ 4] = rotate_left(T[ 4] + SBOX[T[ 3] % 512], 9); - T[ 5] = rotate_left(T[ 5] + SBOX[T[ 4] % 512], 9); - T[ 6] = rotate_left(T[ 6] + SBOX[T[ 5] % 512], 9); - T[ 7] = rotate_left(T[ 7] + SBOX[T[ 6] % 512], 9); - T[ 8] = rotate_left(T[ 8] + SBOX[T[ 7] % 512], 9); - T[ 9] = rotate_left(T[ 9] + SBOX[T[ 8] % 512], 9); - T[10] = rotate_left(T[10] + SBOX[T[ 9] % 512], 9); - T[11] = rotate_left(T[11] + SBOX[T[10] % 512], 9); - T[12] = rotate_left(T[12] + SBOX[T[11] % 512], 9); - T[13] = rotate_left(T[13] + SBOX[T[12] % 512], 9); - T[14] = rotate_left(T[14] + SBOX[T[13] % 512], 9); - } - - EK[10*i + 0] = T[ 0]; - EK[10*i + 1] = T[ 4]; - EK[10*i + 2] = T[ 8]; - EK[10*i + 3] = T[12]; - EK[10*i + 4] = T[ 1]; - EK[10*i + 5] = T[ 5]; - EK[10*i + 6] = T[ 9]; - EK[10*i + 7] = T[13]; - EK[10*i + 8] = T[ 2]; - EK[10*i + 9] = T[ 6]; - } - - for(size_t i = 5; i != 37; i += 2) - { - const u32bit key3 = EK[i] & 3; - EK[i] |= 3; - EK[i] ^= rotate_left(SBOX[265 + key3], EK[i-1] % 32) & gen_mask(EK[i]); - } - } - -} -/* -* MISTY1 -* (C) 1999-2009 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -namespace { - -static const byte MISTY1_SBOX_S7[128] = { - 0x1B, 0x32, 0x33, 0x5A, 0x3B, 0x10, 0x17, 0x54, 0x5B, 0x1A, 0x72, 0x73, - 0x6B, 0x2C, 0x66, 0x49, 0x1F, 0x24, 0x13, 0x6C, 0x37, 0x2E, 0x3F, 0x4A, - 0x5D, 0x0F, 0x40, 0x56, 0x25, 0x51, 0x1C, 0x04, 0x0B, 0x46, 0x20, 0x0D, - 0x7B, 0x35, 0x44, 0x42, 0x2B, 0x1E, 0x41, 0x14, 0x4B, 0x79, 0x15, 0x6F, - 0x0E, 0x55, 0x09, 0x36, 0x74, 0x0C, 0x67, 0x53, 0x28, 0x0A, 0x7E, 0x38, - 0x02, 0x07, 0x60, 0x29, 0x19, 0x12, 0x65, 0x2F, 0x30, 0x39, 0x08, 0x68, - 0x5F, 0x78, 0x2A, 0x4C, 0x64, 0x45, 0x75, 0x3D, 0x59, 0x48, 0x03, 0x57, - 0x7C, 0x4F, 0x62, 0x3C, 0x1D, 0x21, 0x5E, 0x27, 0x6A, 0x70, 0x4D, 0x3A, - 0x01, 0x6D, 0x6E, 0x63, 0x18, 0x77, 0x23, 0x05, 0x26, 0x76, 0x00, 0x31, - 0x2D, 0x7A, 0x7F, 0x61, 0x50, 0x22, 0x11, 0x06, 0x47, 0x16, 0x52, 0x4E, - 0x71, 0x3E, 0x69, 0x43, 0x34, 0x5C, 0x58, 0x7D }; - -static const u16bit MISTY1_SBOX_S9[512] = { - 0x01C3, 0x00CB, 0x0153, 0x019F, 0x01E3, 0x00E9, 0x00FB, 0x0035, 0x0181, - 0x00B9, 0x0117, 0x01EB, 0x0133, 0x0009, 0x002D, 0x00D3, 0x00C7, 0x014A, - 0x0037, 0x007E, 0x00EB, 0x0164, 0x0193, 0x01D8, 0x00A3, 0x011E, 0x0055, - 0x002C, 0x001D, 0x01A2, 0x0163, 0x0118, 0x014B, 0x0152, 0x01D2, 0x000F, - 0x002B, 0x0030, 0x013A, 0x00E5, 0x0111, 0x0138, 0x018E, 0x0063, 0x00E3, - 0x00C8, 0x01F4, 0x001B, 0x0001, 0x009D, 0x00F8, 0x01A0, 0x016D, 0x01F3, - 0x001C, 0x0146, 0x007D, 0x00D1, 0x0082, 0x01EA, 0x0183, 0x012D, 0x00F4, - 0x019E, 0x01D3, 0x00DD, 0x01E2, 0x0128, 0x01E0, 0x00EC, 0x0059, 0x0091, - 0x0011, 0x012F, 0x0026, 0x00DC, 0x00B0, 0x018C, 0x010F, 0x01F7, 0x00E7, - 0x016C, 0x00B6, 0x00F9, 0x00D8, 0x0151, 0x0101, 0x014C, 0x0103, 0x00B8, - 0x0154, 0x012B, 0x01AE, 0x0017, 0x0071, 0x000C, 0x0047, 0x0058, 0x007F, - 0x01A4, 0x0134, 0x0129, 0x0084, 0x015D, 0x019D, 0x01B2, 0x01A3, 0x0048, - 0x007C, 0x0051, 0x01CA, 0x0023, 0x013D, 0x01A7, 0x0165, 0x003B, 0x0042, - 0x00DA, 0x0192, 0x00CE, 0x00C1, 0x006B, 0x009F, 0x01F1, 0x012C, 0x0184, - 0x00FA, 0x0196, 0x01E1, 0x0169, 0x017D, 0x0031, 0x0180, 0x010A, 0x0094, - 0x01DA, 0x0186, 0x013E, 0x011C, 0x0060, 0x0175, 0x01CF, 0x0067, 0x0119, - 0x0065, 0x0068, 0x0099, 0x0150, 0x0008, 0x0007, 0x017C, 0x00B7, 0x0024, - 0x0019, 0x00DE, 0x0127, 0x00DB, 0x00E4, 0x01A9, 0x0052, 0x0109, 0x0090, - 0x019C, 0x01C1, 0x0028, 0x01B3, 0x0135, 0x016A, 0x0176, 0x00DF, 0x01E5, - 0x0188, 0x00C5, 0x016E, 0x01DE, 0x01B1, 0x00C3, 0x01DF, 0x0036, 0x00EE, - 0x01EE, 0x00F0, 0x0093, 0x0049, 0x009A, 0x01B6, 0x0069, 0x0081, 0x0125, - 0x000B, 0x005E, 0x00B4, 0x0149, 0x01C7, 0x0174, 0x003E, 0x013B, 0x01B7, - 0x008E, 0x01C6, 0x00AE, 0x0010, 0x0095, 0x01EF, 0x004E, 0x00F2, 0x01FD, - 0x0085, 0x00FD, 0x00F6, 0x00A0, 0x016F, 0x0083, 0x008A, 0x0156, 0x009B, - 0x013C, 0x0107, 0x0167, 0x0098, 0x01D0, 0x01E9, 0x0003, 0x01FE, 0x00BD, - 0x0122, 0x0089, 0x00D2, 0x018F, 0x0012, 0x0033, 0x006A, 0x0142, 0x00ED, - 0x0170, 0x011B, 0x00E2, 0x014F, 0x0158, 0x0131, 0x0147, 0x005D, 0x0113, - 0x01CD, 0x0079, 0x0161, 0x01A5, 0x0179, 0x009E, 0x01B4, 0x00CC, 0x0022, - 0x0132, 0x001A, 0x00E8, 0x0004, 0x0187, 0x01ED, 0x0197, 0x0039, 0x01BF, - 0x01D7, 0x0027, 0x018B, 0x00C6, 0x009C, 0x00D0, 0x014E, 0x006C, 0x0034, - 0x01F2, 0x006E, 0x00CA, 0x0025, 0x00BA, 0x0191, 0x00FE, 0x0013, 0x0106, - 0x002F, 0x01AD, 0x0172, 0x01DB, 0x00C0, 0x010B, 0x01D6, 0x00F5, 0x01EC, - 0x010D, 0x0076, 0x0114, 0x01AB, 0x0075, 0x010C, 0x01E4, 0x0159, 0x0054, - 0x011F, 0x004B, 0x00C4, 0x01BE, 0x00F7, 0x0029, 0x00A4, 0x000E, 0x01F0, - 0x0077, 0x004D, 0x017A, 0x0086, 0x008B, 0x00B3, 0x0171, 0x00BF, 0x010E, - 0x0104, 0x0097, 0x015B, 0x0160, 0x0168, 0x00D7, 0x00BB, 0x0066, 0x01CE, - 0x00FC, 0x0092, 0x01C5, 0x006F, 0x0016, 0x004A, 0x00A1, 0x0139, 0x00AF, - 0x00F1, 0x0190, 0x000A, 0x01AA, 0x0143, 0x017B, 0x0056, 0x018D, 0x0166, - 0x00D4, 0x01FB, 0x014D, 0x0194, 0x019A, 0x0087, 0x01F8, 0x0123, 0x00A7, - 0x01B8, 0x0141, 0x003C, 0x01F9, 0x0140, 0x002A, 0x0155, 0x011A, 0x01A1, - 0x0198, 0x00D5, 0x0126, 0x01AF, 0x0061, 0x012E, 0x0157, 0x01DC, 0x0072, - 0x018A, 0x00AA, 0x0096, 0x0115, 0x00EF, 0x0045, 0x007B, 0x008D, 0x0145, - 0x0053, 0x005F, 0x0178, 0x00B2, 0x002E, 0x0020, 0x01D5, 0x003F, 0x01C9, - 0x01E7, 0x01AC, 0x0044, 0x0038, 0x0014, 0x00B1, 0x016B, 0x00AB, 0x00B5, - 0x005A, 0x0182, 0x01C8, 0x01D4, 0x0018, 0x0177, 0x0064, 0x00CF, 0x006D, - 0x0100, 0x0199, 0x0130, 0x015A, 0x0005, 0x0120, 0x01BB, 0x01BD, 0x00E0, - 0x004F, 0x00D6, 0x013F, 0x01C4, 0x012A, 0x0015, 0x0006, 0x00FF, 0x019B, - 0x00A6, 0x0043, 0x0088, 0x0050, 0x015F, 0x01E8, 0x0121, 0x0073, 0x017E, - 0x00BC, 0x00C2, 0x00C9, 0x0173, 0x0189, 0x01F5, 0x0074, 0x01CC, 0x01E6, - 0x01A8, 0x0195, 0x001F, 0x0041, 0x000D, 0x01BA, 0x0032, 0x003D, 0x01D1, - 0x0080, 0x00A8, 0x0057, 0x01B9, 0x0162, 0x0148, 0x00D9, 0x0105, 0x0062, - 0x007A, 0x0021, 0x01FF, 0x0112, 0x0108, 0x01C0, 0x00A9, 0x011D, 0x01B0, - 0x01A6, 0x00CD, 0x00F3, 0x005C, 0x0102, 0x005B, 0x01D9, 0x0144, 0x01F6, - 0x00AD, 0x00A5, 0x003A, 0x01CB, 0x0136, 0x017F, 0x0046, 0x00E1, 0x001E, - 0x01DD, 0x00E6, 0x0137, 0x01FA, 0x0185, 0x008C, 0x008F, 0x0040, 0x01B5, - 0x00BE, 0x0078, 0x0000, 0x00AC, 0x0110, 0x015E, 0x0124, 0x0002, 0x01BC, - 0x00A2, 0x00EA, 0x0070, 0x01FC, 0x0116, 0x015C, 0x004C, 0x01C2 }; - -/* -* MISTY1 FI Function -*/ -u16bit FI(u16bit input, u16bit key7, u16bit key9) - { - u16bit D9 = input >> 7, D7 = input & 0x7F; - D9 = MISTY1_SBOX_S9[D9] ^ D7; - D7 = (MISTY1_SBOX_S7[D7] ^ key7 ^ D9) & 0x7F; - D9 = MISTY1_SBOX_S9[D9 ^ key9] ^ D7; - return static_cast((D7 << 9) | D9); - } - -} - -/* -* MISTY1 Encryption -*/ -void MISTY1::encrypt_n(const byte in[], byte out[], size_t blocks) const - { - for(size_t i = 0; i != blocks; ++i) - { - u16bit B0 = load_be(in, 0); - u16bit B1 = load_be(in, 1); - u16bit B2 = load_be(in, 2); - u16bit B3 = load_be(in, 3); - - for(size_t j = 0; j != 12; j += 3) - { - const u16bit* RK = &EK[8 * j]; - - B1 ^= B0 & RK[0]; - B0 ^= B1 | RK[1]; - B3 ^= B2 & RK[2]; - B2 ^= B3 | RK[3]; - - u32bit T0, T1; - - T0 = FI(B0 ^ RK[ 4], RK[ 5], RK[ 6]) ^ B1; - T1 = FI(B1 ^ RK[ 7], RK[ 8], RK[ 9]) ^ T0; - T0 = FI(T0 ^ RK[10], RK[11], RK[12]) ^ T1; - - B2 ^= T1 ^ RK[13]; - B3 ^= T0; - - T0 = FI(B2 ^ RK[14], RK[15], RK[16]) ^ B3; - T1 = FI(B3 ^ RK[17], RK[18], RK[19]) ^ T0; - T0 = FI(T0 ^ RK[20], RK[21], RK[22]) ^ T1; - - B0 ^= T1 ^ RK[23]; - B1 ^= T0; - } - - B1 ^= B0 & EK[96]; - B0 ^= B1 | EK[97]; - B3 ^= B2 & EK[98]; - B2 ^= B3 | EK[99]; - - store_be(out, B2, B3, B0, B1); - - in += BLOCK_SIZE; - out += BLOCK_SIZE; - } - } - -/* -* MISTY1 Decryption -*/ -void MISTY1::decrypt_n(const byte in[], byte out[], size_t blocks) const - { - for(size_t i = 0; i != blocks; ++i) - { - u16bit B0 = load_be(in, 2); - u16bit B1 = load_be(in, 3); - u16bit B2 = load_be(in, 0); - u16bit B3 = load_be(in, 1); - - for(size_t j = 0; j != 12; j += 3) - { - const u16bit* RK = &DK[8 * j]; - - B2 ^= B3 | RK[0]; - B3 ^= B2 & RK[1]; - B0 ^= B1 | RK[2]; - B1 ^= B0 & RK[3]; - - u32bit T0, T1; - - T0 = FI(B2 ^ RK[ 4], RK[ 5], RK[ 6]) ^ B3; - T1 = FI(B3 ^ RK[ 7], RK[ 8], RK[ 9]) ^ T0; - T0 = FI(T0 ^ RK[10], RK[11], RK[12]) ^ T1; - - B0 ^= T1 ^ RK[13]; - B1 ^= T0; - - T0 = FI(B0 ^ RK[14], RK[15], RK[16]) ^ B1; - T1 = FI(B1 ^ RK[17], RK[18], RK[19]) ^ T0; - T0 = FI(T0 ^ RK[20], RK[21], RK[22]) ^ T1; - - B2 ^= T1 ^ RK[23]; - B3 ^= T0; - } - - B2 ^= B3 | DK[96]; - B3 ^= B2 & DK[97]; - B0 ^= B1 | DK[98]; - B1 ^= B0 & DK[99]; - - store_be(out, B0, B1, B2, B3); - - in += BLOCK_SIZE; - out += BLOCK_SIZE; - } - } - -/* -* MISTY1 Key Schedule -*/ -void MISTY1::key_schedule(const byte key[], size_t length) - { - SecureVector KS(32); - for(size_t i = 0; i != length / 2; ++i) - KS[i] = load_be(key, i); - - for(size_t i = 0; i != 8; ++i) - { - KS[i+ 8] = FI(KS[i], KS[(i+1) % 8] >> 9, KS[(i+1) % 8] & 0x1FF); - KS[i+16] = KS[i+8] >> 9; - KS[i+24] = KS[i+8] & 0x1FF; - } - - /* - * Precomputed indexes for the orderings of the subkeys (MISTY1 reuses - * values) - */ - static const byte EK_ORDER[100] = { - 0x00, 0x0E, 0x0A, 0x04, 0x00, 0x15, 0x1D, 0x02, 0x11, 0x19, 0x07, 0x13, - 0x1B, 0x04, 0x01, 0x16, 0x1E, 0x03, 0x12, 0x1A, 0x00, 0x14, 0x1C, 0x05, - 0x01, 0x0F, 0x0B, 0x05, 0x02, 0x17, 0x1F, 0x04, 0x13, 0x1B, 0x01, 0x15, - 0x1D, 0x06, 0x03, 0x10, 0x18, 0x05, 0x14, 0x1C, 0x02, 0x16, 0x1E, 0x07, - 0x02, 0x08, 0x0C, 0x06, 0x04, 0x11, 0x19, 0x06, 0x15, 0x1D, 0x03, 0x17, - 0x1F, 0x00, 0x05, 0x12, 0x1A, 0x07, 0x16, 0x1E, 0x04, 0x10, 0x18, 0x01, - 0x03, 0x09, 0x0D, 0x07, 0x06, 0x13, 0x1B, 0x00, 0x17, 0x1F, 0x05, 0x11, - 0x19, 0x02, 0x07, 0x14, 0x1C, 0x01, 0x10, 0x18, 0x06, 0x12, 0x1A, 0x03, - 0x04, 0x0A, 0x0E, 0x00 }; - - static const byte DK_ORDER[100] = { - 0x00, 0x0E, 0x0A, 0x04, 0x07, 0x14, 0x1C, 0x01, 0x10, 0x18, 0x06, 0x12, - 0x1A, 0x03, 0x06, 0x13, 0x1B, 0x00, 0x17, 0x1F, 0x05, 0x11, 0x19, 0x02, - 0x07, 0x0D, 0x09, 0x03, 0x05, 0x12, 0x1A, 0x07, 0x16, 0x1E, 0x04, 0x10, - 0x18, 0x01, 0x04, 0x11, 0x19, 0x06, 0x15, 0x1D, 0x03, 0x17, 0x1F, 0x00, - 0x06, 0x0C, 0x08, 0x02, 0x03, 0x10, 0x18, 0x05, 0x14, 0x1C, 0x02, 0x16, - 0x1E, 0x07, 0x02, 0x17, 0x1F, 0x04, 0x13, 0x1B, 0x01, 0x15, 0x1D, 0x06, - 0x05, 0x0B, 0x0F, 0x01, 0x01, 0x16, 0x1E, 0x03, 0x12, 0x1A, 0x00, 0x14, - 0x1C, 0x05, 0x00, 0x15, 0x1D, 0x02, 0x11, 0x19, 0x07, 0x13, 0x1B, 0x04, - 0x04, 0x0A, 0x0E, 0x00 }; - - for(size_t i = 0; i != 100; ++i) - { - EK[i] = KS[EK_ORDER[i]]; - DK[i] = KS[DK_ORDER[i]]; - } - } - -/* -* MISTY1 Constructor -*/ -MISTY1::MISTY1(size_t rounds) : EK(100), DK(100) - { - if(rounds != 8) - throw Invalid_Argument("MISTY1: Invalid number of rounds: " - + to_string(rounds)); - } - -} -/* -* Noekeon -* (C) 1999-2008 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -namespace { - -/* -* Noekeon's Theta Operation -*/ -inline void theta(u32bit& A0, u32bit& A1, - u32bit& A2, u32bit& A3, - const u32bit EK[4]) - { - u32bit T = A0 ^ A2; - T ^= rotate_left(T, 8) ^ rotate_right(T, 8); - A1 ^= T; - A3 ^= T; - - A0 ^= EK[0]; - A1 ^= EK[1]; - A2 ^= EK[2]; - A3 ^= EK[3]; - - T = A1 ^ A3; - T ^= rotate_left(T, 8) ^ rotate_right(T, 8); - A0 ^= T; - A2 ^= T; - } - -/* -* Theta With Null Key -*/ -inline void theta(u32bit& A0, u32bit& A1, - u32bit& A2, u32bit& A3) - { - u32bit T = A0 ^ A2; - T ^= rotate_left(T, 8) ^ rotate_right(T, 8); - A1 ^= T; - A3 ^= T; - - T = A1 ^ A3; - T ^= rotate_left(T, 8) ^ rotate_right(T, 8); - A0 ^= T; - A2 ^= T; - } - -/* -* Noekeon's Gamma S-Box Layer -*/ -inline void gamma(u32bit& A0, u32bit& A1, u32bit& A2, u32bit& A3) - { - A1 ^= ~A3 & ~A2; - A0 ^= A2 & A1; - - u32bit T = A3; - A3 = A0; - A0 = T; - - A2 ^= A0 ^ A1 ^ A3; - - A1 ^= ~A3 & ~A2; - A0 ^= A2 & A1; - } - -} - -/* -* Noekeon Round Constants -*/ -const byte Noekeon::RC[] = { - 0x80, 0x1B, 0x36, 0x6C, 0xD8, 0xAB, 0x4D, 0x9A, - 0x2F, 0x5E, 0xBC, 0x63, 0xC6, 0x97, 0x35, 0x6A, - 0xD4 }; - -/* -* Noekeon Encryption -*/ -void Noekeon::encrypt_n(const byte in[], byte out[], size_t blocks) const - { - for(size_t i = 0; i != blocks; ++i) - { - u32bit A0 = load_be(in, 0); - u32bit A1 = load_be(in, 1); - u32bit A2 = load_be(in, 2); - u32bit A3 = load_be(in, 3); - - for(size_t j = 0; j != 16; ++j) - { - A0 ^= RC[j]; - theta(A0, A1, A2, A3, &EK[0]); - - A1 = rotate_left(A1, 1); - A2 = rotate_left(A2, 5); - A3 = rotate_left(A3, 2); - - gamma(A0, A1, A2, A3); - - A1 = rotate_right(A1, 1); - A2 = rotate_right(A2, 5); - A3 = rotate_right(A3, 2); - } - - A0 ^= RC[16]; - theta(A0, A1, A2, A3, &EK[0]); - - store_be(out, A0, A1, A2, A3); - - in += BLOCK_SIZE; - out += BLOCK_SIZE; - } - } - -/* -* Noekeon Encryption -*/ -void Noekeon::decrypt_n(const byte in[], byte out[], size_t blocks) const - { - for(size_t i = 0; i != blocks; ++i) - { - u32bit A0 = load_be(in, 0); - u32bit A1 = load_be(in, 1); - u32bit A2 = load_be(in, 2); - u32bit A3 = load_be(in, 3); - - for(size_t j = 16; j != 0; --j) - { - theta(A0, A1, A2, A3, &DK[0]); - A0 ^= RC[j]; - - A1 = rotate_left(A1, 1); - A2 = rotate_left(A2, 5); - A3 = rotate_left(A3, 2); - - gamma(A0, A1, A2, A3); - - A1 = rotate_right(A1, 1); - A2 = rotate_right(A2, 5); - A3 = rotate_right(A3, 2); - } - - theta(A0, A1, A2, A3, &DK[0]); - A0 ^= RC[0]; - - store_be(out, A0, A1, A2, A3); - - in += BLOCK_SIZE; - out += BLOCK_SIZE; - } - } - -/* -* Noekeon Key Schedule -*/ -void Noekeon::key_schedule(const byte key[], size_t) - { - u32bit A0 = load_be(key, 0); - u32bit A1 = load_be(key, 1); - u32bit A2 = load_be(key, 2); - u32bit A3 = load_be(key, 3); - - for(size_t i = 0; i != 16; ++i) - { - A0 ^= RC[i]; - theta(A0, A1, A2, A3); - - A1 = rotate_left(A1, 1); - A2 = rotate_left(A2, 5); - A3 = rotate_left(A3, 2); - - gamma(A0, A1, A2, A3); - - A1 = rotate_right(A1, 1); - A2 = rotate_right(A2, 5); - A3 = rotate_right(A3, 2); - } - - A0 ^= RC[16]; - - DK[0] = A0; - DK[1] = A1; - DK[2] = A2; - DK[3] = A3; - - theta(A0, A1, A2, A3); - - EK[0] = A0; - EK[1] = A1; - EK[2] = A2; - EK[3] = A3; - } - -/* -* Clear memory of sensitive data -*/ -void Noekeon::clear() - { - zeroise(EK); - zeroise(DK); - } - -} -/* -* Noekeon in SIMD -* (C) 2010 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -/* -* Noekeon's Theta Operation -*/ -#define NOK_SIMD_THETA(A0, A1, A2, A3, K0, K1, K2, K3) \ - do { \ - SIMD_32 T = A0 ^ A2; \ - SIMD_32 T_l8 = T; \ - SIMD_32 T_r8 = T; \ - T_l8.rotate_left(8); \ - T_r8.rotate_right(8); \ - T ^= T_l8; \ - T ^= T_r8; \ - A1 ^= T; \ - A3 ^= T; \ - \ - A0 ^= K0; \ - A1 ^= K1; \ - A2 ^= K2; \ - A3 ^= K3; \ - \ - T = A1 ^ A3; \ - T_l8 = T; \ - T_r8 = T; \ - T_l8.rotate_left(8); \ - T_r8.rotate_right(8); \ - T ^= T_l8; \ - T ^= T_r8; \ - A0 ^= T; \ - A2 ^= T; \ - } while(0) - -/* -* Noekeon's Gamma S-Box Layer -*/ -#define NOK_SIMD_GAMMA(A0, A1, A2, A3) \ - do \ - { \ - A1 ^= A3.andc(~A2); \ - A0 ^= A2 & A1; \ - \ - SIMD_32 T = A3; \ - A3 = A0; \ - A0 = T; \ - \ - A2 ^= A0 ^ A1 ^ A3; \ - \ - A1 ^= A3.andc(~A2); \ - A0 ^= A2 & A1; \ - } while(0) - -/* -* Noekeon Encryption -*/ -void Noekeon_SIMD::encrypt_n(const byte in[], byte out[], size_t blocks) const - { - const SecureVector& EK = this->get_EK(); - - SIMD_32 K0 = SIMD_32(EK[0]); - SIMD_32 K1 = SIMD_32(EK[1]); - SIMD_32 K2 = SIMD_32(EK[2]); - SIMD_32 K3 = SIMD_32(EK[3]); - - while(blocks >= 4) - { - SIMD_32 A0 = SIMD_32::load_be(in ); - SIMD_32 A1 = SIMD_32::load_be(in + 16); - SIMD_32 A2 = SIMD_32::load_be(in + 32); - SIMD_32 A3 = SIMD_32::load_be(in + 48); - - SIMD_32::transpose(A0, A1, A2, A3); - - for(size_t i = 0; i != 16; ++i) - { - A0 ^= SIMD_32(RC[i]); - - NOK_SIMD_THETA(A0, A1, A2, A3, K0, K1, K2, K3); - - A1.rotate_left(1); - A2.rotate_left(5); - A3.rotate_left(2); - - NOK_SIMD_GAMMA(A0, A1, A2, A3); - - A1.rotate_right(1); - A2.rotate_right(5); - A3.rotate_right(2); - } - - A0 ^= SIMD_32(RC[16]); - NOK_SIMD_THETA(A0, A1, A2, A3, K0, K1, K2, K3); - - SIMD_32::transpose(A0, A1, A2, A3); - - A0.store_be(out); - A1.store_be(out + 16); - A2.store_be(out + 32); - A3.store_be(out + 48); - - in += 64; - out += 64; - blocks -= 4; - } - - if(blocks) - Noekeon::encrypt_n(in, out, blocks); - } - -/* -* Noekeon Encryption -*/ -void Noekeon_SIMD::decrypt_n(const byte in[], byte out[], size_t blocks) const - { - const SecureVector& DK = this->get_DK(); - - SIMD_32 K0 = SIMD_32(DK[0]); - SIMD_32 K1 = SIMD_32(DK[1]); - SIMD_32 K2 = SIMD_32(DK[2]); - SIMD_32 K3 = SIMD_32(DK[3]); - - while(blocks >= 4) - { - SIMD_32 A0 = SIMD_32::load_be(in ); - SIMD_32 A1 = SIMD_32::load_be(in + 16); - SIMD_32 A2 = SIMD_32::load_be(in + 32); - SIMD_32 A3 = SIMD_32::load_be(in + 48); - - SIMD_32::transpose(A0, A1, A2, A3); - - for(size_t i = 0; i != 16; ++i) - { - NOK_SIMD_THETA(A0, A1, A2, A3, K0, K1, K2, K3); - - A0 ^= SIMD_32(RC[16-i]); - - A1.rotate_left(1); - A2.rotate_left(5); - A3.rotate_left(2); - - NOK_SIMD_GAMMA(A0, A1, A2, A3); - - A1.rotate_right(1); - A2.rotate_right(5); - A3.rotate_right(2); - } - - NOK_SIMD_THETA(A0, A1, A2, A3, K0, K1, K2, K3); - A0 ^= SIMD_32(RC[0]); - - SIMD_32::transpose(A0, A1, A2, A3); - - A0.store_be(out); - A1.store_be(out + 16); - A2.store_be(out + 32); - A3.store_be(out + 48); - - in += 64; - out += 64; - blocks -= 4; - } - - if(blocks) - Noekeon::decrypt_n(in, out, blocks); - } - -} -/* -* RC2 -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -/* -* RC2 Encryption -*/ -void RC2::encrypt_n(const byte in[], byte out[], size_t blocks) const - { - for(size_t i = 0; i != blocks; ++i) - { - u16bit R0 = load_le(in, 0); - u16bit R1 = load_le(in, 1); - u16bit R2 = load_le(in, 2); - u16bit R3 = load_le(in, 3); - - for(size_t j = 0; j != 16; ++j) - { - R0 += (R1 & ~R3) + (R2 & R3) + K[4*j]; - R0 = rotate_left(R0, 1); - - R1 += (R2 & ~R0) + (R3 & R0) + K[4*j + 1]; - R1 = rotate_left(R1, 2); - - R2 += (R3 & ~R1) + (R0 & R1) + K[4*j + 2]; - R2 = rotate_left(R2, 3); - - R3 += (R0 & ~R2) + (R1 & R2) + K[4*j + 3]; - R3 = rotate_left(R3, 5); - - if(j == 4 || j == 10) - { - R0 += K[R3 % 64]; - R1 += K[R0 % 64]; - R2 += K[R1 % 64]; - R3 += K[R2 % 64]; - } - } - - store_le(out, R0, R1, R2, R3); - - in += BLOCK_SIZE; - out += BLOCK_SIZE; - } - } - -/* -* RC2 Decryption -*/ -void RC2::decrypt_n(const byte in[], byte out[], size_t blocks) const - { - for(size_t i = 0; i != blocks; ++i) - { - u16bit R0 = load_le(in, 0); - u16bit R1 = load_le(in, 1); - u16bit R2 = load_le(in, 2); - u16bit R3 = load_le(in, 3); - - for(size_t j = 0; j != 16; ++j) - { - R3 = rotate_right(R3, 5); - R3 -= (R0 & ~R2) + (R1 & R2) + K[63 - (4*j + 0)]; - - R2 = rotate_right(R2, 3); - R2 -= (R3 & ~R1) + (R0 & R1) + K[63 - (4*j + 1)]; - - R1 = rotate_right(R1, 2); - R1 -= (R2 & ~R0) + (R3 & R0) + K[63 - (4*j + 2)]; - - R0 = rotate_right(R0, 1); - R0 -= (R1 & ~R3) + (R2 & R3) + K[63 - (4*j + 3)]; - - if(j == 4 || j == 10) - { - R3 -= K[R2 % 64]; - R2 -= K[R1 % 64]; - R1 -= K[R0 % 64]; - R0 -= K[R3 % 64]; - } - } - - store_le(out, R0, R1, R2, R3); - - in += BLOCK_SIZE; - out += BLOCK_SIZE; - } - } - -/* -* RC2 Key Schedule -*/ -void RC2::key_schedule(const byte key[], size_t length) - { - static const byte TABLE[256] = { - 0xD9, 0x78, 0xF9, 0xC4, 0x19, 0xDD, 0xB5, 0xED, 0x28, 0xE9, 0xFD, 0x79, - 0x4A, 0xA0, 0xD8, 0x9D, 0xC6, 0x7E, 0x37, 0x83, 0x2B, 0x76, 0x53, 0x8E, - 0x62, 0x4C, 0x64, 0x88, 0x44, 0x8B, 0xFB, 0xA2, 0x17, 0x9A, 0x59, 0xF5, - 0x87, 0xB3, 0x4F, 0x13, 0x61, 0x45, 0x6D, 0x8D, 0x09, 0x81, 0x7D, 0x32, - 0xBD, 0x8F, 0x40, 0xEB, 0x86, 0xB7, 0x7B, 0x0B, 0xF0, 0x95, 0x21, 0x22, - 0x5C, 0x6B, 0x4E, 0x82, 0x54, 0xD6, 0x65, 0x93, 0xCE, 0x60, 0xB2, 0x1C, - 0x73, 0x56, 0xC0, 0x14, 0xA7, 0x8C, 0xF1, 0xDC, 0x12, 0x75, 0xCA, 0x1F, - 0x3B, 0xBE, 0xE4, 0xD1, 0x42, 0x3D, 0xD4, 0x30, 0xA3, 0x3C, 0xB6, 0x26, - 0x6F, 0xBF, 0x0E, 0xDA, 0x46, 0x69, 0x07, 0x57, 0x27, 0xF2, 0x1D, 0x9B, - 0xBC, 0x94, 0x43, 0x03, 0xF8, 0x11, 0xC7, 0xF6, 0x90, 0xEF, 0x3E, 0xE7, - 0x06, 0xC3, 0xD5, 0x2F, 0xC8, 0x66, 0x1E, 0xD7, 0x08, 0xE8, 0xEA, 0xDE, - 0x80, 0x52, 0xEE, 0xF7, 0x84, 0xAA, 0x72, 0xAC, 0x35, 0x4D, 0x6A, 0x2A, - 0x96, 0x1A, 0xD2, 0x71, 0x5A, 0x15, 0x49, 0x74, 0x4B, 0x9F, 0xD0, 0x5E, - 0x04, 0x18, 0xA4, 0xEC, 0xC2, 0xE0, 0x41, 0x6E, 0x0F, 0x51, 0xCB, 0xCC, - 0x24, 0x91, 0xAF, 0x50, 0xA1, 0xF4, 0x70, 0x39, 0x99, 0x7C, 0x3A, 0x85, - 0x23, 0xB8, 0xB4, 0x7A, 0xFC, 0x02, 0x36, 0x5B, 0x25, 0x55, 0x97, 0x31, - 0x2D, 0x5D, 0xFA, 0x98, 0xE3, 0x8A, 0x92, 0xAE, 0x05, 0xDF, 0x29, 0x10, - 0x67, 0x6C, 0xBA, 0xC9, 0xD3, 0x00, 0xE6, 0xCF, 0xE1, 0x9E, 0xA8, 0x2C, - 0x63, 0x16, 0x01, 0x3F, 0x58, 0xE2, 0x89, 0xA9, 0x0D, 0x38, 0x34, 0x1B, - 0xAB, 0x33, 0xFF, 0xB0, 0xBB, 0x48, 0x0C, 0x5F, 0xB9, 0xB1, 0xCD, 0x2E, - 0xC5, 0xF3, 0xDB, 0x47, 0xE5, 0xA5, 0x9C, 0x77, 0x0A, 0xA6, 0x20, 0x68, - 0xFE, 0x7F, 0xC1, 0xAD }; - - SecureVector L(128); - L.copy(key, length); - - for(size_t i = length; i != 128; ++i) - L[i] = TABLE[(L[i-1] + L[i-length]) % 256]; - - L[128-length] = TABLE[L[128-length]]; - - for(s32bit i = 127-length; i >= 0; --i) - L[i] = TABLE[L[i+1] ^ L[i+length]]; - - load_le(&K[0], &L[0], 64); - } - -/* -* Return the code of the effective key bits -*/ -byte RC2::EKB_code(size_t ekb) - { - const byte EKB[256] = { - 0xBD, 0x56, 0xEA, 0xF2, 0xA2, 0xF1, 0xAC, 0x2A, 0xB0, 0x93, 0xD1, 0x9C, - 0x1B, 0x33, 0xFD, 0xD0, 0x30, 0x04, 0xB6, 0xDC, 0x7D, 0xDF, 0x32, 0x4B, - 0xF7, 0xCB, 0x45, 0x9B, 0x31, 0xBB, 0x21, 0x5A, 0x41, 0x9F, 0xE1, 0xD9, - 0x4A, 0x4D, 0x9E, 0xDA, 0xA0, 0x68, 0x2C, 0xC3, 0x27, 0x5F, 0x80, 0x36, - 0x3E, 0xEE, 0xFB, 0x95, 0x1A, 0xFE, 0xCE, 0xA8, 0x34, 0xA9, 0x13, 0xF0, - 0xA6, 0x3F, 0xD8, 0x0C, 0x78, 0x24, 0xAF, 0x23, 0x52, 0xC1, 0x67, 0x17, - 0xF5, 0x66, 0x90, 0xE7, 0xE8, 0x07, 0xB8, 0x60, 0x48, 0xE6, 0x1E, 0x53, - 0xF3, 0x92, 0xA4, 0x72, 0x8C, 0x08, 0x15, 0x6E, 0x86, 0x00, 0x84, 0xFA, - 0xF4, 0x7F, 0x8A, 0x42, 0x19, 0xF6, 0xDB, 0xCD, 0x14, 0x8D, 0x50, 0x12, - 0xBA, 0x3C, 0x06, 0x4E, 0xEC, 0xB3, 0x35, 0x11, 0xA1, 0x88, 0x8E, 0x2B, - 0x94, 0x99, 0xB7, 0x71, 0x74, 0xD3, 0xE4, 0xBF, 0x3A, 0xDE, 0x96, 0x0E, - 0xBC, 0x0A, 0xED, 0x77, 0xFC, 0x37, 0x6B, 0x03, 0x79, 0x89, 0x62, 0xC6, - 0xD7, 0xC0, 0xD2, 0x7C, 0x6A, 0x8B, 0x22, 0xA3, 0x5B, 0x05, 0x5D, 0x02, - 0x75, 0xD5, 0x61, 0xE3, 0x18, 0x8F, 0x55, 0x51, 0xAD, 0x1F, 0x0B, 0x5E, - 0x85, 0xE5, 0xC2, 0x57, 0x63, 0xCA, 0x3D, 0x6C, 0xB4, 0xC5, 0xCC, 0x70, - 0xB2, 0x91, 0x59, 0x0D, 0x47, 0x20, 0xC8, 0x4F, 0x58, 0xE0, 0x01, 0xE2, - 0x16, 0x38, 0xC4, 0x6F, 0x3B, 0x0F, 0x65, 0x46, 0xBE, 0x7E, 0x2D, 0x7B, - 0x82, 0xF9, 0x40, 0xB5, 0x1D, 0x73, 0xF8, 0xEB, 0x26, 0xC7, 0x87, 0x97, - 0x25, 0x54, 0xB1, 0x28, 0xAA, 0x98, 0x9D, 0xA5, 0x64, 0x6D, 0x7A, 0xD4, - 0x10, 0x81, 0x44, 0xEF, 0x49, 0xD6, 0xAE, 0x2E, 0xDD, 0x76, 0x5C, 0x2F, - 0xA7, 0x1C, 0xC9, 0x09, 0x69, 0x9A, 0x83, 0xCF, 0x29, 0x39, 0xB9, 0xE9, - 0x4C, 0xFF, 0x43, 0xAB }; - - if(ekb < 256) - return EKB[ekb]; - else - throw Encoding_Error("RC2::EKB_code: EKB is too large"); - } - -} -/* -* RC5 -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include - -namespace Botan { - -/* -* RC5 Encryption -*/ -void RC5::encrypt_n(const byte in[], byte out[], size_t blocks) const - { - const size_t rounds = (S.size() - 2) / 2; - - for(size_t i = 0; i != blocks; ++i) - { - u32bit A = load_le(in, 0); - u32bit B = load_le(in, 1); - - A += S[0]; B += S[1]; - for(size_t j = 0; j != rounds; j += 4) - { - A = rotate_left(A ^ B, B % 32) + S[2*j+2]; - B = rotate_left(B ^ A, A % 32) + S[2*j+3]; - - A = rotate_left(A ^ B, B % 32) + S[2*j+4]; - B = rotate_left(B ^ A, A % 32) + S[2*j+5]; - - A = rotate_left(A ^ B, B % 32) + S[2*j+6]; - B = rotate_left(B ^ A, A % 32) + S[2*j+7]; - - A = rotate_left(A ^ B, B % 32) + S[2*j+8]; - B = rotate_left(B ^ A, A % 32) + S[2*j+9]; - } - - store_le(out, A, B); - - in += BLOCK_SIZE; - out += BLOCK_SIZE; - } - } - -/* -* RC5 Decryption -*/ -void RC5::decrypt_n(const byte in[], byte out[], size_t blocks) const - { - const size_t rounds = (S.size() - 2) / 2; - - for(size_t i = 0; i != blocks; ++i) - { - u32bit A = load_le(in, 0); - u32bit B = load_le(in, 1); - - for(size_t j = rounds; j != 0; j -= 4) - { - B = rotate_right(B - S[2*j+1], A % 32) ^ A; - A = rotate_right(A - S[2*j ], B % 32) ^ B; - - B = rotate_right(B - S[2*j-1], A % 32) ^ A; - A = rotate_right(A - S[2*j-2], B % 32) ^ B; - - B = rotate_right(B - S[2*j-3], A % 32) ^ A; - A = rotate_right(A - S[2*j-4], B % 32) ^ B; - - B = rotate_right(B - S[2*j-5], A % 32) ^ A; - A = rotate_right(A - S[2*j-6], B % 32) ^ B; - } - B -= S[1]; A -= S[0]; - - store_le(out, A, B); - - in += BLOCK_SIZE; - out += BLOCK_SIZE; - } - } - -/* -* RC5 Key Schedule -*/ -void RC5::key_schedule(const byte key[], size_t length) - { - const size_t WORD_KEYLENGTH = (((length - 1) / 4) + 1); - const size_t MIX_ROUNDS = 3 * std::max(WORD_KEYLENGTH, S.size()); - - S[0] = 0xB7E15163; - for(size_t i = 1; i != S.size(); ++i) - S[i] = S[i-1] + 0x9E3779B9; - - SecureVector K(8); - - for(s32bit i = length-1; i >= 0; --i) - K[i/4] = (K[i/4] << 8) + key[i]; - - u32bit A = 0, B = 0; - - for(size_t i = 0; i != MIX_ROUNDS; ++i) - { - A = rotate_left(S[i % S.size()] + A + B, 3); - B = rotate_left(K[i % WORD_KEYLENGTH] + A + B, (A + B) % 32); - S[i % S.size()] = A; - K[i % WORD_KEYLENGTH] = B; - } - } - -/* -* Return the name of this type -*/ -std::string RC5::name() const - { - return "RC5(" + to_string(get_rounds()) + ")"; - } - -/* -* RC5 Constructor -*/ -RC5::RC5(size_t rounds) - { - if(rounds < 8 || rounds > 32 || (rounds % 4 != 0)) - throw Invalid_Argument("RC5: Invalid number of rounds " + - to_string(rounds)); - - S.resize(2*rounds + 2); - } - -} -/* -* RC6 -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include - -namespace Botan { - -/* -* RC6 Encryption -*/ -void RC6::encrypt_n(const byte in[], byte out[], size_t blocks) const - { - for(size_t i = 0; i != blocks; ++i) - { - u32bit A = load_le(in, 0); - u32bit B = load_le(in, 1); - u32bit C = load_le(in, 2); - u32bit D = load_le(in, 3); - - B += S[0]; D += S[1]; - - for(size_t j = 0; j != 20; j += 4) - { - u32bit T1, T2; - - T1 = rotate_left(B*(2*B+1), 5); - T2 = rotate_left(D*(2*D+1), 5); - A = rotate_left(A ^ T1, T2 % 32) + S[2*j+2]; - C = rotate_left(C ^ T2, T1 % 32) + S[2*j+3]; - - T1 = rotate_left(C*(2*C+1), 5); - T2 = rotate_left(A*(2*A+1), 5); - B = rotate_left(B ^ T1, T2 % 32) + S[2*j+4]; - D = rotate_left(D ^ T2, T1 % 32) + S[2*j+5]; - - T1 = rotate_left(D*(2*D+1), 5); - T2 = rotate_left(B*(2*B+1), 5); - C = rotate_left(C ^ T1, T2 % 32) + S[2*j+6]; - A = rotate_left(A ^ T2, T1 % 32) + S[2*j+7]; - - T1 = rotate_left(A*(2*A+1), 5); - T2 = rotate_left(C*(2*C+1), 5); - D = rotate_left(D ^ T1, T2 % 32) + S[2*j+8]; - B = rotate_left(B ^ T2, T1 % 32) + S[2*j+9]; - } - - A += S[42]; C += S[43]; - - store_le(out, A, B, C, D); - - in += BLOCK_SIZE; - out += BLOCK_SIZE; - } - } - -/* -* RC6 Decryption -*/ -void RC6::decrypt_n(const byte in[], byte out[], size_t blocks) const - { - for(size_t i = 0; i != blocks; ++i) - { - u32bit A = load_le(in, 0); - u32bit B = load_le(in, 1); - u32bit C = load_le(in, 2); - u32bit D = load_le(in, 3); - - C -= S[43]; A -= S[42]; - - for(size_t j = 0; j != 20; j += 4) - { - u32bit T1, T2; - - T1 = rotate_left(A*(2*A+1), 5); - T2 = rotate_left(C*(2*C+1), 5); - B = rotate_right(B - S[41 - 2*j], T1 % 32) ^ T2; - D = rotate_right(D - S[40 - 2*j], T2 % 32) ^ T1; - - T1 = rotate_left(D*(2*D+1), 5); - T2 = rotate_left(B*(2*B+1), 5); - A = rotate_right(A - S[39 - 2*j], T1 % 32) ^ T2; - C = rotate_right(C - S[38 - 2*j], T2 % 32) ^ T1; - - T1 = rotate_left(C*(2*C+1), 5); - T2 = rotate_left(A*(2*A+1), 5); - D = rotate_right(D - S[37 - 2*j], T1 % 32) ^ T2; - B = rotate_right(B - S[36 - 2*j], T2 % 32) ^ T1; - - T1 = rotate_left(B*(2*B+1), 5); - T2 = rotate_left(D*(2*D+1), 5); - C = rotate_right(C - S[35 - 2*j], T1 % 32) ^ T2; - A = rotate_right(A - S[34 - 2*j], T2 % 32) ^ T1; - } - - D -= S[1]; B -= S[0]; - - store_le(out, A, B, C, D); - - in += BLOCK_SIZE; - out += BLOCK_SIZE; - } - } - -/* -* RC6 Key Schedule -*/ -void RC6::key_schedule(const byte key[], size_t length) - { - const size_t WORD_KEYLENGTH = (((length - 1) / 4) + 1); - const size_t MIX_ROUNDS = 3 * std::max(WORD_KEYLENGTH, S.size()); - - S[0] = 0xB7E15163; - for(size_t i = 1; i != S.size(); ++i) - S[i] = S[i-1] + 0x9E3779B9; - - SecureVector K(8); - - for(s32bit i = length-1; i >= 0; --i) - K[i/4] = (K[i/4] << 8) + key[i]; - - u32bit A = 0, B = 0; - for(size_t i = 0; i != MIX_ROUNDS; ++i) - { - A = rotate_left(S[i % S.size()] + A + B, 3); - B = rotate_left(K[i % WORD_KEYLENGTH] + A + B, (A + B) % 32); - S[i % S.size()] = A; - K[i % WORD_KEYLENGTH] = B; - } - } - -} -/* -* SAFER-SK -* (C) 1999-2009 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -namespace { - -const byte EXP[256] = { - 0x01, 0x2D, 0xE2, 0x93, 0xBE, 0x45, 0x15, 0xAE, 0x78, 0x03, 0x87, 0xA4, - 0xB8, 0x38, 0xCF, 0x3F, 0x08, 0x67, 0x09, 0x94, 0xEB, 0x26, 0xA8, 0x6B, - 0xBD, 0x18, 0x34, 0x1B, 0xBB, 0xBF, 0x72, 0xF7, 0x40, 0x35, 0x48, 0x9C, - 0x51, 0x2F, 0x3B, 0x55, 0xE3, 0xC0, 0x9F, 0xD8, 0xD3, 0xF3, 0x8D, 0xB1, - 0xFF, 0xA7, 0x3E, 0xDC, 0x86, 0x77, 0xD7, 0xA6, 0x11, 0xFB, 0xF4, 0xBA, - 0x92, 0x91, 0x64, 0x83, 0xF1, 0x33, 0xEF, 0xDA, 0x2C, 0xB5, 0xB2, 0x2B, - 0x88, 0xD1, 0x99, 0xCB, 0x8C, 0x84, 0x1D, 0x14, 0x81, 0x97, 0x71, 0xCA, - 0x5F, 0xA3, 0x8B, 0x57, 0x3C, 0x82, 0xC4, 0x52, 0x5C, 0x1C, 0xE8, 0xA0, - 0x04, 0xB4, 0x85, 0x4A, 0xF6, 0x13, 0x54, 0xB6, 0xDF, 0x0C, 0x1A, 0x8E, - 0xDE, 0xE0, 0x39, 0xFC, 0x20, 0x9B, 0x24, 0x4E, 0xA9, 0x98, 0x9E, 0xAB, - 0xF2, 0x60, 0xD0, 0x6C, 0xEA, 0xFA, 0xC7, 0xD9, 0x00, 0xD4, 0x1F, 0x6E, - 0x43, 0xBC, 0xEC, 0x53, 0x89, 0xFE, 0x7A, 0x5D, 0x49, 0xC9, 0x32, 0xC2, - 0xF9, 0x9A, 0xF8, 0x6D, 0x16, 0xDB, 0x59, 0x96, 0x44, 0xE9, 0xCD, 0xE6, - 0x46, 0x42, 0x8F, 0x0A, 0xC1, 0xCC, 0xB9, 0x65, 0xB0, 0xD2, 0xC6, 0xAC, - 0x1E, 0x41, 0x62, 0x29, 0x2E, 0x0E, 0x74, 0x50, 0x02, 0x5A, 0xC3, 0x25, - 0x7B, 0x8A, 0x2A, 0x5B, 0xF0, 0x06, 0x0D, 0x47, 0x6F, 0x70, 0x9D, 0x7E, - 0x10, 0xCE, 0x12, 0x27, 0xD5, 0x4C, 0x4F, 0xD6, 0x79, 0x30, 0x68, 0x36, - 0x75, 0x7D, 0xE4, 0xED, 0x80, 0x6A, 0x90, 0x37, 0xA2, 0x5E, 0x76, 0xAA, - 0xC5, 0x7F, 0x3D, 0xAF, 0xA5, 0xE5, 0x19, 0x61, 0xFD, 0x4D, 0x7C, 0xB7, - 0x0B, 0xEE, 0xAD, 0x4B, 0x22, 0xF5, 0xE7, 0x73, 0x23, 0x21, 0xC8, 0x05, - 0xE1, 0x66, 0xDD, 0xB3, 0x58, 0x69, 0x63, 0x56, 0x0F, 0xA1, 0x31, 0x95, - 0x17, 0x07, 0x3A, 0x28 }; - -const byte LOG[512] = { - 0x80, 0x00, 0xB0, 0x09, 0x60, 0xEF, 0xB9, 0xFD, 0x10, 0x12, 0x9F, 0xE4, - 0x69, 0xBA, 0xAD, 0xF8, 0xC0, 0x38, 0xC2, 0x65, 0x4F, 0x06, 0x94, 0xFC, - 0x19, 0xDE, 0x6A, 0x1B, 0x5D, 0x4E, 0xA8, 0x82, 0x70, 0xED, 0xE8, 0xEC, - 0x72, 0xB3, 0x15, 0xC3, 0xFF, 0xAB, 0xB6, 0x47, 0x44, 0x01, 0xAC, 0x25, - 0xC9, 0xFA, 0x8E, 0x41, 0x1A, 0x21, 0xCB, 0xD3, 0x0D, 0x6E, 0xFE, 0x26, - 0x58, 0xDA, 0x32, 0x0F, 0x20, 0xA9, 0x9D, 0x84, 0x98, 0x05, 0x9C, 0xBB, - 0x22, 0x8C, 0x63, 0xE7, 0xC5, 0xE1, 0x73, 0xC6, 0xAF, 0x24, 0x5B, 0x87, - 0x66, 0x27, 0xF7, 0x57, 0xF4, 0x96, 0xB1, 0xB7, 0x5C, 0x8B, 0xD5, 0x54, - 0x79, 0xDF, 0xAA, 0xF6, 0x3E, 0xA3, 0xF1, 0x11, 0xCA, 0xF5, 0xD1, 0x17, - 0x7B, 0x93, 0x83, 0xBC, 0xBD, 0x52, 0x1E, 0xEB, 0xAE, 0xCC, 0xD6, 0x35, - 0x08, 0xC8, 0x8A, 0xB4, 0xE2, 0xCD, 0xBF, 0xD9, 0xD0, 0x50, 0x59, 0x3F, - 0x4D, 0x62, 0x34, 0x0A, 0x48, 0x88, 0xB5, 0x56, 0x4C, 0x2E, 0x6B, 0x9E, - 0xD2, 0x3D, 0x3C, 0x03, 0x13, 0xFB, 0x97, 0x51, 0x75, 0x4A, 0x91, 0x71, - 0x23, 0xBE, 0x76, 0x2A, 0x5F, 0xF9, 0xD4, 0x55, 0x0B, 0xDC, 0x37, 0x31, - 0x16, 0x74, 0xD7, 0x77, 0xA7, 0xE6, 0x07, 0xDB, 0xA4, 0x2F, 0x46, 0xF3, - 0x61, 0x45, 0x67, 0xE3, 0x0C, 0xA2, 0x3B, 0x1C, 0x85, 0x18, 0x04, 0x1D, - 0x29, 0xA0, 0x8F, 0xB2, 0x5A, 0xD8, 0xA6, 0x7E, 0xEE, 0x8D, 0x53, 0x4B, - 0xA1, 0x9A, 0xC1, 0x0E, 0x7A, 0x49, 0xA5, 0x2C, 0x81, 0xC4, 0xC7, 0x36, - 0x2B, 0x7F, 0x43, 0x95, 0x33, 0xF2, 0x6C, 0x68, 0x6D, 0xF0, 0x02, 0x28, - 0xCE, 0xDD, 0x9B, 0xEA, 0x5E, 0x99, 0x7C, 0x14, 0x86, 0xCF, 0xE5, 0x42, - 0xB8, 0x40, 0x78, 0x2D, 0x3A, 0xE9, 0x64, 0x1F, 0x92, 0x90, 0x7D, 0x39, - 0x6F, 0xE0, 0x89, 0x30, 0x80, 0x00, 0xB0, 0x09, 0x60, 0xEF, 0xB9, 0xFD, - 0x10, 0x12, 0x9F, 0xE4, 0x69, 0xBA, 0xAD, 0xF8, 0xC0, 0x38, 0xC2, 0x65, - 0x4F, 0x06, 0x94, 0xFC, 0x19, 0xDE, 0x6A, 0x1B, 0x5D, 0x4E, 0xA8, 0x82, - 0x70, 0xED, 0xE8, 0xEC, 0x72, 0xB3, 0x15, 0xC3, 0xFF, 0xAB, 0xB6, 0x47, - 0x44, 0x01, 0xAC, 0x25, 0xC9, 0xFA, 0x8E, 0x41, 0x1A, 0x21, 0xCB, 0xD3, - 0x0D, 0x6E, 0xFE, 0x26, 0x58, 0xDA, 0x32, 0x0F, 0x20, 0xA9, 0x9D, 0x84, - 0x98, 0x05, 0x9C, 0xBB, 0x22, 0x8C, 0x63, 0xE7, 0xC5, 0xE1, 0x73, 0xC6, - 0xAF, 0x24, 0x5B, 0x87, 0x66, 0x27, 0xF7, 0x57, 0xF4, 0x96, 0xB1, 0xB7, - 0x5C, 0x8B, 0xD5, 0x54, 0x79, 0xDF, 0xAA, 0xF6, 0x3E, 0xA3, 0xF1, 0x11, - 0xCA, 0xF5, 0xD1, 0x17, 0x7B, 0x93, 0x83, 0xBC, 0xBD, 0x52, 0x1E, 0xEB, - 0xAE, 0xCC, 0xD6, 0x35, 0x08, 0xC8, 0x8A, 0xB4, 0xE2, 0xCD, 0xBF, 0xD9, - 0xD0, 0x50, 0x59, 0x3F, 0x4D, 0x62, 0x34, 0x0A, 0x48, 0x88, 0xB5, 0x56, - 0x4C, 0x2E, 0x6B, 0x9E, 0xD2, 0x3D, 0x3C, 0x03, 0x13, 0xFB, 0x97, 0x51, - 0x75, 0x4A, 0x91, 0x71, 0x23, 0xBE, 0x76, 0x2A, 0x5F, 0xF9, 0xD4, 0x55, - 0x0B, 0xDC, 0x37, 0x31, 0x16, 0x74, 0xD7, 0x77, 0xA7, 0xE6, 0x07, 0xDB, - 0xA4, 0x2F, 0x46, 0xF3, 0x61, 0x45, 0x67, 0xE3, 0x0C, 0xA2, 0x3B, 0x1C, - 0x85, 0x18, 0x04, 0x1D, 0x29, 0xA0, 0x8F, 0xB2, 0x5A, 0xD8, 0xA6, 0x7E, - 0xEE, 0x8D, 0x53, 0x4B, 0xA1, 0x9A, 0xC1, 0x0E, 0x7A, 0x49, 0xA5, 0x2C, - 0x81, 0xC4, 0xC7, 0x36, 0x2B, 0x7F, 0x43, 0x95, 0x33, 0xF2, 0x6C, 0x68, - 0x6D, 0xF0, 0x02, 0x28, 0xCE, 0xDD, 0x9B, 0xEA, 0x5E, 0x99, 0x7C, 0x14, - 0x86, 0xCF, 0xE5, 0x42, 0xB8, 0x40, 0x78, 0x2D, 0x3A, 0xE9, 0x64, 0x1F, - 0x92, 0x90, 0x7D, 0x39, 0x6F, 0xE0, 0x89, 0x30 }; - -} - -/* -* SAFER-SK Encryption -*/ -void SAFER_SK::encrypt_n(const byte in[], byte out[], size_t blocks) const - { - const size_t rounds = get_rounds(); - - for(size_t i = 0; i != blocks; ++i) - { - byte A = in[0], B = in[1], C = in[2], D = in[3], - E = in[4], F = in[5], G = in[6], H = in[7], X, Y; - - for(size_t j = 0; j != 16*rounds; j += 16) - { - A = EXP[A ^ EK[j ]]; B = LOG[B + EK[j+1]]; - C = LOG[C + EK[j+2]]; D = EXP[D ^ EK[j+3]]; - E = EXP[E ^ EK[j+4]]; F = LOG[F + EK[j+5]]; - G = LOG[G + EK[j+6]]; H = EXP[H ^ EK[j+7]]; - - A += EK[j+ 8]; B ^= EK[j+ 9]; C ^= EK[j+10]; D += EK[j+11]; - E += EK[j+12]; F ^= EK[j+13]; G ^= EK[j+14]; H += EK[j+15]; - - B += A; D += C; F += E; H += G; A += B; C += D; E += F; G += H; - C += A; G += E; D += B; H += F; A += C; E += G; B += D; F += H; - H += D; Y = D + H; D = B + F; X = B + D; B = A + E; - A += B; F = C + G; E = C + F; C = X; G = Y; - } - - out[0] = A ^ EK[16*rounds+0]; out[1] = B + EK[16*rounds+1]; - out[2] = C + EK[16*rounds+2]; out[3] = D ^ EK[16*rounds+3]; - out[4] = E ^ EK[16*rounds+4]; out[5] = F + EK[16*rounds+5]; - out[6] = G + EK[16*rounds+6]; out[7] = H ^ EK[16*rounds+7]; - - in += BLOCK_SIZE; - out += BLOCK_SIZE; - } - } - -/* -* SAFER-SK Decryption -*/ -void SAFER_SK::decrypt_n(const byte in[], byte out[], size_t blocks) const - { - const size_t rounds = get_rounds(); - - for(size_t i = 0; i != blocks; ++i) - { - byte A = in[0], B = in[1], C = in[2], D = in[3], - E = in[4], F = in[5], G = in[6], H = in[7]; - - A ^= EK[16*rounds+0]; B -= EK[16*rounds+1]; C -= EK[16*rounds+2]; - D ^= EK[16*rounds+3]; E ^= EK[16*rounds+4]; F -= EK[16*rounds+5]; - G -= EK[16*rounds+6]; H ^= EK[16*rounds+7]; - - for(s32bit j = 16*(rounds-1); j >= 0; j -= 16) - { - byte T = E; E = B; B = C; C = T; T = F; F = D; D = G; G = T; - A -= E; B -= F; C -= G; D -= H; E -= A; F -= B; G -= C; H -= D; - A -= C; E -= G; B -= D; F -= H; C -= A; G -= E; D -= B; H -= F; - A -= B; C -= D; E -= F; G -= H; B -= A; D -= C; F -= E; H -= G; - - A = LOG[A - EK[j+8 ] + 256]; B = EXP[B ^ EK[j+9 ]]; - C = EXP[C ^ EK[j+10]]; D = LOG[D - EK[j+11] + 256]; - E = LOG[E - EK[j+12] + 256]; F = EXP[F ^ EK[j+13]]; - G = EXP[G ^ EK[j+14]]; H = LOG[H - EK[j+15] + 256]; - - A ^= EK[j+0]; B -= EK[j+1]; C -= EK[j+2]; D ^= EK[j+3]; - E ^= EK[j+4]; F -= EK[j+5]; G -= EK[j+6]; H ^= EK[j+7]; - } - - out[0] = A; out[1] = B; out[2] = C; out[3] = D; - out[4] = E; out[5] = F; out[6] = G; out[7] = H; - - in += BLOCK_SIZE; - out += BLOCK_SIZE; - } - } - -/* -* SAFER-SK Key Schedule -*/ -void SAFER_SK::key_schedule(const byte key[], size_t) - { - const byte BIAS[208] = { - 0x16, 0x73, 0x3B, 0x1E, 0x8E, 0x70, 0xBD, 0x86, 0x47, 0x7E, 0x24, 0x56, - 0xF1, 0x77, 0x88, 0x46, 0xB1, 0xBA, 0xA3, 0xB7, 0x10, 0x0A, 0xC5, 0x37, - 0xC9, 0x5A, 0x28, 0xAC, 0x64, 0xA5, 0xEC, 0xAB, 0xC6, 0x67, 0x95, 0x58, - 0x0D, 0xF8, 0x9A, 0xF6, 0x66, 0xDC, 0x05, 0x3D, 0xD3, 0x8A, 0xC3, 0xD8, - 0x6A, 0xE9, 0x36, 0x49, 0x43, 0xBF, 0xEB, 0xD4, 0x9B, 0x68, 0xA0, 0x65, - 0x5D, 0x57, 0x92, 0x1F, 0x71, 0x5C, 0xBB, 0x22, 0xC1, 0xBE, 0x7B, 0xBC, - 0x63, 0x94, 0x5F, 0x2A, 0x61, 0xB8, 0x34, 0x32, 0xFD, 0xFB, 0x17, 0x40, - 0xE6, 0x51, 0x1D, 0x41, 0x8F, 0x29, 0xDD, 0x04, 0x80, 0xDE, 0xE7, 0x31, - 0x7F, 0x01, 0xA2, 0xF7, 0x39, 0xDA, 0x6F, 0x23, 0xFE, 0x3A, 0xD0, 0x1C, - 0xD1, 0x30, 0x3E, 0x12, 0xCD, 0x0F, 0xE0, 0xA8, 0xAF, 0x82, 0x59, 0x2C, - 0x7D, 0xAD, 0xB2, 0xEF, 0xC2, 0x87, 0xCE, 0x75, 0x13, 0x02, 0x90, 0x4F, - 0x2E, 0x72, 0x33, 0x85, 0x8D, 0xCF, 0xA9, 0x81, 0xE2, 0xC4, 0x27, 0x2F, - 0x7A, 0x9F, 0x52, 0xE1, 0x15, 0x38, 0x2B, 0xFC, 0x42, 0xC7, 0x08, 0xE4, - 0x09, 0x55, 0x5E, 0x8C, 0x76, 0x60, 0xFF, 0xDF, 0xD7, 0x98, 0xFA, 0x0B, - 0x00, 0x1A, 0xF9, 0xA6, 0xB9, 0xE8, 0x9E, 0x62, 0xD9, 0x91, 0x50, 0xD2, - 0xEE, 0x18, 0xB4, 0x07, 0xEA, 0x5B, 0xA4, 0xC8, 0x0E, 0xCB, 0x48, 0x69, - 0x4E, 0x9C, 0x35, 0x79, 0x45, 0x4D, 0x54, 0xE5, 0x3C, 0x0C, 0x4A, 0x8B, - 0x3F, 0xCC, 0xA7, 0xDB }; - - const byte KEY_INDEX[208] = { - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x0B, 0x0C, 0x0D, 0x0E, - 0x0F, 0x10, 0x11, 0x09, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x00, 0x01, - 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x09, 0x0A, 0x0B, 0x05, 0x06, 0x07, 0x08, - 0x00, 0x01, 0x02, 0x03, 0x0F, 0x10, 0x11, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, - 0x07, 0x08, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x11, 0x09, 0x0A, 0x0B, - 0x0C, 0x0D, 0x0E, 0x0F, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x02, 0x03, 0x04, 0x05, - 0x06, 0x07, 0x08, 0x00, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x09, 0x0A, - 0x04, 0x05, 0x06, 0x07, 0x08, 0x00, 0x01, 0x02, 0x0E, 0x0F, 0x10, 0x11, - 0x09, 0x0A, 0x0B, 0x0C, 0x06, 0x07, 0x08, 0x00, 0x01, 0x02, 0x03, 0x04, - 0x10, 0x11, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x08, 0x00, 0x01, 0x02, - 0x03, 0x04, 0x05, 0x06, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x0B, 0x0C, 0x0D, 0x0E, - 0x0F, 0x10, 0x11, 0x09, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x00, 0x01, - 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x09, 0x0A, 0x0B, 0x05, 0x06, 0x07, 0x08, - 0x00, 0x01, 0x02, 0x03, 0x0F, 0x10, 0x11, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, - 0x07, 0x08, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x11, 0x09, 0x0A, 0x0B, - 0x0C, 0x0D, 0x0E, 0x0F }; - - SecureVector KB(18); - - for(size_t i = 0; i != 8; ++i) - { - KB[ 8] ^= KB[i] = rotate_left(key[i], 5); - KB[17] ^= KB[i+9] = EK[i] = key[i+8]; - } - - for(size_t i = 0; i != get_rounds(); ++i) - { - for(size_t j = 0; j != 18; ++j) - KB[j] = rotate_left(KB[j], 6); - for(size_t j = 0; j != 16; ++j) - EK[16*i+j+8] = KB[KEY_INDEX[16*i+j]] + BIAS[16*i+j]; - } - } - -/* -* Return the name of this type -*/ -std::string SAFER_SK::name() const - { - return "SAFER-SK(" + to_string(get_rounds()) + ")"; - } - -/* -* Return a clone of this object -*/ -BlockCipher* SAFER_SK::clone() const - { - return new SAFER_SK(get_rounds()); - } - -/* -* SAFER-SK Constructor -*/ -SAFER_SK::SAFER_SK(size_t rounds) - { - if(rounds > 13 || rounds == 0) - throw Invalid_Argument(name() + ": Invalid number of rounds"); - - EK.resize(16 * rounds + 8); - } - -} -/* -* SEED -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -/* -* SEED G Function -*/ -u32bit SEED::G_FUNC::operator()(u32bit X) const - { - return (S0[get_byte(3, X)] ^ S1[get_byte(2, X)] ^ - S2[get_byte(1, X)] ^ S3[get_byte(0, X)]); - } - -/* -* SEED Encryption -*/ -void SEED::encrypt_n(const byte in[], byte out[], size_t blocks) const - { - for(size_t i = 0; i != blocks; ++i) - { - u32bit B0 = load_be(in, 0); - u32bit B1 = load_be(in, 1); - u32bit B2 = load_be(in, 2); - u32bit B3 = load_be(in, 3); - - G_FUNC G; - - for(size_t j = 0; j != 16; j += 2) - { - u32bit T0, T1; - - T0 = B2 ^ K[2*j]; - T1 = G(B2 ^ B3 ^ K[2*j+1]); - T0 = G(T1 + T0); - T1 = G(T1 + T0); - B1 ^= T1; - B0 ^= T0 + T1; - - T0 = B0 ^ K[2*j+2]; - T1 = G(B0 ^ B1 ^ K[2*j+3]); - T0 = G(T1 + T0); - T1 = G(T1 + T0); - B3 ^= T1; - B2 ^= T0 + T1; - } - - store_be(out, B2, B3, B0, B1); - - in += BLOCK_SIZE; - out += BLOCK_SIZE; - } - } - -/* -* SEED Decryption -*/ -void SEED::decrypt_n(const byte in[], byte out[], size_t blocks) const - { - for(size_t i = 0; i != blocks; ++i) - { - u32bit B0 = load_be(in, 0); - u32bit B1 = load_be(in, 1); - u32bit B2 = load_be(in, 2); - u32bit B3 = load_be(in, 3); - - G_FUNC G; - - for(size_t j = 0; j != 16; j += 2) - { - u32bit T0, T1; - - T0 = B2 ^ K[30-2*j]; - T1 = G(B2 ^ B3 ^ K[31-2*j]); - T0 = G(T1 + T0); - T1 = G(T1 + T0); - B1 ^= T1; - B0 ^= T0 + T1; - - T0 = B0 ^ K[28-2*j]; - T1 = G(B0 ^ B1 ^ K[29-2*j]); - T0 = G(T1 + T0); - T1 = G(T1 + T0); - B3 ^= T1; - B2 ^= T0 + T1; - } - - store_be(out, B2, B3, B0, B1); - - in += BLOCK_SIZE; - out += BLOCK_SIZE; - } - } - -/* -* SEED Key Schedule -*/ -void SEED::key_schedule(const byte key[], size_t) - { - const u32bit RC[16] = { - 0x9E3779B9, 0x3C6EF373, 0x78DDE6E6, 0xF1BBCDCC, - 0xE3779B99, 0xC6EF3733, 0x8DDE6E67, 0x1BBCDCCF, - 0x3779B99E, 0x6EF3733C, 0xDDE6E678, 0xBBCDCCF1, - 0x779B99E3, 0xEF3733C6, 0xDE6E678D, 0xBCDCCF1B - }; - - SecureVector WK(4); - - for(size_t i = 0; i != 4; ++i) - WK[i] = load_be(key, i); - - G_FUNC G; - - for(size_t i = 0; i != 16; i += 2) - { - K[2*i ] = G(WK[0] + WK[2] - RC[i]); - K[2*i+1] = G(WK[1] - WK[3] + RC[i]) ^ K[2*i]; - - byte T = get_byte(3, WK[0]); - WK[0] = (WK[0] >> 8) | (get_byte(3, WK[1]) << 24); - WK[1] = (WK[1] >> 8) | (T << 24); - - K[2*i+2] = G(WK[0] + WK[2] - RC[i+1]); - K[2*i+3] = G(WK[1] - WK[3] + RC[i+1]) ^ K[2*i+2]; - - T = get_byte(0, WK[3]); - WK[3] = (WK[3] << 8) | get_byte(0, WK[2]); - WK[2] = (WK[2] << 8) | T; - } - } - -} -/* -* S-Box Tables for SEED -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -const u32bit SEED::G_FUNC::S0[256] = { - 0x2989A1A8, 0x05858184, 0x16C6D2D4, 0x13C3D3D0, 0x14445054, 0x1D0D111C, - 0x2C8CA0AC, 0x25052124, 0x1D4D515C, 0x03434340, 0x18081018, 0x1E0E121C, - 0x11415150, 0x3CCCF0FC, 0x0ACAC2C8, 0x23436360, 0x28082028, 0x04444044, - 0x20002020, 0x1D8D919C, 0x20C0E0E0, 0x22C2E2E0, 0x08C8C0C8, 0x17071314, - 0x2585A1A4, 0x0F8F838C, 0x03030300, 0x3B4B7378, 0x3B8BB3B8, 0x13031310, - 0x12C2D2D0, 0x2ECEE2EC, 0x30407070, 0x0C8C808C, 0x3F0F333C, 0x2888A0A8, - 0x32023230, 0x1DCDD1DC, 0x36C6F2F4, 0x34447074, 0x2CCCE0EC, 0x15859194, - 0x0B0B0308, 0x17475354, 0x1C4C505C, 0x1B4B5358, 0x3D8DB1BC, 0x01010100, - 0x24042024, 0x1C0C101C, 0x33437370, 0x18889098, 0x10001010, 0x0CCCC0CC, - 0x32C2F2F0, 0x19C9D1D8, 0x2C0C202C, 0x27C7E3E4, 0x32427270, 0x03838380, - 0x1B8B9398, 0x11C1D1D0, 0x06868284, 0x09C9C1C8, 0x20406060, 0x10405050, - 0x2383A3A0, 0x2BCBE3E8, 0x0D0D010C, 0x3686B2B4, 0x1E8E929C, 0x0F4F434C, - 0x3787B3B4, 0x1A4A5258, 0x06C6C2C4, 0x38487078, 0x2686A2A4, 0x12021210, - 0x2F8FA3AC, 0x15C5D1D4, 0x21416160, 0x03C3C3C0, 0x3484B0B4, 0x01414140, - 0x12425250, 0x3D4D717C, 0x0D8D818C, 0x08080008, 0x1F0F131C, 0x19899198, - 0x00000000, 0x19091118, 0x04040004, 0x13435350, 0x37C7F3F4, 0x21C1E1E0, - 0x3DCDF1FC, 0x36467274, 0x2F0F232C, 0x27072324, 0x3080B0B0, 0x0B8B8388, - 0x0E0E020C, 0x2B8BA3A8, 0x2282A2A0, 0x2E4E626C, 0x13839390, 0x0D4D414C, - 0x29496168, 0x3C4C707C, 0x09090108, 0x0A0A0208, 0x3F8FB3BC, 0x2FCFE3EC, - 0x33C3F3F0, 0x05C5C1C4, 0x07878384, 0x14041014, 0x3ECEF2FC, 0x24446064, - 0x1ECED2DC, 0x2E0E222C, 0x0B4B4348, 0x1A0A1218, 0x06060204, 0x21012120, - 0x2B4B6368, 0x26466264, 0x02020200, 0x35C5F1F4, 0x12829290, 0x0A8A8288, - 0x0C0C000C, 0x3383B3B0, 0x3E4E727C, 0x10C0D0D0, 0x3A4A7278, 0x07474344, - 0x16869294, 0x25C5E1E4, 0x26062224, 0x00808080, 0x2D8DA1AC, 0x1FCFD3DC, - 0x2181A1A0, 0x30003030, 0x37073334, 0x2E8EA2AC, 0x36063234, 0x15051114, - 0x22022220, 0x38083038, 0x34C4F0F4, 0x2787A3A4, 0x05454144, 0x0C4C404C, - 0x01818180, 0x29C9E1E8, 0x04848084, 0x17879394, 0x35053134, 0x0BCBC3C8, - 0x0ECEC2CC, 0x3C0C303C, 0x31417170, 0x11011110, 0x07C7C3C4, 0x09898188, - 0x35457174, 0x3BCBF3F8, 0x1ACAD2D8, 0x38C8F0F8, 0x14849094, 0x19495158, - 0x02828280, 0x04C4C0C4, 0x3FCFF3FC, 0x09494148, 0x39093138, 0x27476364, - 0x00C0C0C0, 0x0FCFC3CC, 0x17C7D3D4, 0x3888B0B8, 0x0F0F030C, 0x0E8E828C, - 0x02424240, 0x23032320, 0x11819190, 0x2C4C606C, 0x1BCBD3D8, 0x2484A0A4, - 0x34043034, 0x31C1F1F0, 0x08484048, 0x02C2C2C0, 0x2F4F636C, 0x3D0D313C, - 0x2D0D212C, 0x00404040, 0x3E8EB2BC, 0x3E0E323C, 0x3C8CB0BC, 0x01C1C1C0, - 0x2A8AA2A8, 0x3A8AB2B8, 0x0E4E424C, 0x15455154, 0x3B0B3338, 0x1CCCD0DC, - 0x28486068, 0x3F4F737C, 0x1C8C909C, 0x18C8D0D8, 0x0A4A4248, 0x16465254, - 0x37477374, 0x2080A0A0, 0x2DCDE1EC, 0x06464244, 0x3585B1B4, 0x2B0B2328, - 0x25456164, 0x3ACAF2F8, 0x23C3E3E0, 0x3989B1B8, 0x3181B1B0, 0x1F8F939C, - 0x1E4E525C, 0x39C9F1F8, 0x26C6E2E4, 0x3282B2B0, 0x31013130, 0x2ACAE2E8, - 0x2D4D616C, 0x1F4F535C, 0x24C4E0E4, 0x30C0F0F0, 0x0DCDC1CC, 0x08888088, - 0x16061214, 0x3A0A3238, 0x18485058, 0x14C4D0D4, 0x22426260, 0x29092128, - 0x07070304, 0x33033330, 0x28C8E0E8, 0x1B0B1318, 0x05050104, 0x39497178, - 0x10809090, 0x2A4A6268, 0x2A0A2228, 0x1A8A9298 }; - -const u32bit SEED::G_FUNC::S1[256] = { - 0x38380830, 0xE828C8E0, 0x2C2D0D21, 0xA42686A2, 0xCC0FCFC3, 0xDC1ECED2, - 0xB03383B3, 0xB83888B0, 0xAC2F8FA3, 0x60204060, 0x54154551, 0xC407C7C3, - 0x44044440, 0x6C2F4F63, 0x682B4B63, 0x581B4B53, 0xC003C3C3, 0x60224262, - 0x30330333, 0xB43585B1, 0x28290921, 0xA02080A0, 0xE022C2E2, 0xA42787A3, - 0xD013C3D3, 0x90118191, 0x10110111, 0x04060602, 0x1C1C0C10, 0xBC3C8CB0, - 0x34360632, 0x480B4B43, 0xEC2FCFE3, 0x88088880, 0x6C2C4C60, 0xA82888A0, - 0x14170713, 0xC404C4C0, 0x14160612, 0xF434C4F0, 0xC002C2C2, 0x44054541, - 0xE021C1E1, 0xD416C6D2, 0x3C3F0F33, 0x3C3D0D31, 0x8C0E8E82, 0x98188890, - 0x28280820, 0x4C0E4E42, 0xF436C6F2, 0x3C3E0E32, 0xA42585A1, 0xF839C9F1, - 0x0C0D0D01, 0xDC1FCFD3, 0xD818C8D0, 0x282B0B23, 0x64264662, 0x783A4A72, - 0x24270723, 0x2C2F0F23, 0xF031C1F1, 0x70324272, 0x40024242, 0xD414C4D0, - 0x40014141, 0xC000C0C0, 0x70334373, 0x64274763, 0xAC2C8CA0, 0x880B8B83, - 0xF437C7F3, 0xAC2D8DA1, 0x80008080, 0x1C1F0F13, 0xC80ACAC2, 0x2C2C0C20, - 0xA82A8AA2, 0x34340430, 0xD012C2D2, 0x080B0B03, 0xEC2ECEE2, 0xE829C9E1, - 0x5C1D4D51, 0x94148490, 0x18180810, 0xF838C8F0, 0x54174753, 0xAC2E8EA2, - 0x08080800, 0xC405C5C1, 0x10130313, 0xCC0DCDC1, 0x84068682, 0xB83989B1, - 0xFC3FCFF3, 0x7C3D4D71, 0xC001C1C1, 0x30310131, 0xF435C5F1, 0x880A8A82, - 0x682A4A62, 0xB03181B1, 0xD011C1D1, 0x20200020, 0xD417C7D3, 0x00020202, - 0x20220222, 0x04040400, 0x68284860, 0x70314171, 0x04070703, 0xD81BCBD3, - 0x9C1D8D91, 0x98198991, 0x60214161, 0xBC3E8EB2, 0xE426C6E2, 0x58194951, - 0xDC1DCDD1, 0x50114151, 0x90108090, 0xDC1CCCD0, 0x981A8A92, 0xA02383A3, - 0xA82B8BA3, 0xD010C0D0, 0x80018181, 0x0C0F0F03, 0x44074743, 0x181A0A12, - 0xE023C3E3, 0xEC2CCCE0, 0x8C0D8D81, 0xBC3F8FB3, 0x94168692, 0x783B4B73, - 0x5C1C4C50, 0xA02282A2, 0xA02181A1, 0x60234363, 0x20230323, 0x4C0D4D41, - 0xC808C8C0, 0x9C1E8E92, 0x9C1C8C90, 0x383A0A32, 0x0C0C0C00, 0x2C2E0E22, - 0xB83A8AB2, 0x6C2E4E62, 0x9C1F8F93, 0x581A4A52, 0xF032C2F2, 0x90128292, - 0xF033C3F3, 0x48094941, 0x78384870, 0xCC0CCCC0, 0x14150511, 0xF83BCBF3, - 0x70304070, 0x74354571, 0x7C3F4F73, 0x34350531, 0x10100010, 0x00030303, - 0x64244460, 0x6C2D4D61, 0xC406C6C2, 0x74344470, 0xD415C5D1, 0xB43484B0, - 0xE82ACAE2, 0x08090901, 0x74364672, 0x18190911, 0xFC3ECEF2, 0x40004040, - 0x10120212, 0xE020C0E0, 0xBC3D8DB1, 0x04050501, 0xF83ACAF2, 0x00010101, - 0xF030C0F0, 0x282A0A22, 0x5C1E4E52, 0xA82989A1, 0x54164652, 0x40034343, - 0x84058581, 0x14140410, 0x88098981, 0x981B8B93, 0xB03080B0, 0xE425C5E1, - 0x48084840, 0x78394971, 0x94178793, 0xFC3CCCF0, 0x1C1E0E12, 0x80028282, - 0x20210121, 0x8C0C8C80, 0x181B0B13, 0x5C1F4F53, 0x74374773, 0x54144450, - 0xB03282B2, 0x1C1D0D11, 0x24250521, 0x4C0F4F43, 0x00000000, 0x44064642, - 0xEC2DCDE1, 0x58184850, 0x50124252, 0xE82BCBE3, 0x7C3E4E72, 0xD81ACAD2, - 0xC809C9C1, 0xFC3DCDF1, 0x30300030, 0x94158591, 0x64254561, 0x3C3C0C30, - 0xB43686B2, 0xE424C4E0, 0xB83B8BB3, 0x7C3C4C70, 0x0C0E0E02, 0x50104050, - 0x38390931, 0x24260622, 0x30320232, 0x84048480, 0x68294961, 0x90138393, - 0x34370733, 0xE427C7E3, 0x24240420, 0xA42484A0, 0xC80BCBC3, 0x50134353, - 0x080A0A02, 0x84078783, 0xD819C9D1, 0x4C0C4C40, 0x80038383, 0x8C0F8F83, - 0xCC0ECEC2, 0x383B0B33, 0x480A4A42, 0xB43787B3 }; - -const u32bit SEED::G_FUNC::S2[256] = { - 0xA1A82989, 0x81840585, 0xD2D416C6, 0xD3D013C3, 0x50541444, 0x111C1D0D, - 0xA0AC2C8C, 0x21242505, 0x515C1D4D, 0x43400343, 0x10181808, 0x121C1E0E, - 0x51501141, 0xF0FC3CCC, 0xC2C80ACA, 0x63602343, 0x20282808, 0x40440444, - 0x20202000, 0x919C1D8D, 0xE0E020C0, 0xE2E022C2, 0xC0C808C8, 0x13141707, - 0xA1A42585, 0x838C0F8F, 0x03000303, 0x73783B4B, 0xB3B83B8B, 0x13101303, - 0xD2D012C2, 0xE2EC2ECE, 0x70703040, 0x808C0C8C, 0x333C3F0F, 0xA0A82888, - 0x32303202, 0xD1DC1DCD, 0xF2F436C6, 0x70743444, 0xE0EC2CCC, 0x91941585, - 0x03080B0B, 0x53541747, 0x505C1C4C, 0x53581B4B, 0xB1BC3D8D, 0x01000101, - 0x20242404, 0x101C1C0C, 0x73703343, 0x90981888, 0x10101000, 0xC0CC0CCC, - 0xF2F032C2, 0xD1D819C9, 0x202C2C0C, 0xE3E427C7, 0x72703242, 0x83800383, - 0x93981B8B, 0xD1D011C1, 0x82840686, 0xC1C809C9, 0x60602040, 0x50501040, - 0xA3A02383, 0xE3E82BCB, 0x010C0D0D, 0xB2B43686, 0x929C1E8E, 0x434C0F4F, - 0xB3B43787, 0x52581A4A, 0xC2C406C6, 0x70783848, 0xA2A42686, 0x12101202, - 0xA3AC2F8F, 0xD1D415C5, 0x61602141, 0xC3C003C3, 0xB0B43484, 0x41400141, - 0x52501242, 0x717C3D4D, 0x818C0D8D, 0x00080808, 0x131C1F0F, 0x91981989, - 0x00000000, 0x11181909, 0x00040404, 0x53501343, 0xF3F437C7, 0xE1E021C1, - 0xF1FC3DCD, 0x72743646, 0x232C2F0F, 0x23242707, 0xB0B03080, 0x83880B8B, - 0x020C0E0E, 0xA3A82B8B, 0xA2A02282, 0x626C2E4E, 0x93901383, 0x414C0D4D, - 0x61682949, 0x707C3C4C, 0x01080909, 0x02080A0A, 0xB3BC3F8F, 0xE3EC2FCF, - 0xF3F033C3, 0xC1C405C5, 0x83840787, 0x10141404, 0xF2FC3ECE, 0x60642444, - 0xD2DC1ECE, 0x222C2E0E, 0x43480B4B, 0x12181A0A, 0x02040606, 0x21202101, - 0x63682B4B, 0x62642646, 0x02000202, 0xF1F435C5, 0x92901282, 0x82880A8A, - 0x000C0C0C, 0xB3B03383, 0x727C3E4E, 0xD0D010C0, 0x72783A4A, 0x43440747, - 0x92941686, 0xE1E425C5, 0x22242606, 0x80800080, 0xA1AC2D8D, 0xD3DC1FCF, - 0xA1A02181, 0x30303000, 0x33343707, 0xA2AC2E8E, 0x32343606, 0x11141505, - 0x22202202, 0x30383808, 0xF0F434C4, 0xA3A42787, 0x41440545, 0x404C0C4C, - 0x81800181, 0xE1E829C9, 0x80840484, 0x93941787, 0x31343505, 0xC3C80BCB, - 0xC2CC0ECE, 0x303C3C0C, 0x71703141, 0x11101101, 0xC3C407C7, 0x81880989, - 0x71743545, 0xF3F83BCB, 0xD2D81ACA, 0xF0F838C8, 0x90941484, 0x51581949, - 0x82800282, 0xC0C404C4, 0xF3FC3FCF, 0x41480949, 0x31383909, 0x63642747, - 0xC0C000C0, 0xC3CC0FCF, 0xD3D417C7, 0xB0B83888, 0x030C0F0F, 0x828C0E8E, - 0x42400242, 0x23202303, 0x91901181, 0x606C2C4C, 0xD3D81BCB, 0xA0A42484, - 0x30343404, 0xF1F031C1, 0x40480848, 0xC2C002C2, 0x636C2F4F, 0x313C3D0D, - 0x212C2D0D, 0x40400040, 0xB2BC3E8E, 0x323C3E0E, 0xB0BC3C8C, 0xC1C001C1, - 0xA2A82A8A, 0xB2B83A8A, 0x424C0E4E, 0x51541545, 0x33383B0B, 0xD0DC1CCC, - 0x60682848, 0x737C3F4F, 0x909C1C8C, 0xD0D818C8, 0x42480A4A, 0x52541646, - 0x73743747, 0xA0A02080, 0xE1EC2DCD, 0x42440646, 0xB1B43585, 0x23282B0B, - 0x61642545, 0xF2F83ACA, 0xE3E023C3, 0xB1B83989, 0xB1B03181, 0x939C1F8F, - 0x525C1E4E, 0xF1F839C9, 0xE2E426C6, 0xB2B03282, 0x31303101, 0xE2E82ACA, - 0x616C2D4D, 0x535C1F4F, 0xE0E424C4, 0xF0F030C0, 0xC1CC0DCD, 0x80880888, - 0x12141606, 0x32383A0A, 0x50581848, 0xD0D414C4, 0x62602242, 0x21282909, - 0x03040707, 0x33303303, 0xE0E828C8, 0x13181B0B, 0x01040505, 0x71783949, - 0x90901080, 0x62682A4A, 0x22282A0A, 0x92981A8A }; - -const u32bit SEED::G_FUNC::S3[256] = { - 0x08303838, 0xC8E0E828, 0x0D212C2D, 0x86A2A426, 0xCFC3CC0F, 0xCED2DC1E, - 0x83B3B033, 0x88B0B838, 0x8FA3AC2F, 0x40606020, 0x45515415, 0xC7C3C407, - 0x44404404, 0x4F636C2F, 0x4B63682B, 0x4B53581B, 0xC3C3C003, 0x42626022, - 0x03333033, 0x85B1B435, 0x09212829, 0x80A0A020, 0xC2E2E022, 0x87A3A427, - 0xC3D3D013, 0x81919011, 0x01111011, 0x06020406, 0x0C101C1C, 0x8CB0BC3C, - 0x06323436, 0x4B43480B, 0xCFE3EC2F, 0x88808808, 0x4C606C2C, 0x88A0A828, - 0x07131417, 0xC4C0C404, 0x06121416, 0xC4F0F434, 0xC2C2C002, 0x45414405, - 0xC1E1E021, 0xC6D2D416, 0x0F333C3F, 0x0D313C3D, 0x8E828C0E, 0x88909818, - 0x08202828, 0x4E424C0E, 0xC6F2F436, 0x0E323C3E, 0x85A1A425, 0xC9F1F839, - 0x0D010C0D, 0xCFD3DC1F, 0xC8D0D818, 0x0B23282B, 0x46626426, 0x4A72783A, - 0x07232427, 0x0F232C2F, 0xC1F1F031, 0x42727032, 0x42424002, 0xC4D0D414, - 0x41414001, 0xC0C0C000, 0x43737033, 0x47636427, 0x8CA0AC2C, 0x8B83880B, - 0xC7F3F437, 0x8DA1AC2D, 0x80808000, 0x0F131C1F, 0xCAC2C80A, 0x0C202C2C, - 0x8AA2A82A, 0x04303434, 0xC2D2D012, 0x0B03080B, 0xCEE2EC2E, 0xC9E1E829, - 0x4D515C1D, 0x84909414, 0x08101818, 0xC8F0F838, 0x47535417, 0x8EA2AC2E, - 0x08000808, 0xC5C1C405, 0x03131013, 0xCDC1CC0D, 0x86828406, 0x89B1B839, - 0xCFF3FC3F, 0x4D717C3D, 0xC1C1C001, 0x01313031, 0xC5F1F435, 0x8A82880A, - 0x4A62682A, 0x81B1B031, 0xC1D1D011, 0x00202020, 0xC7D3D417, 0x02020002, - 0x02222022, 0x04000404, 0x48606828, 0x41717031, 0x07030407, 0xCBD3D81B, - 0x8D919C1D, 0x89919819, 0x41616021, 0x8EB2BC3E, 0xC6E2E426, 0x49515819, - 0xCDD1DC1D, 0x41515011, 0x80909010, 0xCCD0DC1C, 0x8A92981A, 0x83A3A023, - 0x8BA3A82B, 0xC0D0D010, 0x81818001, 0x0F030C0F, 0x47434407, 0x0A12181A, - 0xC3E3E023, 0xCCE0EC2C, 0x8D818C0D, 0x8FB3BC3F, 0x86929416, 0x4B73783B, - 0x4C505C1C, 0x82A2A022, 0x81A1A021, 0x43636023, 0x03232023, 0x4D414C0D, - 0xC8C0C808, 0x8E929C1E, 0x8C909C1C, 0x0A32383A, 0x0C000C0C, 0x0E222C2E, - 0x8AB2B83A, 0x4E626C2E, 0x8F939C1F, 0x4A52581A, 0xC2F2F032, 0x82929012, - 0xC3F3F033, 0x49414809, 0x48707838, 0xCCC0CC0C, 0x05111415, 0xCBF3F83B, - 0x40707030, 0x45717435, 0x4F737C3F, 0x05313435, 0x00101010, 0x03030003, - 0x44606424, 0x4D616C2D, 0xC6C2C406, 0x44707434, 0xC5D1D415, 0x84B0B434, - 0xCAE2E82A, 0x09010809, 0x46727436, 0x09111819, 0xCEF2FC3E, 0x40404000, - 0x02121012, 0xC0E0E020, 0x8DB1BC3D, 0x05010405, 0xCAF2F83A, 0x01010001, - 0xC0F0F030, 0x0A22282A, 0x4E525C1E, 0x89A1A829, 0x46525416, 0x43434003, - 0x85818405, 0x04101414, 0x89818809, 0x8B93981B, 0x80B0B030, 0xC5E1E425, - 0x48404808, 0x49717839, 0x87939417, 0xCCF0FC3C, 0x0E121C1E, 0x82828002, - 0x01212021, 0x8C808C0C, 0x0B13181B, 0x4F535C1F, 0x47737437, 0x44505414, - 0x82B2B032, 0x0D111C1D, 0x05212425, 0x4F434C0F, 0x00000000, 0x46424406, - 0xCDE1EC2D, 0x48505818, 0x42525012, 0xCBE3E82B, 0x4E727C3E, 0xCAD2D81A, - 0xC9C1C809, 0xCDF1FC3D, 0x00303030, 0x85919415, 0x45616425, 0x0C303C3C, - 0x86B2B436, 0xC4E0E424, 0x8BB3B83B, 0x4C707C3C, 0x0E020C0E, 0x40505010, - 0x09313839, 0x06222426, 0x02323032, 0x84808404, 0x49616829, 0x83939013, - 0x07333437, 0xC7E3E427, 0x04202424, 0x84A0A424, 0xCBC3C80B, 0x43535013, - 0x0A02080A, 0x87838407, 0xC9D1D819, 0x4C404C0C, 0x83838003, 0x8F838C0F, - 0xCEC2CC0E, 0x0B33383B, 0x4A42480A, 0x87B3B437 }; - -} -/* -* Serpent -* (C) 1999-2007 Jack Lloyd -* -* The sbox expressions used here were discovered by Dag Arne Osvik and -* are described in his paper "Speeding Up Serpent". -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -namespace { - -/* -* Serpent Encryption S-Box 1 -*/ -inline void SBoxE1(u32bit& B0, u32bit& B1, u32bit& B2, u32bit& B3) - { - u32bit T0 = B0, T1 = B1, T2 = B2, T3 = B3, T4; - T3 ^= T0; T4 = T1; T1 &= T3; T4 ^= T2; T1 ^= T0; T0 |= T3; T0 ^= T4; - T4 ^= T3; T3 ^= T2; T2 |= T1; T2 ^= T4; T4 = ~T4; T4 |= T1; T1 ^= T3; - T1 ^= T4; T3 |= T0; T1 ^= T3; T4 ^= T3; - B0 = T1; B1 = T4; B2 = T2; B3 = T0; - } - -/* -* Serpent Encryption S-Box 2 -*/ -inline void SBoxE2(u32bit& B0, u32bit& B1, u32bit& B2, u32bit& B3) - { - u32bit T0 = B0, T1 = B1, T2 = B2, T3 = B3, T4; - T0 = ~T0; T2 = ~T2; T4 = T0; T0 &= T1; T2 ^= T0; T0 |= T3; T3 ^= T2; - T1 ^= T0; T0 ^= T4; T4 |= T1; T1 ^= T3; T2 |= T0; T2 &= T4; T0 ^= T1; - T1 &= T2; T1 ^= T0; T0 &= T2; T0 ^= T4; - B0 = T2; B1 = T0; B2 = T3; B3 = T1; - } - -/* -* Serpent Encryption S-Box 3 -*/ -inline void SBoxE3(u32bit& B0, u32bit& B1, u32bit& B2, u32bit& B3) - { - u32bit T0 = B0, T1 = B1, T2 = B2, T3 = B3, T4; - T4 = T0; T0 &= T2; T0 ^= T3; T2 ^= T1; T2 ^= T0; T3 |= T4; T3 ^= T1; - T4 ^= T2; T1 = T3; T3 |= T4; T3 ^= T0; T0 &= T1; T4 ^= T0; T1 ^= T3; - T1 ^= T4; T4 = ~T4; - B0 = T2; B1 = T3; B2 = T1; B3 = T4; - } - -/* -* Serpent Encryption S-Box 4 -*/ -inline void SBoxE4(u32bit& B0, u32bit& B1, u32bit& B2, u32bit& B3) - { - u32bit T0 = B0, T1 = B1, T2 = B2, T3 = B3, T4; - T4 = T0; T0 |= T3; T3 ^= T1; T1 &= T4; T4 ^= T2; T2 ^= T3; T3 &= T0; - T4 |= T1; T3 ^= T4; T0 ^= T1; T4 &= T0; T1 ^= T3; T4 ^= T2; T1 |= T0; - T1 ^= T2; T0 ^= T3; T2 = T1; T1 |= T3; T1 ^= T0; - B0 = T1; B1 = T2; B2 = T3; B3 = T4; - } - -/* -* Serpent Encryption S-Box 5 -*/ -inline void SBoxE5(u32bit& B0, u32bit& B1, u32bit& B2, u32bit& B3) - { - u32bit T0 = B0, T1 = B1, T2 = B2, T3 = B3, T4; - T1 ^= T3; T3 = ~T3; T2 ^= T3; T3 ^= T0; T4 = T1; T1 &= T3; T1 ^= T2; - T4 ^= T3; T0 ^= T4; T2 &= T4; T2 ^= T0; T0 &= T1; T3 ^= T0; T4 |= T1; - T4 ^= T0; T0 |= T3; T0 ^= T2; T2 &= T3; T0 = ~T0; T4 ^= T2; - B0 = T1; B1 = T4; B2 = T0; B3 = T3; - } - -/* -* Serpent Encryption S-Box 6 -*/ -inline void SBoxE6(u32bit& B0, u32bit& B1, u32bit& B2, u32bit& B3) - { - u32bit T0 = B0, T1 = B1, T2 = B2, T3 = B3, T4; - T0 ^= T1; T1 ^= T3; T3 = ~T3; T4 = T1; T1 &= T0; T2 ^= T3; T1 ^= T2; - T2 |= T4; T4 ^= T3; T3 &= T1; T3 ^= T0; T4 ^= T1; T4 ^= T2; T2 ^= T0; - T0 &= T3; T2 = ~T2; T0 ^= T4; T4 |= T3; T2 ^= T4; - B0 = T1; B1 = T3; B2 = T0; B3 = T2; - } - -/* -* Serpent Encryption S-Box 7 -*/ -inline void SBoxE7(u32bit& B0, u32bit& B1, u32bit& B2, u32bit& B3) - { - u32bit T0 = B0, T1 = B1, T2 = B2, T3 = B3, T4; - T2 = ~T2; T4 = T3; T3 &= T0; T0 ^= T4; T3 ^= T2; T2 |= T4; T1 ^= T3; - T2 ^= T0; T0 |= T1; T2 ^= T1; T4 ^= T0; T0 |= T3; T0 ^= T2; T4 ^= T3; - T4 ^= T0; T3 = ~T3; T2 &= T4; T2 ^= T3; - B0 = T0; B1 = T1; B2 = T4; B3 = T2; - } - -/* -* Serpent Encryption S-Box 8 -*/ -inline void SBoxE8(u32bit& B0, u32bit& B1, u32bit& B2, u32bit& B3) - { - u32bit T0 = B0, T1 = B1, T2 = B2, T3 = B3, T4; - T4 = T1; T1 |= T2; T1 ^= T3; T4 ^= T2; T2 ^= T1; T3 |= T4; T3 &= T0; - T4 ^= T2; T3 ^= T1; T1 |= T4; T1 ^= T0; T0 |= T4; T0 ^= T2; T1 ^= T4; - T2 ^= T1; T1 &= T0; T1 ^= T4; T2 = ~T2; T2 |= T0; T4 ^= T2; - B0 = T4; B1 = T3; B2 = T1; B3 = T0; - } - -/* -* Serpent Decryption S-Box 1 -*/ -inline void SBoxD1(u32bit& B0, u32bit& B1, u32bit& B2, u32bit& B3) - { - u32bit T0 = B0, T1 = B1, T2 = B2, T3 = B3, T4; - T2 = ~T2; T4 = T1; T1 |= T0; T4 = ~T4; T1 ^= T2; T2 |= T4; T1 ^= T3; - T0 ^= T4; T2 ^= T0; T0 &= T3; T4 ^= T0; T0 |= T1; T0 ^= T2; T3 ^= T4; - T2 ^= T1; T3 ^= T0; T3 ^= T1; T2 &= T3; T4 ^= T2; - B0 = T0; B1 = T4; B2 = T1; B3 = T3; - } - -/* -* Serpent Decryption S-Box 2 -*/ -inline void SBoxD2(u32bit& B0, u32bit& B1, u32bit& B2, u32bit& B3) - { - u32bit T0 = B0, T1 = B1, T2 = B2, T3 = B3, T4; - T4 = T1; T1 ^= T3; T3 &= T1; T4 ^= T2; T3 ^= T0; T0 |= T1; T2 ^= T3; - T0 ^= T4; T0 |= T2; T1 ^= T3; T0 ^= T1; T1 |= T3; T1 ^= T0; T4 = ~T4; - T4 ^= T1; T1 |= T0; T1 ^= T0; T1 |= T4; T3 ^= T1; - B0 = T4; B1 = T0; B2 = T3; B3 = T2; - } - -/* -* Serpent Decryption S-Box 3 -*/ -inline void SBoxD3(u32bit& B0, u32bit& B1, u32bit& B2, u32bit& B3) - { - u32bit T0 = B0, T1 = B1, T2 = B2, T3 = B3, T4; - T2 ^= T3; T3 ^= T0; T4 = T3; T3 &= T2; T3 ^= T1; T1 |= T2; T1 ^= T4; - T4 &= T3; T2 ^= T3; T4 &= T0; T4 ^= T2; T2 &= T1; T2 |= T0; T3 = ~T3; - T2 ^= T3; T0 ^= T3; T0 &= T1; T3 ^= T4; T3 ^= T0; - B0 = T1; B1 = T4; B2 = T2; B3 = T3; - } - -/* -* Serpent Decryption S-Box 4 -*/ -inline void SBoxD4(u32bit& B0, u32bit& B1, u32bit& B2, u32bit& B3) - { - u32bit T0 = B0, T1 = B1, T2 = B2, T3 = B3, T4; - T4 = T2; T2 ^= T1; T0 ^= T2; T4 &= T2; T4 ^= T0; T0 &= T1; T1 ^= T3; - T3 |= T4; T2 ^= T3; T0 ^= T3; T1 ^= T4; T3 &= T2; T3 ^= T1; T1 ^= T0; - T1 |= T2; T0 ^= T3; T1 ^= T4; T0 ^= T1; - B0 = T2; B1 = T1; B2 = T3; B3 = T0; - } - -/* -* Serpent Decryption S-Box 5 -*/ -inline void SBoxD5(u32bit& B0, u32bit& B1, u32bit& B2, u32bit& B3) - { - u32bit T0 = B0, T1 = B1, T2 = B2, T3 = B3, T4; - T4 = T2; T2 &= T3; T2 ^= T1; T1 |= T3; T1 &= T0; T4 ^= T2; T4 ^= T1; - T1 &= T2; T0 = ~T0; T3 ^= T4; T1 ^= T3; T3 &= T0; T3 ^= T2; T0 ^= T1; - T2 &= T0; T3 ^= T0; T2 ^= T4; T2 |= T3; T3 ^= T0; T2 ^= T1; - B0 = T0; B1 = T3; B2 = T2; B3 = T4; - } - -/* -* Serpent Decryption S-Box 6 -*/ -inline void SBoxD6(u32bit& B0, u32bit& B1, u32bit& B2, u32bit& B3) - { - u32bit T0 = B0, T1 = B1, T2 = B2, T3 = B3, T4; - T1 = ~T1; T4 = T3; T2 ^= T1; T3 |= T0; T3 ^= T2; T2 |= T1; T2 &= T0; - T4 ^= T3; T2 ^= T4; T4 |= T0; T4 ^= T1; T1 &= T2; T1 ^= T3; T4 ^= T2; - T3 &= T4; T4 ^= T1; T3 ^= T4; T4 = ~T4; T3 ^= T0; - B0 = T1; B1 = T4; B2 = T3; B3 = T2; - } - -/* -* Serpent Decryption S-Box 7 -*/ -inline void SBoxD7(u32bit& B0, u32bit& B1, u32bit& B2, u32bit& B3) - { - u32bit T0 = B0, T1 = B1, T2 = B2, T3 = B3, T4; - T0 ^= T2; T4 = T2; T2 &= T0; T4 ^= T3; T2 = ~T2; T3 ^= T1; T2 ^= T3; - T4 |= T0; T0 ^= T2; T3 ^= T4; T4 ^= T1; T1 &= T3; T1 ^= T0; T0 ^= T3; - T0 |= T2; T3 ^= T1; T4 ^= T0; - B0 = T1; B1 = T2; B2 = T4; B3 = T3; - } - -/* -* Serpent Decryption S-Box 8 -*/ -inline void SBoxD8(u32bit& B0, u32bit& B1, u32bit& B2, u32bit& B3) - { - u32bit T0 = B0, T1 = B1, T2 = B2, T3 = B3, T4; - T4 = T2; T2 ^= T0; T0 &= T3; T4 |= T3; T2 = ~T2; T3 ^= T1; T1 |= T0; - T0 ^= T2; T2 &= T4; T3 &= T4; T1 ^= T2; T2 ^= T0; T0 |= T2; T4 ^= T1; - T0 ^= T3; T3 ^= T4; T4 |= T0; T3 ^= T2; T4 ^= T2; - B0 = T3; B1 = T0; B2 = T1; B3 = T4; - } - -/* -* Serpent's Linear Transformation -*/ -inline void transform(u32bit& B0, u32bit& B1, u32bit& B2, u32bit& B3) - { - B0 = rotate_left(B0, 13); B2 = rotate_left(B2, 3); - B1 ^= B0 ^ B2; B3 ^= B2 ^ (B0 << 3); - B1 = rotate_left(B1, 1); B3 = rotate_left(B3, 7); - B0 ^= B1 ^ B3; B2 ^= B3 ^ (B1 << 7); - B0 = rotate_left(B0, 5); B2 = rotate_left(B2, 22); - } - -/* -* Serpent's Inverse Linear Transformation -*/ -inline void i_transform(u32bit& B0, u32bit& B1, u32bit& B2, u32bit& B3) - { - B2 = rotate_right(B2, 22); B0 = rotate_right(B0, 5); - B2 ^= B3 ^ (B1 << 7); B0 ^= B1 ^ B3; - B3 = rotate_right(B3, 7); B1 = rotate_right(B1, 1); - B3 ^= B2 ^ (B0 << 3); B1 ^= B0 ^ B2; - B2 = rotate_right(B2, 3); B0 = rotate_right(B0, 13); - } - -} - -/* -* XOR a key block with a data block -*/ -#define key_xor(round, B0, B1, B2, B3) \ - B0 ^= round_key[4*round ]; \ - B1 ^= round_key[4*round+1]; \ - B2 ^= round_key[4*round+2]; \ - B3 ^= round_key[4*round+3]; - -/* -* Serpent Encryption -*/ -void Serpent::encrypt_n(const byte in[], byte out[], size_t blocks) const - { - for(size_t i = 0; i != blocks; ++i) - { - u32bit B0 = load_le(in, 0); - u32bit B1 = load_le(in, 1); - u32bit B2 = load_le(in, 2); - u32bit B3 = load_le(in, 3); - - key_xor( 0,B0,B1,B2,B3); SBoxE1(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor( 1,B0,B1,B2,B3); SBoxE2(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor( 2,B0,B1,B2,B3); SBoxE3(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor( 3,B0,B1,B2,B3); SBoxE4(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor( 4,B0,B1,B2,B3); SBoxE5(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor( 5,B0,B1,B2,B3); SBoxE6(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor( 6,B0,B1,B2,B3); SBoxE7(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor( 7,B0,B1,B2,B3); SBoxE8(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor( 8,B0,B1,B2,B3); SBoxE1(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor( 9,B0,B1,B2,B3); SBoxE2(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor(10,B0,B1,B2,B3); SBoxE3(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor(11,B0,B1,B2,B3); SBoxE4(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor(12,B0,B1,B2,B3); SBoxE5(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor(13,B0,B1,B2,B3); SBoxE6(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor(14,B0,B1,B2,B3); SBoxE7(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor(15,B0,B1,B2,B3); SBoxE8(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor(16,B0,B1,B2,B3); SBoxE1(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor(17,B0,B1,B2,B3); SBoxE2(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor(18,B0,B1,B2,B3); SBoxE3(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor(19,B0,B1,B2,B3); SBoxE4(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor(20,B0,B1,B2,B3); SBoxE5(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor(21,B0,B1,B2,B3); SBoxE6(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor(22,B0,B1,B2,B3); SBoxE7(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor(23,B0,B1,B2,B3); SBoxE8(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor(24,B0,B1,B2,B3); SBoxE1(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor(25,B0,B1,B2,B3); SBoxE2(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor(26,B0,B1,B2,B3); SBoxE3(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor(27,B0,B1,B2,B3); SBoxE4(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor(28,B0,B1,B2,B3); SBoxE5(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor(29,B0,B1,B2,B3); SBoxE6(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor(30,B0,B1,B2,B3); SBoxE7(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor(31,B0,B1,B2,B3); SBoxE8(B0,B1,B2,B3); key_xor(32,B0,B1,B2,B3); - - store_le(out, B0, B1, B2, B3); - - in += BLOCK_SIZE; - out += BLOCK_SIZE; - } - } - -/* -* Serpent Decryption -*/ -void Serpent::decrypt_n(const byte in[], byte out[], size_t blocks) const - { - for(size_t i = 0; i != blocks; ++i) - { - u32bit B0 = load_le(in, 0); - u32bit B1 = load_le(in, 1); - u32bit B2 = load_le(in, 2); - u32bit B3 = load_le(in, 3); - - key_xor(32,B0,B1,B2,B3); SBoxD8(B0,B1,B2,B3); key_xor(31,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD7(B0,B1,B2,B3); key_xor(30,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD6(B0,B1,B2,B3); key_xor(29,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD5(B0,B1,B2,B3); key_xor(28,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD4(B0,B1,B2,B3); key_xor(27,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD3(B0,B1,B2,B3); key_xor(26,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD2(B0,B1,B2,B3); key_xor(25,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD1(B0,B1,B2,B3); key_xor(24,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD8(B0,B1,B2,B3); key_xor(23,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD7(B0,B1,B2,B3); key_xor(22,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD6(B0,B1,B2,B3); key_xor(21,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD5(B0,B1,B2,B3); key_xor(20,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD4(B0,B1,B2,B3); key_xor(19,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD3(B0,B1,B2,B3); key_xor(18,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD2(B0,B1,B2,B3); key_xor(17,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD1(B0,B1,B2,B3); key_xor(16,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD8(B0,B1,B2,B3); key_xor(15,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD7(B0,B1,B2,B3); key_xor(14,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD6(B0,B1,B2,B3); key_xor(13,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD5(B0,B1,B2,B3); key_xor(12,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD4(B0,B1,B2,B3); key_xor(11,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD3(B0,B1,B2,B3); key_xor(10,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD2(B0,B1,B2,B3); key_xor( 9,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD1(B0,B1,B2,B3); key_xor( 8,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD8(B0,B1,B2,B3); key_xor( 7,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD7(B0,B1,B2,B3); key_xor( 6,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD6(B0,B1,B2,B3); key_xor( 5,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD5(B0,B1,B2,B3); key_xor( 4,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD4(B0,B1,B2,B3); key_xor( 3,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD3(B0,B1,B2,B3); key_xor( 2,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD2(B0,B1,B2,B3); key_xor( 1,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD1(B0,B1,B2,B3); key_xor( 0,B0,B1,B2,B3); - - store_le(out, B0, B1, B2, B3); - - in += BLOCK_SIZE; - out += BLOCK_SIZE; - } - } - -#undef key_xor -#undef transform -#undef i_transform - -/* -* Serpent Key Schedule -*/ -void Serpent::key_schedule(const byte key[], size_t length) - { - const u32bit PHI = 0x9E3779B9; - - SecureVector W(140); - for(size_t i = 0; i != length / 4; ++i) - W[i] = load_le(key, i); - - W[length / 4] |= u32bit(1) << ((length%4)*8); - - for(size_t i = 8; i != 140; ++i) - { - u32bit wi = W[i-8] ^ W[i-5] ^ W[i-3] ^ W[i-1] ^ PHI ^ u32bit(i-8); - W[i] = rotate_left(wi, 11); - } - - SBoxE4(W[ 8],W[ 9],W[ 10],W[ 11]); SBoxE3(W[ 12],W[ 13],W[ 14],W[ 15]); - SBoxE2(W[ 16],W[ 17],W[ 18],W[ 19]); SBoxE1(W[ 20],W[ 21],W[ 22],W[ 23]); - SBoxE8(W[ 24],W[ 25],W[ 26],W[ 27]); SBoxE7(W[ 28],W[ 29],W[ 30],W[ 31]); - SBoxE6(W[ 32],W[ 33],W[ 34],W[ 35]); SBoxE5(W[ 36],W[ 37],W[ 38],W[ 39]); - SBoxE4(W[ 40],W[ 41],W[ 42],W[ 43]); SBoxE3(W[ 44],W[ 45],W[ 46],W[ 47]); - SBoxE2(W[ 48],W[ 49],W[ 50],W[ 51]); SBoxE1(W[ 52],W[ 53],W[ 54],W[ 55]); - SBoxE8(W[ 56],W[ 57],W[ 58],W[ 59]); SBoxE7(W[ 60],W[ 61],W[ 62],W[ 63]); - SBoxE6(W[ 64],W[ 65],W[ 66],W[ 67]); SBoxE5(W[ 68],W[ 69],W[ 70],W[ 71]); - SBoxE4(W[ 72],W[ 73],W[ 74],W[ 75]); SBoxE3(W[ 76],W[ 77],W[ 78],W[ 79]); - SBoxE2(W[ 80],W[ 81],W[ 82],W[ 83]); SBoxE1(W[ 84],W[ 85],W[ 86],W[ 87]); - SBoxE8(W[ 88],W[ 89],W[ 90],W[ 91]); SBoxE7(W[ 92],W[ 93],W[ 94],W[ 95]); - SBoxE6(W[ 96],W[ 97],W[ 98],W[ 99]); SBoxE5(W[100],W[101],W[102],W[103]); - SBoxE4(W[104],W[105],W[106],W[107]); SBoxE3(W[108],W[109],W[110],W[111]); - SBoxE2(W[112],W[113],W[114],W[115]); SBoxE1(W[116],W[117],W[118],W[119]); - SBoxE8(W[120],W[121],W[122],W[123]); SBoxE7(W[124],W[125],W[126],W[127]); - SBoxE6(W[128],W[129],W[130],W[131]); SBoxE5(W[132],W[133],W[134],W[135]); - SBoxE4(W[136],W[137],W[138],W[139]); - round_key.copy(&W[8], 132); - } - -} -/* -* Serpent (SIMD) -* (C) 2009 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -namespace { - -#define SBoxE1(B0, B1, B2, B3) \ - do { \ - B3 ^= B0; \ - SIMD_32 B4 = B1; \ - B1 &= B3; \ - B4 ^= B2; \ - B1 ^= B0; \ - B0 |= B3; \ - B0 ^= B4; \ - B4 ^= B3; \ - B3 ^= B2; \ - B2 |= B1; \ - B2 ^= B4; \ - B4 = ~B4; \ - B4 |= B1; \ - B1 ^= B3; \ - B1 ^= B4; \ - B3 |= B0; \ - B1 ^= B3; \ - B4 ^= B3; \ - B3 = B0; \ - B0 = B1; \ - B1 = B4; \ - } while(0); - -#define SBoxE2(B0, B1, B2, B3) \ - do { \ - B0 = ~B0; \ - B2 = ~B2; \ - SIMD_32 B4 = B0; \ - B0 &= B1; \ - B2 ^= B0; \ - B0 |= B3; \ - B3 ^= B2; \ - B1 ^= B0; \ - B0 ^= B4; \ - B4 |= B1; \ - B1 ^= B3; \ - B2 |= B0; \ - B2 &= B4; \ - B0 ^= B1; \ - B1 &= B2; \ - B1 ^= B0; \ - B0 &= B2; \ - B4 ^= B0; \ - B0 = B2; \ - B2 = B3; \ - B3 = B1; \ - B1 = B4; \ - } while(0); - -#define SBoxE3(B0, B1, B2, B3) \ - do { \ - SIMD_32 B4 = B0; \ - B0 &= B2; \ - B0 ^= B3; \ - B2 ^= B1; \ - B2 ^= B0; \ - B3 |= B4; \ - B3 ^= B1; \ - B4 ^= B2; \ - B1 = B3; \ - B3 |= B4; \ - B3 ^= B0; \ - B0 &= B1; \ - B4 ^= B0; \ - B1 ^= B3; \ - B1 ^= B4; \ - B0 = B2; \ - B2 = B1; \ - B1 = B3; \ - B3 = ~B4; \ - } while(0); - -#define SBoxE4(B0, B1, B2, B3) \ - do { \ - SIMD_32 B4 = B0; \ - B0 |= B3; \ - B3 ^= B1; \ - B1 &= B4; \ - B4 ^= B2; \ - B2 ^= B3; \ - B3 &= B0; \ - B4 |= B1; \ - B3 ^= B4; \ - B0 ^= B1; \ - B4 &= B0; \ - B1 ^= B3; \ - B4 ^= B2; \ - B1 |= B0; \ - B1 ^= B2; \ - B0 ^= B3; \ - B2 = B1; \ - B1 |= B3; \ - B0 ^= B1; \ - B1 = B2; \ - B2 = B3; \ - B3 = B4; \ - } while(0); - -#define SBoxE5(B0, B1, B2, B3) \ - do { \ - B1 ^= B3; \ - B3 = ~B3; \ - B2 ^= B3; \ - B3 ^= B0; \ - SIMD_32 B4 = B1; \ - B1 &= B3; \ - B1 ^= B2; \ - B4 ^= B3; \ - B0 ^= B4; \ - B2 &= B4; \ - B2 ^= B0; \ - B0 &= B1; \ - B3 ^= B0; \ - B4 |= B1; \ - B4 ^= B0; \ - B0 |= B3; \ - B0 ^= B2; \ - B2 &= B3; \ - B0 = ~B0; \ - B4 ^= B2; \ - B2 = B0; \ - B0 = B1; \ - B1 = B4; \ - } while(0); - -#define SBoxE6(B0, B1, B2, B3) \ - do { \ - B0 ^= B1; \ - B1 ^= B3; \ - B3 = ~B3; \ - SIMD_32 B4 = B1; \ - B1 &= B0; \ - B2 ^= B3; \ - B1 ^= B2; \ - B2 |= B4; \ - B4 ^= B3; \ - B3 &= B1; \ - B3 ^= B0; \ - B4 ^= B1; \ - B4 ^= B2; \ - B2 ^= B0; \ - B0 &= B3; \ - B2 = ~B2; \ - B0 ^= B4; \ - B4 |= B3; \ - B4 ^= B2; \ - B2 = B0; \ - B0 = B1; \ - B1 = B3; \ - B3 = B4; \ - } while(0); - -#define SBoxE7(B0, B1, B2, B3) \ - do { \ - B2 = ~B2; \ - SIMD_32 B4 = B3; \ - B3 &= B0; \ - B0 ^= B4; \ - B3 ^= B2; \ - B2 |= B4; \ - B1 ^= B3; \ - B2 ^= B0; \ - B0 |= B1; \ - B2 ^= B1; \ - B4 ^= B0; \ - B0 |= B3; \ - B0 ^= B2; \ - B4 ^= B3; \ - B4 ^= B0; \ - B3 = ~B3; \ - B2 &= B4; \ - B3 ^= B2; \ - B2 = B4; \ - } while(0); - -#define SBoxE8(B0, B1, B2, B3) \ - do { \ - SIMD_32 B4 = B1; \ - B1 |= B2; \ - B1 ^= B3; \ - B4 ^= B2; \ - B2 ^= B1; \ - B3 |= B4; \ - B3 &= B0; \ - B4 ^= B2; \ - B3 ^= B1; \ - B1 |= B4; \ - B1 ^= B0; \ - B0 |= B4; \ - B0 ^= B2; \ - B1 ^= B4; \ - B2 ^= B1; \ - B1 &= B0; \ - B1 ^= B4; \ - B2 = ~B2; \ - B2 |= B0; \ - B4 ^= B2; \ - B2 = B1; \ - B1 = B3; \ - B3 = B0; \ - B0 = B4; \ - } while(0); - -#define SBoxD1(B0, B1, B2, B3) \ - do { \ - B2 = ~B2; \ - SIMD_32 B4 = B1; \ - B1 |= B0; \ - B4 = ~B4; \ - B1 ^= B2; \ - B2 |= B4; \ - B1 ^= B3; \ - B0 ^= B4; \ - B2 ^= B0; \ - B0 &= B3; \ - B4 ^= B0; \ - B0 |= B1; \ - B0 ^= B2; \ - B3 ^= B4; \ - B2 ^= B1; \ - B3 ^= B0; \ - B3 ^= B1; \ - B2 &= B3; \ - B4 ^= B2; \ - B2 = B1; \ - B1 = B4; \ - } while(0); - -#define SBoxD2(B0, B1, B2, B3) \ - do { \ - SIMD_32 B4 = B1; \ - B1 ^= B3; \ - B3 &= B1; \ - B4 ^= B2; \ - B3 ^= B0; \ - B0 |= B1; \ - B2 ^= B3; \ - B0 ^= B4; \ - B0 |= B2; \ - B1 ^= B3; \ - B0 ^= B1; \ - B1 |= B3; \ - B1 ^= B0; \ - B4 = ~B4; \ - B4 ^= B1; \ - B1 |= B0; \ - B1 ^= B0; \ - B1 |= B4; \ - B3 ^= B1; \ - B1 = B0; \ - B0 = B4; \ - B4 = B2; \ - B2 = B3; \ - B3 = B4; \ - } while(0); - -#define SBoxD3(B0, B1, B2, B3) \ - do { \ - B2 ^= B3; \ - B3 ^= B0; \ - SIMD_32 B4 = B3; \ - B3 &= B2; \ - B3 ^= B1; \ - B1 |= B2; \ - B1 ^= B4; \ - B4 &= B3; \ - B2 ^= B3; \ - B4 &= B0; \ - B4 ^= B2; \ - B2 &= B1; \ - B2 |= B0; \ - B3 = ~B3; \ - B2 ^= B3; \ - B0 ^= B3; \ - B0 &= B1; \ - B3 ^= B4; \ - B3 ^= B0; \ - B0 = B1; \ - B1 = B4; \ - } while(0); - -#define SBoxD4(B0, B1, B2, B3) \ - do { \ - SIMD_32 B4 = B2; \ - B2 ^= B1; \ - B0 ^= B2; \ - B4 &= B2; \ - B4 ^= B0; \ - B0 &= B1; \ - B1 ^= B3; \ - B3 |= B4; \ - B2 ^= B3; \ - B0 ^= B3; \ - B1 ^= B4; \ - B3 &= B2; \ - B3 ^= B1; \ - B1 ^= B0; \ - B1 |= B2; \ - B0 ^= B3; \ - B1 ^= B4; \ - B0 ^= B1; \ - B4 = B0; \ - B0 = B2; \ - B2 = B3; \ - B3 = B4; \ - } while(0); - -#define SBoxD5(B0, B1, B2, B3) \ - do { \ - SIMD_32 B4 = B2; \ - B2 &= B3; \ - B2 ^= B1; \ - B1 |= B3; \ - B1 &= B0; \ - B4 ^= B2; \ - B4 ^= B1; \ - B1 &= B2; \ - B0 = ~B0; \ - B3 ^= B4; \ - B1 ^= B3; \ - B3 &= B0; \ - B3 ^= B2; \ - B0 ^= B1; \ - B2 &= B0; \ - B3 ^= B0; \ - B2 ^= B4; \ - B2 |= B3; \ - B3 ^= B0; \ - B2 ^= B1; \ - B1 = B3; \ - B3 = B4; \ - } while(0); - -#define SBoxD6(B0, B1, B2, B3) \ - do { \ - B1 = ~B1; \ - SIMD_32 B4 = B3; \ - B2 ^= B1; \ - B3 |= B0; \ - B3 ^= B2; \ - B2 |= B1; \ - B2 &= B0; \ - B4 ^= B3; \ - B2 ^= B4; \ - B4 |= B0; \ - B4 ^= B1; \ - B1 &= B2; \ - B1 ^= B3; \ - B4 ^= B2; \ - B3 &= B4; \ - B4 ^= B1; \ - B3 ^= B4; \ - B4 = ~B4; \ - B3 ^= B0; \ - B0 = B1; \ - B1 = B4; \ - B4 = B3; \ - B3 = B2; \ - B2 = B4; \ - } while(0); - -#define SBoxD7(B0, B1, B2, B3) \ - do { \ - B0 ^= B2; \ - SIMD_32 B4 = B2; \ - B2 &= B0; \ - B4 ^= B3; \ - B2 = ~B2; \ - B3 ^= B1; \ - B2 ^= B3; \ - B4 |= B0; \ - B0 ^= B2; \ - B3 ^= B4; \ - B4 ^= B1; \ - B1 &= B3; \ - B1 ^= B0; \ - B0 ^= B3; \ - B0 |= B2; \ - B3 ^= B1; \ - B4 ^= B0; \ - B0 = B1; \ - B1 = B2; \ - B2 = B4; \ - } while(0); - -#define SBoxD8(B0, B1, B2, B3) \ - do { \ - SIMD_32 B4 = B2; \ - B2 ^= B0; \ - B0 &= B3; \ - B4 |= B3; \ - B2 = ~B2; \ - B3 ^= B1; \ - B1 |= B0; \ - B0 ^= B2; \ - B2 &= B4; \ - B3 &= B4; \ - B1 ^= B2; \ - B2 ^= B0; \ - B0 |= B2; \ - B4 ^= B1; \ - B0 ^= B3; \ - B3 ^= B4; \ - B4 |= B0; \ - B3 ^= B2; \ - B4 ^= B2; \ - B2 = B1; \ - B1 = B0; \ - B0 = B3; \ - B3 = B4; \ - } while(0); - -#define key_xor(round, B0, B1, B2, B3) \ - do { \ - B0 ^= SIMD_32(keys[4*round ]); \ - B1 ^= SIMD_32(keys[4*round+1]); \ - B2 ^= SIMD_32(keys[4*round+2]); \ - B3 ^= SIMD_32(keys[4*round+3]); \ - } while(0); - -/* -* Serpent's linear transformations -*/ -#define transform(B0, B1, B2, B3) \ - do { \ - B0.rotate_left(13); \ - B2.rotate_left(3); \ - B1 ^= B0 ^ B2; \ - B3 ^= B2 ^ (B0 << 3); \ - B1.rotate_left(1); \ - B3.rotate_left(7); \ - B0 ^= B1 ^ B3; \ - B2 ^= B3 ^ (B1 << 7); \ - B0.rotate_left(5); \ - B2.rotate_left(22); \ - } while(0); - -#define i_transform(B0, B1, B2, B3) \ - do { \ - B2.rotate_right(22); \ - B0.rotate_right(5); \ - B2 ^= B3 ^ (B1 << 7); \ - B0 ^= B1 ^ B3; \ - B3.rotate_right(7); \ - B1.rotate_right(1); \ - B3 ^= B2 ^ (B0 << 3); \ - B1 ^= B0 ^ B2; \ - B2.rotate_right(3); \ - B0.rotate_right(13); \ - } while(0); - -/* -* SIMD Serpent Encryption of 4 blocks in parallel -*/ -void serpent_encrypt_4(const byte in[64], - byte out[64], - const u32bit keys[132]) - { - SIMD_32 B0 = SIMD_32::load_le(in); - SIMD_32 B1 = SIMD_32::load_le(in + 16); - SIMD_32 B2 = SIMD_32::load_le(in + 32); - SIMD_32 B3 = SIMD_32::load_le(in + 48); - - SIMD_32::transpose(B0, B1, B2, B3); - - key_xor( 0,B0,B1,B2,B3); SBoxE1(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor( 1,B0,B1,B2,B3); SBoxE2(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor( 2,B0,B1,B2,B3); SBoxE3(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor( 3,B0,B1,B2,B3); SBoxE4(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor( 4,B0,B1,B2,B3); SBoxE5(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor( 5,B0,B1,B2,B3); SBoxE6(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor( 6,B0,B1,B2,B3); SBoxE7(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor( 7,B0,B1,B2,B3); SBoxE8(B0,B1,B2,B3); transform(B0,B1,B2,B3); - - key_xor( 8,B0,B1,B2,B3); SBoxE1(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor( 9,B0,B1,B2,B3); SBoxE2(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor(10,B0,B1,B2,B3); SBoxE3(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor(11,B0,B1,B2,B3); SBoxE4(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor(12,B0,B1,B2,B3); SBoxE5(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor(13,B0,B1,B2,B3); SBoxE6(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor(14,B0,B1,B2,B3); SBoxE7(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor(15,B0,B1,B2,B3); SBoxE8(B0,B1,B2,B3); transform(B0,B1,B2,B3); - - key_xor(16,B0,B1,B2,B3); SBoxE1(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor(17,B0,B1,B2,B3); SBoxE2(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor(18,B0,B1,B2,B3); SBoxE3(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor(19,B0,B1,B2,B3); SBoxE4(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor(20,B0,B1,B2,B3); SBoxE5(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor(21,B0,B1,B2,B3); SBoxE6(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor(22,B0,B1,B2,B3); SBoxE7(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor(23,B0,B1,B2,B3); SBoxE8(B0,B1,B2,B3); transform(B0,B1,B2,B3); - - key_xor(24,B0,B1,B2,B3); SBoxE1(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor(25,B0,B1,B2,B3); SBoxE2(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor(26,B0,B1,B2,B3); SBoxE3(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor(27,B0,B1,B2,B3); SBoxE4(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor(28,B0,B1,B2,B3); SBoxE5(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor(29,B0,B1,B2,B3); SBoxE6(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor(30,B0,B1,B2,B3); SBoxE7(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor(31,B0,B1,B2,B3); SBoxE8(B0,B1,B2,B3); key_xor(32,B0,B1,B2,B3); - - SIMD_32::transpose(B0, B1, B2, B3); - - B0.store_le(out); - B1.store_le(out + 16); - B2.store_le(out + 32); - B3.store_le(out + 48); - } - -/* -* SIMD Serpent Decryption of 4 blocks in parallel -*/ -void serpent_decrypt_4(const byte in[64], - byte out[64], - const u32bit keys[132]) - { - SIMD_32 B0 = SIMD_32::load_le(in); - SIMD_32 B1 = SIMD_32::load_le(in + 16); - SIMD_32 B2 = SIMD_32::load_le(in + 32); - SIMD_32 B3 = SIMD_32::load_le(in + 48); - - SIMD_32::transpose(B0, B1, B2, B3); - - key_xor(32,B0,B1,B2,B3); SBoxD8(B0,B1,B2,B3); key_xor(31,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD7(B0,B1,B2,B3); key_xor(30,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD6(B0,B1,B2,B3); key_xor(29,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD5(B0,B1,B2,B3); key_xor(28,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD4(B0,B1,B2,B3); key_xor(27,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD3(B0,B1,B2,B3); key_xor(26,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD2(B0,B1,B2,B3); key_xor(25,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD1(B0,B1,B2,B3); key_xor(24,B0,B1,B2,B3); - - i_transform(B0,B1,B2,B3); SBoxD8(B0,B1,B2,B3); key_xor(23,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD7(B0,B1,B2,B3); key_xor(22,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD6(B0,B1,B2,B3); key_xor(21,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD5(B0,B1,B2,B3); key_xor(20,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD4(B0,B1,B2,B3); key_xor(19,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD3(B0,B1,B2,B3); key_xor(18,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD2(B0,B1,B2,B3); key_xor(17,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD1(B0,B1,B2,B3); key_xor(16,B0,B1,B2,B3); - - i_transform(B0,B1,B2,B3); SBoxD8(B0,B1,B2,B3); key_xor(15,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD7(B0,B1,B2,B3); key_xor(14,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD6(B0,B1,B2,B3); key_xor(13,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD5(B0,B1,B2,B3); key_xor(12,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD4(B0,B1,B2,B3); key_xor(11,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD3(B0,B1,B2,B3); key_xor(10,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD2(B0,B1,B2,B3); key_xor( 9,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD1(B0,B1,B2,B3); key_xor( 8,B0,B1,B2,B3); - - i_transform(B0,B1,B2,B3); SBoxD8(B0,B1,B2,B3); key_xor( 7,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD7(B0,B1,B2,B3); key_xor( 6,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD6(B0,B1,B2,B3); key_xor( 5,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD5(B0,B1,B2,B3); key_xor( 4,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD4(B0,B1,B2,B3); key_xor( 3,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD3(B0,B1,B2,B3); key_xor( 2,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD2(B0,B1,B2,B3); key_xor( 1,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD1(B0,B1,B2,B3); key_xor( 0,B0,B1,B2,B3); - - SIMD_32::transpose(B0, B1, B2, B3); - - B0.store_le(out); - B1.store_le(out + 16); - B2.store_le(out + 32); - B3.store_le(out + 48); - } - -} - -#undef key_xor -#undef transform -#undef i_transform - -#undef SBoxE1 -#undef SBoxE2 -#undef SBoxE3 -#undef SBoxE4 -#undef SBoxE5 -#undef SBoxE6 -#undef SBoxE7 -#undef SBoxE8 - -#undef SBoxD1 -#undef SBoxD2 -#undef SBoxD3 -#undef SBoxD4 -#undef SBoxD5 -#undef SBoxD6 -#undef SBoxD7 -#undef SBoxD8 - -/* -* Serpent Encryption -*/ -void Serpent_SIMD::encrypt_n(const byte in[], byte out[], size_t blocks) const - { - const u32bit* KS = &(this->get_round_keys()[0]); - - while(blocks >= 4) - { - serpent_encrypt_4(in, out, KS); - in += 4 * BLOCK_SIZE; - out += 4 * BLOCK_SIZE; - blocks -= 4; - } - - if(blocks) - Serpent::encrypt_n(in, out, blocks); - } - -/* -* Serpent Decryption -*/ -void Serpent_SIMD::decrypt_n(const byte in[], byte out[], size_t blocks) const - { - const u32bit* KS = &(this->get_round_keys()[0]); - - while(blocks >= 4) - { - serpent_decrypt_4(in, out, KS); - in += 4 * BLOCK_SIZE; - out += 4 * BLOCK_SIZE; - blocks -= 4; - } - - if(blocks) - Serpent::decrypt_n(in, out, blocks); - } - -} -/* -* Skipjack -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -namespace { - -/* -* Skipjack Stepping Rule 'A' -*/ -void step_A(u16bit& W1, u16bit& W4, size_t round, const byte FTAB[]) - { - byte G1 = get_byte(0, W1), G2 = get_byte(1, W1), G3; - - G3 = FTAB[((4*round-4)%10)*256 + G2] ^ G1; - G1 = FTAB[((4*round-3)%10)*256 + G3] ^ G2; - G2 = FTAB[((4*round-2)%10)*256 + G1] ^ G3; - G3 = FTAB[((4*round-1)%10)*256 + G2] ^ G1; - - W1 = make_u16bit(G2, G3); - W4 ^= W1 ^ round; - } - -/* -* Skipjack Stepping Rule 'B' -*/ -void step_B(u16bit& W1, u16bit& W2, size_t round, const byte FTAB[]) - { - W2 ^= W1 ^ round; - byte G1 = get_byte(0, W1), G2 = get_byte(1, W1), G3; - G3 = FTAB[((4*round-4)%10)*256 + G2] ^ G1; - G1 = FTAB[((4*round-3)%10)*256 + G3] ^ G2; - G2 = FTAB[((4*round-2)%10)*256 + G1] ^ G3; - G3 = FTAB[((4*round-1)%10)*256 + G2] ^ G1; - W1 = make_u16bit(G2, G3); - } - -/* -* Skipjack Invserse Stepping Rule 'A' -*/ -void step_Ai(u16bit& W1, u16bit& W2, size_t round, const byte FTAB[]) - { - W1 ^= W2 ^ round; - byte G1 = get_byte(1, W2), G2 = get_byte(0, W2), G3; - G3 = FTAB[((4 * round - 1) % 10)*256 + G2] ^ G1; - G1 = FTAB[((4 * round - 2) % 10)*256 + G3] ^ G2; - G2 = FTAB[((4 * round - 3) % 10)*256 + G1] ^ G3; - G3 = FTAB[((4 * round - 4) % 10)*256 + G2] ^ G1; - W2 = make_u16bit(G3, G2); - } - -/* -* Skipjack Invserse Stepping Rule 'B' -*/ -void step_Bi(u16bit& W2, u16bit& W3, size_t round, const byte FTAB[]) - { - byte G1 = get_byte(1, W2), G2 = get_byte(0, W2), G3; - G3 = FTAB[((4 * round - 1) % 10)*256 + G2] ^ G1; - G1 = FTAB[((4 * round - 2) % 10)*256 + G3] ^ G2; - G2 = FTAB[((4 * round - 3) % 10)*256 + G1] ^ G3; - G3 = FTAB[((4 * round - 4) % 10)*256 + G2] ^ G1; - W2 = make_u16bit(G3, G2); - W3 ^= W2 ^ round; - } - -} - -/* -* Skipjack Encryption -*/ -void Skipjack::encrypt_n(const byte in[], byte out[], size_t blocks) const - { - const byte* ftab = &FTAB[0]; - - for(size_t i = 0; i != blocks; ++i) - { - u16bit W1 = load_le(in, 3); - u16bit W2 = load_le(in, 2); - u16bit W3 = load_le(in, 1); - u16bit W4 = load_le(in, 0); - - step_A(W1, W4, 1, ftab); step_A(W4, W3, 2, ftab); - step_A(W3, W2, 3, ftab); step_A(W2, W1, 4, ftab); - step_A(W1, W4, 5, ftab); step_A(W4, W3, 6, ftab); - step_A(W3, W2, 7, ftab); step_A(W2, W1, 8, ftab); - - step_B(W1, W2, 9, ftab); step_B(W4, W1, 10, ftab); - step_B(W3, W4, 11, ftab); step_B(W2, W3, 12, ftab); - step_B(W1, W2, 13, ftab); step_B(W4, W1, 14, ftab); - step_B(W3, W4, 15, ftab); step_B(W2, W3, 16, ftab); - - step_A(W1, W4, 17, ftab); step_A(W4, W3, 18, ftab); - step_A(W3, W2, 19, ftab); step_A(W2, W1, 20, ftab); - step_A(W1, W4, 21, ftab); step_A(W4, W3, 22, ftab); - step_A(W3, W2, 23, ftab); step_A(W2, W1, 24, ftab); - - step_B(W1, W2, 25, ftab); step_B(W4, W1, 26, ftab); - step_B(W3, W4, 27, ftab); step_B(W2, W3, 28, ftab); - step_B(W1, W2, 29, ftab); step_B(W4, W1, 30, ftab); - step_B(W3, W4, 31, ftab); step_B(W2, W3, 32, ftab); - - store_le(out, W4, W3, W2, W1); - - in += BLOCK_SIZE; - out += BLOCK_SIZE; - } - } - -/* -* Skipjack Decryption -*/ -void Skipjack::decrypt_n(const byte in[], byte out[], size_t blocks) const - { - const byte* ftab = &FTAB[0]; - - for(size_t i = 0; i != blocks; ++i) - { - u16bit W1 = load_le(in, 3); - u16bit W2 = load_le(in, 2); - u16bit W3 = load_le(in, 1); - u16bit W4 = load_le(in, 0); - - step_Bi(W2, W3, 32, ftab); step_Bi(W3, W4, 31, ftab); - step_Bi(W4, W1, 30, ftab); step_Bi(W1, W2, 29, ftab); - step_Bi(W2, W3, 28, ftab); step_Bi(W3, W4, 27, ftab); - step_Bi(W4, W1, 26, ftab); step_Bi(W1, W2, 25, ftab); - - step_Ai(W1, W2, 24, ftab); step_Ai(W2, W3, 23, ftab); - step_Ai(W3, W4, 22, ftab); step_Ai(W4, W1, 21, ftab); - step_Ai(W1, W2, 20, ftab); step_Ai(W2, W3, 19, ftab); - step_Ai(W3, W4, 18, ftab); step_Ai(W4, W1, 17, ftab); - - step_Bi(W2, W3, 16, ftab); step_Bi(W3, W4, 15, ftab); - step_Bi(W4, W1, 14, ftab); step_Bi(W1, W2, 13, ftab); - step_Bi(W2, W3, 12, ftab); step_Bi(W3, W4, 11, ftab); - step_Bi(W4, W1, 10, ftab); step_Bi(W1, W2, 9, ftab); - - step_Ai(W1, W2, 8, ftab); step_Ai(W2, W3, 7, ftab); - step_Ai(W3, W4, 6, ftab); step_Ai(W4, W1, 5, ftab); - step_Ai(W1, W2, 4, ftab); step_Ai(W2, W3, 3, ftab); - step_Ai(W3, W4, 2, ftab); step_Ai(W4, W1, 1, ftab); - - store_le(out, W4, W3, W2, W1); - - in += BLOCK_SIZE; - out += BLOCK_SIZE; - } - } - -/* -* Skipjack Key Schedule -*/ -void Skipjack::key_schedule(const byte key[], size_t) - { - static const byte F[256] = { - 0xA3, 0xD7, 0x09, 0x83, 0xF8, 0x48, 0xF6, 0xF4, 0xB3, 0x21, 0x15, 0x78, - 0x99, 0xB1, 0xAF, 0xF9, 0xE7, 0x2D, 0x4D, 0x8A, 0xCE, 0x4C, 0xCA, 0x2E, - 0x52, 0x95, 0xD9, 0x1E, 0x4E, 0x38, 0x44, 0x28, 0x0A, 0xDF, 0x02, 0xA0, - 0x17, 0xF1, 0x60, 0x68, 0x12, 0xB7, 0x7A, 0xC3, 0xE9, 0xFA, 0x3D, 0x53, - 0x96, 0x84, 0x6B, 0xBA, 0xF2, 0x63, 0x9A, 0x19, 0x7C, 0xAE, 0xE5, 0xF5, - 0xF7, 0x16, 0x6A, 0xA2, 0x39, 0xB6, 0x7B, 0x0F, 0xC1, 0x93, 0x81, 0x1B, - 0xEE, 0xB4, 0x1A, 0xEA, 0xD0, 0x91, 0x2F, 0xB8, 0x55, 0xB9, 0xDA, 0x85, - 0x3F, 0x41, 0xBF, 0xE0, 0x5A, 0x58, 0x80, 0x5F, 0x66, 0x0B, 0xD8, 0x90, - 0x35, 0xD5, 0xC0, 0xA7, 0x33, 0x06, 0x65, 0x69, 0x45, 0x00, 0x94, 0x56, - 0x6D, 0x98, 0x9B, 0x76, 0x97, 0xFC, 0xB2, 0xC2, 0xB0, 0xFE, 0xDB, 0x20, - 0xE1, 0xEB, 0xD6, 0xE4, 0xDD, 0x47, 0x4A, 0x1D, 0x42, 0xED, 0x9E, 0x6E, - 0x49, 0x3C, 0xCD, 0x43, 0x27, 0xD2, 0x07, 0xD4, 0xDE, 0xC7, 0x67, 0x18, - 0x89, 0xCB, 0x30, 0x1F, 0x8D, 0xC6, 0x8F, 0xAA, 0xC8, 0x74, 0xDC, 0xC9, - 0x5D, 0x5C, 0x31, 0xA4, 0x70, 0x88, 0x61, 0x2C, 0x9F, 0x0D, 0x2B, 0x87, - 0x50, 0x82, 0x54, 0x64, 0x26, 0x7D, 0x03, 0x40, 0x34, 0x4B, 0x1C, 0x73, - 0xD1, 0xC4, 0xFD, 0x3B, 0xCC, 0xFB, 0x7F, 0xAB, 0xE6, 0x3E, 0x5B, 0xA5, - 0xAD, 0x04, 0x23, 0x9C, 0x14, 0x51, 0x22, 0xF0, 0x29, 0x79, 0x71, 0x7E, - 0xFF, 0x8C, 0x0E, 0xE2, 0x0C, 0xEF, 0xBC, 0x72, 0x75, 0x6F, 0x37, 0xA1, - 0xEC, 0xD3, 0x8E, 0x62, 0x8B, 0x86, 0x10, 0xE8, 0x08, 0x77, 0x11, 0xBE, - 0x92, 0x4F, 0x24, 0xC5, 0x32, 0x36, 0x9D, 0xCF, 0xF3, 0xA6, 0xBB, 0xAC, - 0x5E, 0x6C, 0xA9, 0x13, 0x57, 0x25, 0xB5, 0xE3, 0xBD, 0xA8, 0x3A, 0x01, - 0x05, 0x59, 0x2A, 0x46 }; - - for(size_t i = 0; i != 10; ++i) - for(size_t j = 0; j != 256; ++j) - FTAB[256*i+j] = F[j ^ key[9-i]]; - } - -/* -* Clear memory of sensitive data -*/ -void Skipjack::clear() - { - zeroise(FTAB); - } - -} -/* -* S-Box and Diffusion Tables for Square -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -const byte Square::SE[256] = { -0xB1, 0xCE, 0xC3, 0x95, 0x5A, 0xAD, 0xE7, 0x02, 0x4D, 0x44, 0xFB, 0x91, 0x0C, -0x87, 0xA1, 0x50, 0xCB, 0x67, 0x54, 0xDD, 0x46, 0x8F, 0xE1, 0x4E, 0xF0, 0xFD, -0xFC, 0xEB, 0xF9, 0xC4, 0x1A, 0x6E, 0x5E, 0xF5, 0xCC, 0x8D, 0x1C, 0x56, 0x43, -0xFE, 0x07, 0x61, 0xF8, 0x75, 0x59, 0xFF, 0x03, 0x22, 0x8A, 0xD1, 0x13, 0xEE, -0x88, 0x00, 0x0E, 0x34, 0x15, 0x80, 0x94, 0xE3, 0xED, 0xB5, 0x53, 0x23, 0x4B, -0x47, 0x17, 0xA7, 0x90, 0x35, 0xAB, 0xD8, 0xB8, 0xDF, 0x4F, 0x57, 0x9A, 0x92, -0xDB, 0x1B, 0x3C, 0xC8, 0x99, 0x04, 0x8E, 0xE0, 0xD7, 0x7D, 0x85, 0xBB, 0x40, -0x2C, 0x3A, 0x45, 0xF1, 0x42, 0x65, 0x20, 0x41, 0x18, 0x72, 0x25, 0x93, 0x70, -0x36, 0x05, 0xF2, 0x0B, 0xA3, 0x79, 0xEC, 0x08, 0x27, 0x31, 0x32, 0xB6, 0x7C, -0xB0, 0x0A, 0x73, 0x5B, 0x7B, 0xB7, 0x81, 0xD2, 0x0D, 0x6A, 0x26, 0x9E, 0x58, -0x9C, 0x83, 0x74, 0xB3, 0xAC, 0x30, 0x7A, 0x69, 0x77, 0x0F, 0xAE, 0x21, 0xDE, -0xD0, 0x2E, 0x97, 0x10, 0xA4, 0x98, 0xA8, 0xD4, 0x68, 0x2D, 0x62, 0x29, 0x6D, -0x16, 0x49, 0x76, 0xC7, 0xE8, 0xC1, 0x96, 0x37, 0xE5, 0xCA, 0xF4, 0xE9, 0x63, -0x12, 0xC2, 0xA6, 0x14, 0xBC, 0xD3, 0x28, 0xAF, 0x2F, 0xE6, 0x24, 0x52, 0xC6, -0xA0, 0x09, 0xBD, 0x8C, 0xCF, 0x5D, 0x11, 0x5F, 0x01, 0xC5, 0x9F, 0x3D, 0xA2, -0x9B, 0xC9, 0x3B, 0xBE, 0x51, 0x19, 0x1F, 0x3F, 0x5C, 0xB2, 0xEF, 0x4A, 0xCD, -0xBF, 0xBA, 0x6F, 0x64, 0xD9, 0xF3, 0x3E, 0xB4, 0xAA, 0xDC, 0xD5, 0x06, 0xC0, -0x7E, 0xF6, 0x66, 0x6C, 0x84, 0x71, 0x38, 0xB9, 0x1D, 0x7F, 0x9D, 0x48, 0x8B, -0x2A, 0xDA, 0xA5, 0x33, 0x82, 0x39, 0xD6, 0x78, 0x86, 0xFA, 0xE4, 0x2B, 0xA9, -0x1E, 0x89, 0x60, 0x6B, 0xEA, 0x55, 0x4C, 0xF7, 0xE2 }; - -const byte Square::SD[256] = { -0x35, 0xBE, 0x07, 0x2E, 0x53, 0x69, 0xDB, 0x28, 0x6F, 0xB7, 0x76, 0x6B, 0x0C, -0x7D, 0x36, 0x8B, 0x92, 0xBC, 0xA9, 0x32, 0xAC, 0x38, 0x9C, 0x42, 0x63, 0xC8, -0x1E, 0x4F, 0x24, 0xE5, 0xF7, 0xC9, 0x61, 0x8D, 0x2F, 0x3F, 0xB3, 0x65, 0x7F, -0x70, 0xAF, 0x9A, 0xEA, 0xF5, 0x5B, 0x98, 0x90, 0xB1, 0x87, 0x71, 0x72, 0xED, -0x37, 0x45, 0x68, 0xA3, 0xE3, 0xEF, 0x5C, 0xC5, 0x50, 0xC1, 0xD6, 0xCA, 0x5A, -0x62, 0x5F, 0x26, 0x09, 0x5D, 0x14, 0x41, 0xE8, 0x9D, 0xCE, 0x40, 0xFD, 0x08, -0x17, 0x4A, 0x0F, 0xC7, 0xB4, 0x3E, 0x12, 0xFC, 0x25, 0x4B, 0x81, 0x2C, 0x04, -0x78, 0xCB, 0xBB, 0x20, 0xBD, 0xF9, 0x29, 0x99, 0xA8, 0xD3, 0x60, 0xDF, 0x11, -0x97, 0x89, 0x7E, 0xFA, 0xE0, 0x9B, 0x1F, 0xD2, 0x67, 0xE2, 0x64, 0x77, 0x84, -0x2B, 0x9E, 0x8A, 0xF1, 0x6D, 0x88, 0x79, 0x74, 0x57, 0xDD, 0xE6, 0x39, 0x7B, -0xEE, 0x83, 0xE1, 0x58, 0xF2, 0x0D, 0x34, 0xF8, 0x30, 0xE9, 0xB9, 0x23, 0x54, -0x15, 0x44, 0x0B, 0x4D, 0x66, 0x3A, 0x03, 0xA2, 0x91, 0x94, 0x52, 0x4C, 0xC3, -0x82, 0xE7, 0x80, 0xC0, 0xB6, 0x0E, 0xC2, 0x6C, 0x93, 0xEC, 0xAB, 0x43, 0x95, -0xF6, 0xD8, 0x46, 0x86, 0x05, 0x8C, 0xB0, 0x75, 0x00, 0xCC, 0x85, 0xD7, 0x3D, -0x73, 0x7A, 0x48, 0xE4, 0xD1, 0x59, 0xAD, 0xB8, 0xC6, 0xD0, 0xDC, 0xA1, 0xAA, -0x02, 0x1D, 0xBF, 0xB5, 0x9F, 0x51, 0xC4, 0xA5, 0x10, 0x22, 0xCF, 0x01, 0xBA, -0x8F, 0x31, 0x7C, 0xAE, 0x96, 0xDA, 0xF0, 0x56, 0x47, 0xD4, 0xEB, 0x4E, 0xD9, -0x13, 0x8E, 0x49, 0x55, 0x16, 0xFF, 0x3B, 0xF4, 0xA4, 0xB2, 0x06, 0xA0, 0xA7, -0xFB, 0x1B, 0x6E, 0x3C, 0x33, 0xCD, 0x18, 0x5E, 0x6A, 0xD5, 0xA6, 0x21, 0xDE, -0xFE, 0x2A, 0x1C, 0xF3, 0x0A, 0x1A, 0x19, 0x27, 0x2D }; - -const byte Square::Log[256] = { -0x00, 0x00, 0x01, 0x86, 0x02, 0x0D, 0x87, 0x4C, 0x03, 0xD2, 0x0E, 0xAE, 0x88, -0x22, 0x4D, 0x93, 0x04, 0x1A, 0xD3, 0xCB, 0x0F, 0x98, 0xAF, 0xA8, 0x89, 0xF0, -0x23, 0x59, 0x4E, 0x35, 0x94, 0x09, 0x05, 0x8F, 0x1B, 0x6E, 0xD4, 0x39, 0xCC, -0xBB, 0x10, 0x68, 0x99, 0x77, 0xB0, 0xDF, 0xA9, 0x72, 0x8A, 0xFA, 0xF1, 0xA0, -0x24, 0x52, 0x5A, 0x60, 0x4F, 0x2F, 0x36, 0xDC, 0x95, 0x32, 0x0A, 0x1F, 0x06, -0xA5, 0x90, 0x49, 0x1C, 0x5D, 0x6F, 0xB8, 0xD5, 0xC1, 0x3A, 0xB5, 0xCD, 0x63, -0xBC, 0x3D, 0x11, 0x44, 0x69, 0x81, 0x9A, 0x27, 0x78, 0xC4, 0xB1, 0xE6, 0xE0, -0xEA, 0xAA, 0x55, 0x73, 0xD8, 0x8B, 0xF6, 0xFB, 0x16, 0xF2, 0xF4, 0xA1, 0x40, -0x25, 0x42, 0x53, 0xE4, 0x5B, 0xA3, 0x61, 0xBF, 0x50, 0xF8, 0x30, 0x2D, 0x37, -0x8D, 0xDD, 0x66, 0x96, 0x18, 0x33, 0xEE, 0x0B, 0xFD, 0x20, 0xD0, 0x07, 0x57, -0xA6, 0xC9, 0x91, 0xAC, 0x4A, 0x84, 0x1D, 0xDA, 0x5E, 0x9E, 0x70, 0x75, 0xB9, -0x6C, 0xD6, 0xE8, 0xC2, 0x7F, 0x3B, 0xB3, 0xB6, 0x47, 0xCE, 0xEC, 0x64, 0x2B, -0xBD, 0xE2, 0x3E, 0x14, 0x12, 0x29, 0x45, 0x7D, 0x6A, 0x9C, 0x82, 0xC7, 0x9B, -0xC6, 0x28, 0x7C, 0x79, 0x7A, 0xC5, 0x7B, 0xB2, 0x46, 0xE7, 0x7E, 0xE1, 0x13, -0xEB, 0x2A, 0xAB, 0x83, 0x56, 0xC8, 0x74, 0x6B, 0xD9, 0x9D, 0x8C, 0x65, 0xF7, -0x2C, 0xFC, 0xCF, 0x17, 0xED, 0xF3, 0x3F, 0xF5, 0x15, 0xA2, 0xBE, 0x41, 0xE3, -0x26, 0xC3, 0x43, 0x80, 0x54, 0xD7, 0xE5, 0xE9, 0x5C, 0xB7, 0xA4, 0x48, 0x62, -0x3C, 0xC0, 0xB4, 0x51, 0x5F, 0xF9, 0x9F, 0x31, 0x1E, 0x2E, 0xDB, 0x38, 0xBA, -0x8E, 0x6D, 0xDE, 0x71, 0x67, 0x76, 0x97, 0xA7, 0x19, 0xCA, 0x34, 0x08, 0xEF, -0x58, 0x0C, 0x4B, 0xFE, 0x85, 0x21, 0x92, 0xD1, 0xAD }; - -const byte Square::ALog[255] = { -0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0xF5, 0x1F, 0x3E, 0x7C, 0xF8, -0x05, 0x0A, 0x14, 0x28, 0x50, 0xA0, 0xB5, 0x9F, 0xCB, 0x63, 0xC6, 0x79, 0xF2, -0x11, 0x22, 0x44, 0x88, 0xE5, 0x3F, 0x7E, 0xFC, 0x0D, 0x1A, 0x34, 0x68, 0xD0, -0x55, 0xAA, 0xA1, 0xB7, 0x9B, 0xC3, 0x73, 0xE6, 0x39, 0x72, 0xE4, 0x3D, 0x7A, -0xF4, 0x1D, 0x3A, 0x74, 0xE8, 0x25, 0x4A, 0x94, 0xDD, 0x4F, 0x9E, 0xC9, 0x67, -0xCE, 0x69, 0xD2, 0x51, 0xA2, 0xB1, 0x97, 0xDB, 0x43, 0x86, 0xF9, 0x07, 0x0E, -0x1C, 0x38, 0x70, 0xE0, 0x35, 0x6A, 0xD4, 0x5D, 0xBA, 0x81, 0xF7, 0x1B, 0x36, -0x6C, 0xD8, 0x45, 0x8A, 0xE1, 0x37, 0x6E, 0xDC, 0x4D, 0x9A, 0xC1, 0x77, 0xEE, -0x29, 0x52, 0xA4, 0xBD, 0x8F, 0xEB, 0x23, 0x46, 0x8C, 0xED, 0x2F, 0x5E, 0xBC, -0x8D, 0xEF, 0x2B, 0x56, 0xAC, 0xAD, 0xAF, 0xAB, 0xA3, 0xB3, 0x93, 0xD3, 0x53, -0xA6, 0xB9, 0x87, 0xFB, 0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0x75, 0xEA, -0x21, 0x42, 0x84, 0xFD, 0x0F, 0x1E, 0x3C, 0x78, 0xF0, 0x15, 0x2A, 0x54, 0xA8, -0xA5, 0xBF, 0x8B, 0xE3, 0x33, 0x66, 0xCC, 0x6D, 0xDA, 0x41, 0x82, 0xF1, 0x17, -0x2E, 0x5C, 0xB8, 0x85, 0xFF, 0x0B, 0x16, 0x2C, 0x58, 0xB0, 0x95, 0xDF, 0x4B, -0x96, 0xD9, 0x47, 0x8E, 0xE9, 0x27, 0x4E, 0x9C, 0xCD, 0x6F, 0xDE, 0x49, 0x92, -0xD1, 0x57, 0xAE, 0xA9, 0xA7, 0xBB, 0x83, 0xF3, 0x13, 0x26, 0x4C, 0x98, 0xC5, -0x7F, 0xFE, 0x09, 0x12, 0x24, 0x48, 0x90, 0xD5, 0x5F, 0xBE, 0x89, 0xE7, 0x3B, -0x76, 0xEC, 0x2D, 0x5A, 0xB4, 0x9D, 0xCF, 0x6B, 0xD6, 0x59, 0xB2, 0x91, 0xD7, -0x5B, 0xB6, 0x99, 0xC7, 0x7B, 0xF6, 0x19, 0x32, 0x64, 0xC8, 0x65, 0xCA, 0x61, -0xC2, 0x71, 0xE2, 0x31, 0x62, 0xC4, 0x7D, 0xFA }; - -const u32bit Square::TE0[256] = { -0x97B1B126, 0x69CECEA7, 0x73C3C3B0, 0xDF95954A, 0xB45A5AEE, 0xAFADAD02, -0x3BE7E7DC, 0x04020206, 0x9A4D4DD7, 0x884444CC, 0x03FBFBF8, 0xD7919146, -0x180C0C14, 0xFB87877C, 0xB7A1A116, 0xA05050F0, 0x63CBCBA8, 0xCE6767A9, -0xA85454FC, 0x4FDDDD92, 0x8C4646CA, 0xEB8F8F64, 0x37E1E1D6, 0x9C4E4ED2, -0x15F0F0E5, 0x0FFDFDF2, 0x0DFCFCF1, 0x23EBEBC8, 0x07F9F9FE, 0x7DC4C4B9, -0x341A1A2E, 0xDC6E6EB2, 0xBC5E5EE2, 0x1FF5F5EA, 0x6DCCCCA1, 0xEF8D8D62, -0x381C1C24, 0xAC5656FA, 0x864343C5, 0x09FEFEF7, 0x0E070709, 0xC26161A3, -0x05F8F8FD, 0xEA75759F, 0xB25959EB, 0x0BFFFFF4, 0x06030305, 0x44222266, -0xE18A8A6B, 0x57D1D186, 0x26131335, 0x29EEEEC7, 0xE588886D, 0x00000000, -0x1C0E0E12, 0x6834345C, 0x2A15153F, 0xF5808075, 0xDD949449, 0x33E3E3D0, -0x2FEDEDC2, 0x9FB5B52A, 0xA65353F5, 0x46232365, 0x964B4BDD, 0x8E4747C9, -0x2E171739, 0xBBA7A71C, 0xD5909045, 0x6A35355F, 0xA3ABAB08, 0x45D8D89D, -0x85B8B83D, 0x4BDFDF94, 0x9E4F4FD1, 0xAE5757F9, 0xC19A9A5B, 0xD1929243, -0x43DBDB98, 0x361B1B2D, 0x783C3C44, 0x65C8C8AD, 0xC799995E, 0x0804040C, -0xE98E8E67, 0x35E0E0D5, 0x5BD7D78C, 0xFA7D7D87, 0xFF85857A, 0x83BBBB38, -0x804040C0, 0x582C2C74, 0x743A3A4E, 0x8A4545CF, 0x17F1F1E6, 0x844242C6, -0xCA6565AF, 0x40202060, 0x824141C3, 0x30181828, 0xE4727296, 0x4A25256F, -0xD3939340, 0xE0707090, 0x6C36365A, 0x0A05050F, 0x11F2F2E3, 0x160B0B1D, -0xB3A3A310, 0xF279798B, 0x2DECECC1, 0x10080818, 0x4E272769, 0x62313153, -0x64323256, 0x99B6B62F, 0xF87C7C84, 0x95B0B025, 0x140A0A1E, 0xE6737395, -0xB65B5BED, 0xF67B7B8D, 0x9BB7B72C, 0xF7818176, 0x51D2D283, 0x1A0D0D17, -0xD46A6ABE, 0x4C26266A, 0xC99E9E57, 0xB05858E8, 0xCD9C9C51, 0xF3838370, -0xE874749C, 0x93B3B320, 0xADACAC01, 0x60303050, 0xF47A7A8E, 0xD26969BB, -0xEE777799, 0x1E0F0F11, 0xA9AEAE07, 0x42212163, 0x49DEDE97, 0x55D0D085, -0x5C2E2E72, 0xDB97974C, 0x20101030, 0xBDA4A419, 0xC598985D, 0xA5A8A80D, -0x5DD4D489, 0xD06868B8, 0x5A2D2D77, 0xC46262A6, 0x5229297B, 0xDA6D6DB7, -0x2C16163A, 0x924949DB, 0xEC76769A, 0x7BC7C7BC, 0x25E8E8CD, 0x77C1C1B6, -0xD996964F, 0x6E373759, 0x3FE5E5DA, 0x61CACAAB, 0x1DF4F4E9, 0x27E9E9CE, -0xC66363A5, 0x24121236, 0x71C2C2B3, 0xB9A6A61F, 0x2814143C, 0x8DBCBC31, -0x53D3D380, 0x50282878, 0xABAFAF04, 0x5E2F2F71, 0x39E6E6DF, 0x4824246C, -0xA45252F6, 0x79C6C6BF, 0xB5A0A015, 0x1209091B, 0x8FBDBD32, 0xED8C8C61, -0x6BCFCFA4, 0xBA5D5DE7, 0x22111133, 0xBE5F5FE1, 0x02010103, 0x7FC5C5BA, -0xCB9F9F54, 0x7A3D3D47, 0xB1A2A213, 0xC39B9B58, 0x67C9C9AE, 0x763B3B4D, -0x89BEBE37, 0xA25151F3, 0x3219192B, 0x3E1F1F21, 0x7E3F3F41, 0xB85C5CE4, -0x91B2B223, 0x2BEFEFC4, 0x944A4ADE, 0x6FCDCDA2, 0x8BBFBF34, 0x81BABA3B, -0xDE6F6FB1, 0xC86464AC, 0x47D9D99E, 0x13F3F3E0, 0x7C3E3E42, 0x9DB4B429, -0xA1AAAA0B, 0x4DDCDC91, 0x5FD5D58A, 0x0C06060A, 0x75C0C0B5, 0xFC7E7E82, -0x19F6F6EF, 0xCC6666AA, 0xD86C6CB4, 0xFD848479, 0xE2717193, 0x70383848, -0x87B9B93E, 0x3A1D1D27, 0xFE7F7F81, 0xCF9D9D52, 0x904848D8, 0xE38B8B68, -0x542A2A7E, 0x41DADA9B, 0xBFA5A51A, 0x66333355, 0xF1828273, 0x7239394B, -0x59D6D68F, 0xF0787888, 0xF986867F, 0x01FAFAFB, 0x3DE4E4D9, 0x562B2B7D, -0xA7A9A90E, 0x3C1E1E22, 0xE789896E, 0xC06060A0, 0xD66B6BBD, 0x21EAEACB, -0xAA5555FF, 0x984C4CD4, 0x1BF7F7EC, 0x31E2E2D3 }; - -const u32bit Square::TE1[256] = { -0x2697B1B1, 0xA769CECE, 0xB073C3C3, 0x4ADF9595, 0xEEB45A5A, 0x02AFADAD, -0xDC3BE7E7, 0x06040202, 0xD79A4D4D, 0xCC884444, 0xF803FBFB, 0x46D79191, -0x14180C0C, 0x7CFB8787, 0x16B7A1A1, 0xF0A05050, 0xA863CBCB, 0xA9CE6767, -0xFCA85454, 0x924FDDDD, 0xCA8C4646, 0x64EB8F8F, 0xD637E1E1, 0xD29C4E4E, -0xE515F0F0, 0xF20FFDFD, 0xF10DFCFC, 0xC823EBEB, 0xFE07F9F9, 0xB97DC4C4, -0x2E341A1A, 0xB2DC6E6E, 0xE2BC5E5E, 0xEA1FF5F5, 0xA16DCCCC, 0x62EF8D8D, -0x24381C1C, 0xFAAC5656, 0xC5864343, 0xF709FEFE, 0x090E0707, 0xA3C26161, -0xFD05F8F8, 0x9FEA7575, 0xEBB25959, 0xF40BFFFF, 0x05060303, 0x66442222, -0x6BE18A8A, 0x8657D1D1, 0x35261313, 0xC729EEEE, 0x6DE58888, 0x00000000, -0x121C0E0E, 0x5C683434, 0x3F2A1515, 0x75F58080, 0x49DD9494, 0xD033E3E3, -0xC22FEDED, 0x2A9FB5B5, 0xF5A65353, 0x65462323, 0xDD964B4B, 0xC98E4747, -0x392E1717, 0x1CBBA7A7, 0x45D59090, 0x5F6A3535, 0x08A3ABAB, 0x9D45D8D8, -0x3D85B8B8, 0x944BDFDF, 0xD19E4F4F, 0xF9AE5757, 0x5BC19A9A, 0x43D19292, -0x9843DBDB, 0x2D361B1B, 0x44783C3C, 0xAD65C8C8, 0x5EC79999, 0x0C080404, -0x67E98E8E, 0xD535E0E0, 0x8C5BD7D7, 0x87FA7D7D, 0x7AFF8585, 0x3883BBBB, -0xC0804040, 0x74582C2C, 0x4E743A3A, 0xCF8A4545, 0xE617F1F1, 0xC6844242, -0xAFCA6565, 0x60402020, 0xC3824141, 0x28301818, 0x96E47272, 0x6F4A2525, -0x40D39393, 0x90E07070, 0x5A6C3636, 0x0F0A0505, 0xE311F2F2, 0x1D160B0B, -0x10B3A3A3, 0x8BF27979, 0xC12DECEC, 0x18100808, 0x694E2727, 0x53623131, -0x56643232, 0x2F99B6B6, 0x84F87C7C, 0x2595B0B0, 0x1E140A0A, 0x95E67373, -0xEDB65B5B, 0x8DF67B7B, 0x2C9BB7B7, 0x76F78181, 0x8351D2D2, 0x171A0D0D, -0xBED46A6A, 0x6A4C2626, 0x57C99E9E, 0xE8B05858, 0x51CD9C9C, 0x70F38383, -0x9CE87474, 0x2093B3B3, 0x01ADACAC, 0x50603030, 0x8EF47A7A, 0xBBD26969, -0x99EE7777, 0x111E0F0F, 0x07A9AEAE, 0x63422121, 0x9749DEDE, 0x8555D0D0, -0x725C2E2E, 0x4CDB9797, 0x30201010, 0x19BDA4A4, 0x5DC59898, 0x0DA5A8A8, -0x895DD4D4, 0xB8D06868, 0x775A2D2D, 0xA6C46262, 0x7B522929, 0xB7DA6D6D, -0x3A2C1616, 0xDB924949, 0x9AEC7676, 0xBC7BC7C7, 0xCD25E8E8, 0xB677C1C1, -0x4FD99696, 0x596E3737, 0xDA3FE5E5, 0xAB61CACA, 0xE91DF4F4, 0xCE27E9E9, -0xA5C66363, 0x36241212, 0xB371C2C2, 0x1FB9A6A6, 0x3C281414, 0x318DBCBC, -0x8053D3D3, 0x78502828, 0x04ABAFAF, 0x715E2F2F, 0xDF39E6E6, 0x6C482424, -0xF6A45252, 0xBF79C6C6, 0x15B5A0A0, 0x1B120909, 0x328FBDBD, 0x61ED8C8C, -0xA46BCFCF, 0xE7BA5D5D, 0x33221111, 0xE1BE5F5F, 0x03020101, 0xBA7FC5C5, -0x54CB9F9F, 0x477A3D3D, 0x13B1A2A2, 0x58C39B9B, 0xAE67C9C9, 0x4D763B3B, -0x3789BEBE, 0xF3A25151, 0x2B321919, 0x213E1F1F, 0x417E3F3F, 0xE4B85C5C, -0x2391B2B2, 0xC42BEFEF, 0xDE944A4A, 0xA26FCDCD, 0x348BBFBF, 0x3B81BABA, -0xB1DE6F6F, 0xACC86464, 0x9E47D9D9, 0xE013F3F3, 0x427C3E3E, 0x299DB4B4, -0x0BA1AAAA, 0x914DDCDC, 0x8A5FD5D5, 0x0A0C0606, 0xB575C0C0, 0x82FC7E7E, -0xEF19F6F6, 0xAACC6666, 0xB4D86C6C, 0x79FD8484, 0x93E27171, 0x48703838, -0x3E87B9B9, 0x273A1D1D, 0x81FE7F7F, 0x52CF9D9D, 0xD8904848, 0x68E38B8B, -0x7E542A2A, 0x9B41DADA, 0x1ABFA5A5, 0x55663333, 0x73F18282, 0x4B723939, -0x8F59D6D6, 0x88F07878, 0x7FF98686, 0xFB01FAFA, 0xD93DE4E4, 0x7D562B2B, -0x0EA7A9A9, 0x223C1E1E, 0x6EE78989, 0xA0C06060, 0xBDD66B6B, 0xCB21EAEA, -0xFFAA5555, 0xD4984C4C, 0xEC1BF7F7, 0xD331E2E2 }; - -const u32bit Square::TE2[256] = { -0xB12697B1, 0xCEA769CE, 0xC3B073C3, 0x954ADF95, 0x5AEEB45A, 0xAD02AFAD, -0xE7DC3BE7, 0x02060402, 0x4DD79A4D, 0x44CC8844, 0xFBF803FB, 0x9146D791, -0x0C14180C, 0x877CFB87, 0xA116B7A1, 0x50F0A050, 0xCBA863CB, 0x67A9CE67, -0x54FCA854, 0xDD924FDD, 0x46CA8C46, 0x8F64EB8F, 0xE1D637E1, 0x4ED29C4E, -0xF0E515F0, 0xFDF20FFD, 0xFCF10DFC, 0xEBC823EB, 0xF9FE07F9, 0xC4B97DC4, -0x1A2E341A, 0x6EB2DC6E, 0x5EE2BC5E, 0xF5EA1FF5, 0xCCA16DCC, 0x8D62EF8D, -0x1C24381C, 0x56FAAC56, 0x43C58643, 0xFEF709FE, 0x07090E07, 0x61A3C261, -0xF8FD05F8, 0x759FEA75, 0x59EBB259, 0xFFF40BFF, 0x03050603, 0x22664422, -0x8A6BE18A, 0xD18657D1, 0x13352613, 0xEEC729EE, 0x886DE588, 0x00000000, -0x0E121C0E, 0x345C6834, 0x153F2A15, 0x8075F580, 0x9449DD94, 0xE3D033E3, -0xEDC22FED, 0xB52A9FB5, 0x53F5A653, 0x23654623, 0x4BDD964B, 0x47C98E47, -0x17392E17, 0xA71CBBA7, 0x9045D590, 0x355F6A35, 0xAB08A3AB, 0xD89D45D8, -0xB83D85B8, 0xDF944BDF, 0x4FD19E4F, 0x57F9AE57, 0x9A5BC19A, 0x9243D192, -0xDB9843DB, 0x1B2D361B, 0x3C44783C, 0xC8AD65C8, 0x995EC799, 0x040C0804, -0x8E67E98E, 0xE0D535E0, 0xD78C5BD7, 0x7D87FA7D, 0x857AFF85, 0xBB3883BB, -0x40C08040, 0x2C74582C, 0x3A4E743A, 0x45CF8A45, 0xF1E617F1, 0x42C68442, -0x65AFCA65, 0x20604020, 0x41C38241, 0x18283018, 0x7296E472, 0x256F4A25, -0x9340D393, 0x7090E070, 0x365A6C36, 0x050F0A05, 0xF2E311F2, 0x0B1D160B, -0xA310B3A3, 0x798BF279, 0xECC12DEC, 0x08181008, 0x27694E27, 0x31536231, -0x32566432, 0xB62F99B6, 0x7C84F87C, 0xB02595B0, 0x0A1E140A, 0x7395E673, -0x5BEDB65B, 0x7B8DF67B, 0xB72C9BB7, 0x8176F781, 0xD28351D2, 0x0D171A0D, -0x6ABED46A, 0x266A4C26, 0x9E57C99E, 0x58E8B058, 0x9C51CD9C, 0x8370F383, -0x749CE874, 0xB32093B3, 0xAC01ADAC, 0x30506030, 0x7A8EF47A, 0x69BBD269, -0x7799EE77, 0x0F111E0F, 0xAE07A9AE, 0x21634221, 0xDE9749DE, 0xD08555D0, -0x2E725C2E, 0x974CDB97, 0x10302010, 0xA419BDA4, 0x985DC598, 0xA80DA5A8, -0xD4895DD4, 0x68B8D068, 0x2D775A2D, 0x62A6C462, 0x297B5229, 0x6DB7DA6D, -0x163A2C16, 0x49DB9249, 0x769AEC76, 0xC7BC7BC7, 0xE8CD25E8, 0xC1B677C1, -0x964FD996, 0x37596E37, 0xE5DA3FE5, 0xCAAB61CA, 0xF4E91DF4, 0xE9CE27E9, -0x63A5C663, 0x12362412, 0xC2B371C2, 0xA61FB9A6, 0x143C2814, 0xBC318DBC, -0xD38053D3, 0x28785028, 0xAF04ABAF, 0x2F715E2F, 0xE6DF39E6, 0x246C4824, -0x52F6A452, 0xC6BF79C6, 0xA015B5A0, 0x091B1209, 0xBD328FBD, 0x8C61ED8C, -0xCFA46BCF, 0x5DE7BA5D, 0x11332211, 0x5FE1BE5F, 0x01030201, 0xC5BA7FC5, -0x9F54CB9F, 0x3D477A3D, 0xA213B1A2, 0x9B58C39B, 0xC9AE67C9, 0x3B4D763B, -0xBE3789BE, 0x51F3A251, 0x192B3219, 0x1F213E1F, 0x3F417E3F, 0x5CE4B85C, -0xB22391B2, 0xEFC42BEF, 0x4ADE944A, 0xCDA26FCD, 0xBF348BBF, 0xBA3B81BA, -0x6FB1DE6F, 0x64ACC864, 0xD99E47D9, 0xF3E013F3, 0x3E427C3E, 0xB4299DB4, -0xAA0BA1AA, 0xDC914DDC, 0xD58A5FD5, 0x060A0C06, 0xC0B575C0, 0x7E82FC7E, -0xF6EF19F6, 0x66AACC66, 0x6CB4D86C, 0x8479FD84, 0x7193E271, 0x38487038, -0xB93E87B9, 0x1D273A1D, 0x7F81FE7F, 0x9D52CF9D, 0x48D89048, 0x8B68E38B, -0x2A7E542A, 0xDA9B41DA, 0xA51ABFA5, 0x33556633, 0x8273F182, 0x394B7239, -0xD68F59D6, 0x7888F078, 0x867FF986, 0xFAFB01FA, 0xE4D93DE4, 0x2B7D562B, -0xA90EA7A9, 0x1E223C1E, 0x896EE789, 0x60A0C060, 0x6BBDD66B, 0xEACB21EA, -0x55FFAA55, 0x4CD4984C, 0xF7EC1BF7, 0xE2D331E2 }; - -const u32bit Square::TE3[256] = { -0xB1B12697, 0xCECEA769, 0xC3C3B073, 0x95954ADF, 0x5A5AEEB4, 0xADAD02AF, -0xE7E7DC3B, 0x02020604, 0x4D4DD79A, 0x4444CC88, 0xFBFBF803, 0x919146D7, -0x0C0C1418, 0x87877CFB, 0xA1A116B7, 0x5050F0A0, 0xCBCBA863, 0x6767A9CE, -0x5454FCA8, 0xDDDD924F, 0x4646CA8C, 0x8F8F64EB, 0xE1E1D637, 0x4E4ED29C, -0xF0F0E515, 0xFDFDF20F, 0xFCFCF10D, 0xEBEBC823, 0xF9F9FE07, 0xC4C4B97D, -0x1A1A2E34, 0x6E6EB2DC, 0x5E5EE2BC, 0xF5F5EA1F, 0xCCCCA16D, 0x8D8D62EF, -0x1C1C2438, 0x5656FAAC, 0x4343C586, 0xFEFEF709, 0x0707090E, 0x6161A3C2, -0xF8F8FD05, 0x75759FEA, 0x5959EBB2, 0xFFFFF40B, 0x03030506, 0x22226644, -0x8A8A6BE1, 0xD1D18657, 0x13133526, 0xEEEEC729, 0x88886DE5, 0x00000000, -0x0E0E121C, 0x34345C68, 0x15153F2A, 0x808075F5, 0x949449DD, 0xE3E3D033, -0xEDEDC22F, 0xB5B52A9F, 0x5353F5A6, 0x23236546, 0x4B4BDD96, 0x4747C98E, -0x1717392E, 0xA7A71CBB, 0x909045D5, 0x35355F6A, 0xABAB08A3, 0xD8D89D45, -0xB8B83D85, 0xDFDF944B, 0x4F4FD19E, 0x5757F9AE, 0x9A9A5BC1, 0x929243D1, -0xDBDB9843, 0x1B1B2D36, 0x3C3C4478, 0xC8C8AD65, 0x99995EC7, 0x04040C08, -0x8E8E67E9, 0xE0E0D535, 0xD7D78C5B, 0x7D7D87FA, 0x85857AFF, 0xBBBB3883, -0x4040C080, 0x2C2C7458, 0x3A3A4E74, 0x4545CF8A, 0xF1F1E617, 0x4242C684, -0x6565AFCA, 0x20206040, 0x4141C382, 0x18182830, 0x727296E4, 0x25256F4A, -0x939340D3, 0x707090E0, 0x36365A6C, 0x05050F0A, 0xF2F2E311, 0x0B0B1D16, -0xA3A310B3, 0x79798BF2, 0xECECC12D, 0x08081810, 0x2727694E, 0x31315362, -0x32325664, 0xB6B62F99, 0x7C7C84F8, 0xB0B02595, 0x0A0A1E14, 0x737395E6, -0x5B5BEDB6, 0x7B7B8DF6, 0xB7B72C9B, 0x818176F7, 0xD2D28351, 0x0D0D171A, -0x6A6ABED4, 0x26266A4C, 0x9E9E57C9, 0x5858E8B0, 0x9C9C51CD, 0x838370F3, -0x74749CE8, 0xB3B32093, 0xACAC01AD, 0x30305060, 0x7A7A8EF4, 0x6969BBD2, -0x777799EE, 0x0F0F111E, 0xAEAE07A9, 0x21216342, 0xDEDE9749, 0xD0D08555, -0x2E2E725C, 0x97974CDB, 0x10103020, 0xA4A419BD, 0x98985DC5, 0xA8A80DA5, -0xD4D4895D, 0x6868B8D0, 0x2D2D775A, 0x6262A6C4, 0x29297B52, 0x6D6DB7DA, -0x16163A2C, 0x4949DB92, 0x76769AEC, 0xC7C7BC7B, 0xE8E8CD25, 0xC1C1B677, -0x96964FD9, 0x3737596E, 0xE5E5DA3F, 0xCACAAB61, 0xF4F4E91D, 0xE9E9CE27, -0x6363A5C6, 0x12123624, 0xC2C2B371, 0xA6A61FB9, 0x14143C28, 0xBCBC318D, -0xD3D38053, 0x28287850, 0xAFAF04AB, 0x2F2F715E, 0xE6E6DF39, 0x24246C48, -0x5252F6A4, 0xC6C6BF79, 0xA0A015B5, 0x09091B12, 0xBDBD328F, 0x8C8C61ED, -0xCFCFA46B, 0x5D5DE7BA, 0x11113322, 0x5F5FE1BE, 0x01010302, 0xC5C5BA7F, -0x9F9F54CB, 0x3D3D477A, 0xA2A213B1, 0x9B9B58C3, 0xC9C9AE67, 0x3B3B4D76, -0xBEBE3789, 0x5151F3A2, 0x19192B32, 0x1F1F213E, 0x3F3F417E, 0x5C5CE4B8, -0xB2B22391, 0xEFEFC42B, 0x4A4ADE94, 0xCDCDA26F, 0xBFBF348B, 0xBABA3B81, -0x6F6FB1DE, 0x6464ACC8, 0xD9D99E47, 0xF3F3E013, 0x3E3E427C, 0xB4B4299D, -0xAAAA0BA1, 0xDCDC914D, 0xD5D58A5F, 0x06060A0C, 0xC0C0B575, 0x7E7E82FC, -0xF6F6EF19, 0x6666AACC, 0x6C6CB4D8, 0x848479FD, 0x717193E2, 0x38384870, -0xB9B93E87, 0x1D1D273A, 0x7F7F81FE, 0x9D9D52CF, 0x4848D890, 0x8B8B68E3, -0x2A2A7E54, 0xDADA9B41, 0xA5A51ABF, 0x33335566, 0x828273F1, 0x39394B72, -0xD6D68F59, 0x787888F0, 0x86867FF9, 0xFAFAFB01, 0xE4E4D93D, 0x2B2B7D56, -0xA9A90EA7, 0x1E1E223C, 0x89896EE7, 0x6060A0C0, 0x6B6BBDD6, 0xEAEACB21, -0x5555FFAA, 0x4C4CD498, 0xF7F7EC1B, 0xE2E2D331 }; - -const u32bit Square::TD0[256] = { -0xE368BC02, 0x5585620C, 0x2A3F2331, 0x61AB13F7, 0x98D46D72, 0x21CB9A19, -0x3C22A461, 0x459D3DCD, 0x05FDB423, 0x2BC4075F, 0x9B2C01C0, 0x3DD9800F, -0x486C5C74, 0xF97F7E85, 0xF173AB1F, 0xB6EDDE0E, 0x283C6BED, 0x4997781A, -0x9F2A918D, 0xC9579F33, 0xA907A8AA, 0xA50DED7D, 0x7C422D8F, 0x764DB0C9, -0x4D91E857, 0xCEA963CC, 0xB4EE96D2, 0x3028E1B6, 0x0DF161B9, 0xBD196726, -0x419BAD80, 0xC0A06EC7, 0x5183F241, 0x92DBF034, 0x6FA21EFC, 0x8F32CE4C, -0x13E03373, 0x69A7C66D, 0xE56D6493, 0xBF1A2FFA, 0xBB1CBFB7, 0x587403B5, -0xE76E2C4F, 0x5D89B796, 0xE89C052A, 0x446619A3, 0x342E71FB, 0x0FF22965, -0xFE81827A, 0xB11322F1, 0xA30835EC, 0xCD510F7E, 0xFF7AA614, 0x5C7293F8, -0x2FC29712, 0xF370E3C3, 0x992F491C, 0xD1431568, 0xC2A3261B, 0x88CC32B3, -0x8ACF7A6F, 0xB0E8069F, 0x7A47F51E, 0xD2BB79DA, 0xE6950821, 0x4398E55C, -0xD0B83106, 0x11E37BAF, 0x7E416553, 0xCCAA2B10, 0xD8B4E49C, 0x6456A7D4, -0xFB7C3659, 0x724B2084, 0xEA9F4DF6, 0x6A5FAADF, 0x2DC1DFCE, 0x70486858, -0xCAAFF381, 0x0605D891, 0x5A774B69, 0x94DE28A5, 0x39DF1042, 0x813BC347, -0xFC82CAA6, 0x23C8D2C5, 0x03F86CB2, 0x080CD59A, 0xDAB7AC40, 0x7DB909E1, -0x3824342C, 0xCF5247A2, 0xDCB274D1, 0x63A85B2B, 0x35D55595, 0x479E7511, -0x15E5EBE2, 0x4B9430C6, 0x4A6F14A8, 0x91239C86, 0x4C6ACC39, 0x5F8AFF4A, -0x0406904D, 0xEE99DDBB, 0x1E1152CA, 0xAAFFC418, 0xEB646998, 0x07FEFCFF, -0x8B345E01, 0x567D0EBE, 0xBAE79BD9, 0x4263C132, 0x75B5DC7B, 0x97264417, -0x67AECB66, 0x95250CCB, 0xEC9A9567, 0x57862AD0, 0x60503799, 0xB8E4D305, -0x65AD83BA, 0x19EFAE35, 0xA4F6C913, 0xC15B4AA9, 0x873E1BD6, 0xA0F0595E, -0x18148A5B, 0xAF02703B, 0xAB04E076, 0xDD4950BF, 0xDF4A1863, 0xC6A5B656, -0x853D530A, 0xFA871237, 0x77B694A7, 0x4665517F, 0xED61B109, 0x1BECE6E9, -0xD5458525, 0xF5753B52, 0x7FBA413D, 0x27CE4288, 0xB2EB4E43, 0xD6BDE997, -0x527B9EF3, 0x62537F45, 0x2C3AFBA0, 0x7BBCD170, 0xB91FF76B, 0x121B171D, -0xFD79EEC8, 0x3A277CF0, 0x0C0A45D7, 0x96DD6079, 0x2233F6AB, 0xACFA1C89, -0xC8ACBB5D, 0xA10B7D30, 0xD4BEA14B, 0xBEE10B94, 0x25CD0A54, 0x547E4662, -0xA2F31182, 0x17E6A33E, 0x263566E6, 0xC3580275, 0x83388B9B, 0x7844BDC2, -0x020348DC, 0x4F92A08B, 0x2E39B37C, 0x4E6984E5, 0xF0888F71, 0x362D3927, -0x9CD2FD3F, 0x01FB246E, 0x893716DD, 0x00000000, 0xF68D57E0, 0xE293986C, -0x744EF815, 0x9320D45A, 0xAD0138E7, 0xD3405DB4, 0x1A17C287, 0xB3106A2D, -0x5078D62F, 0xF48E1F3C, 0xA70EA5A1, 0x71B34C36, 0x9AD725AE, 0x5E71DB24, -0x161D8750, 0xEF62F9D5, 0x8D318690, 0x1C121A16, 0xA6F581CF, 0x5B8C6F07, -0x37D61D49, 0x6E593A92, 0x84C67764, 0x86C53FB8, 0xD746CDF9, 0xE090D0B0, -0x29C74F83, 0xE49640FD, 0x0E090D0B, 0x6DA15620, 0x8EC9EA22, 0xDB4C882E, -0xF776738E, 0xB515B2BC, 0x10185FC1, 0x322BA96A, 0x6BA48EB1, 0xAEF95455, -0x406089EE, 0x6655EF08, 0xE9672144, 0x3E21ECBD, 0x2030BE77, 0xF28BC7AD, -0x80C0E729, 0x141ECF8C, 0xBCE24348, 0xC4A6FE8A, 0x31D3C5D8, 0xB716FA60, -0x5380BA9D, 0xD94FC0F2, 0x1DE93E78, 0x24362E3A, 0xE16BF4DE, 0xCB54D7EF, -0x09F7F1F4, 0x82C3AFF5, 0x0BF4B928, 0x9D29D951, 0xC75E9238, 0xF8845AEB, -0x90D8B8E8, 0xDEB13C0D, 0x33D08D04, 0x685CE203, 0xC55DDAE4, 0x3BDC589E, -0x0A0F9D46, 0x3FDAC8D3, 0x598F27DB, 0xA8FC8CC4, 0x79BF99AC, 0x6C5A724E, -0x8CCAA2FE, 0x9ED1B5E3, 0x1FEA76A4, 0x73B004EA }; - -const u32bit Square::TD1[256] = { -0x02E368BC, 0x0C558562, 0x312A3F23, 0xF761AB13, 0x7298D46D, 0x1921CB9A, -0x613C22A4, 0xCD459D3D, 0x2305FDB4, 0x5F2BC407, 0xC09B2C01, 0x0F3DD980, -0x74486C5C, 0x85F97F7E, 0x1FF173AB, 0x0EB6EDDE, 0xED283C6B, 0x1A499778, -0x8D9F2A91, 0x33C9579F, 0xAAA907A8, 0x7DA50DED, 0x8F7C422D, 0xC9764DB0, -0x574D91E8, 0xCCCEA963, 0xD2B4EE96, 0xB63028E1, 0xB90DF161, 0x26BD1967, -0x80419BAD, 0xC7C0A06E, 0x415183F2, 0x3492DBF0, 0xFC6FA21E, 0x4C8F32CE, -0x7313E033, 0x6D69A7C6, 0x93E56D64, 0xFABF1A2F, 0xB7BB1CBF, 0xB5587403, -0x4FE76E2C, 0x965D89B7, 0x2AE89C05, 0xA3446619, 0xFB342E71, 0x650FF229, -0x7AFE8182, 0xF1B11322, 0xECA30835, 0x7ECD510F, 0x14FF7AA6, 0xF85C7293, -0x122FC297, 0xC3F370E3, 0x1C992F49, 0x68D14315, 0x1BC2A326, 0xB388CC32, -0x6F8ACF7A, 0x9FB0E806, 0x1E7A47F5, 0xDAD2BB79, 0x21E69508, 0x5C4398E5, -0x06D0B831, 0xAF11E37B, 0x537E4165, 0x10CCAA2B, 0x9CD8B4E4, 0xD46456A7, -0x59FB7C36, 0x84724B20, 0xF6EA9F4D, 0xDF6A5FAA, 0xCE2DC1DF, 0x58704868, -0x81CAAFF3, 0x910605D8, 0x695A774B, 0xA594DE28, 0x4239DF10, 0x47813BC3, -0xA6FC82CA, 0xC523C8D2, 0xB203F86C, 0x9A080CD5, 0x40DAB7AC, 0xE17DB909, -0x2C382434, 0xA2CF5247, 0xD1DCB274, 0x2B63A85B, 0x9535D555, 0x11479E75, -0xE215E5EB, 0xC64B9430, 0xA84A6F14, 0x8691239C, 0x394C6ACC, 0x4A5F8AFF, -0x4D040690, 0xBBEE99DD, 0xCA1E1152, 0x18AAFFC4, 0x98EB6469, 0xFF07FEFC, -0x018B345E, 0xBE567D0E, 0xD9BAE79B, 0x324263C1, 0x7B75B5DC, 0x17972644, -0x6667AECB, 0xCB95250C, 0x67EC9A95, 0xD057862A, 0x99605037, 0x05B8E4D3, -0xBA65AD83, 0x3519EFAE, 0x13A4F6C9, 0xA9C15B4A, 0xD6873E1B, 0x5EA0F059, -0x5B18148A, 0x3BAF0270, 0x76AB04E0, 0xBFDD4950, 0x63DF4A18, 0x56C6A5B6, -0x0A853D53, 0x37FA8712, 0xA777B694, 0x7F466551, 0x09ED61B1, 0xE91BECE6, -0x25D54585, 0x52F5753B, 0x3D7FBA41, 0x8827CE42, 0x43B2EB4E, 0x97D6BDE9, -0xF3527B9E, 0x4562537F, 0xA02C3AFB, 0x707BBCD1, 0x6BB91FF7, 0x1D121B17, -0xC8FD79EE, 0xF03A277C, 0xD70C0A45, 0x7996DD60, 0xAB2233F6, 0x89ACFA1C, -0x5DC8ACBB, 0x30A10B7D, 0x4BD4BEA1, 0x94BEE10B, 0x5425CD0A, 0x62547E46, -0x82A2F311, 0x3E17E6A3, 0xE6263566, 0x75C35802, 0x9B83388B, 0xC27844BD, -0xDC020348, 0x8B4F92A0, 0x7C2E39B3, 0xE54E6984, 0x71F0888F, 0x27362D39, -0x3F9CD2FD, 0x6E01FB24, 0xDD893716, 0x00000000, 0xE0F68D57, 0x6CE29398, -0x15744EF8, 0x5A9320D4, 0xE7AD0138, 0xB4D3405D, 0x871A17C2, 0x2DB3106A, -0x2F5078D6, 0x3CF48E1F, 0xA1A70EA5, 0x3671B34C, 0xAE9AD725, 0x245E71DB, -0x50161D87, 0xD5EF62F9, 0x908D3186, 0x161C121A, 0xCFA6F581, 0x075B8C6F, -0x4937D61D, 0x926E593A, 0x6484C677, 0xB886C53F, 0xF9D746CD, 0xB0E090D0, -0x8329C74F, 0xFDE49640, 0x0B0E090D, 0x206DA156, 0x228EC9EA, 0x2EDB4C88, -0x8EF77673, 0xBCB515B2, 0xC110185F, 0x6A322BA9, 0xB16BA48E, 0x55AEF954, -0xEE406089, 0x086655EF, 0x44E96721, 0xBD3E21EC, 0x772030BE, 0xADF28BC7, -0x2980C0E7, 0x8C141ECF, 0x48BCE243, 0x8AC4A6FE, 0xD831D3C5, 0x60B716FA, -0x9D5380BA, 0xF2D94FC0, 0x781DE93E, 0x3A24362E, 0xDEE16BF4, 0xEFCB54D7, -0xF409F7F1, 0xF582C3AF, 0x280BF4B9, 0x519D29D9, 0x38C75E92, 0xEBF8845A, -0xE890D8B8, 0x0DDEB13C, 0x0433D08D, 0x03685CE2, 0xE4C55DDA, 0x9E3BDC58, -0x460A0F9D, 0xD33FDAC8, 0xDB598F27, 0xC4A8FC8C, 0xAC79BF99, 0x4E6C5A72, -0xFE8CCAA2, 0xE39ED1B5, 0xA41FEA76, 0xEA73B004 }; - -const u32bit Square::TD2[256] = { -0xBC02E368, 0x620C5585, 0x23312A3F, 0x13F761AB, 0x6D7298D4, 0x9A1921CB, -0xA4613C22, 0x3DCD459D, 0xB42305FD, 0x075F2BC4, 0x01C09B2C, 0x800F3DD9, -0x5C74486C, 0x7E85F97F, 0xAB1FF173, 0xDE0EB6ED, 0x6BED283C, 0x781A4997, -0x918D9F2A, 0x9F33C957, 0xA8AAA907, 0xED7DA50D, 0x2D8F7C42, 0xB0C9764D, -0xE8574D91, 0x63CCCEA9, 0x96D2B4EE, 0xE1B63028, 0x61B90DF1, 0x6726BD19, -0xAD80419B, 0x6EC7C0A0, 0xF2415183, 0xF03492DB, 0x1EFC6FA2, 0xCE4C8F32, -0x337313E0, 0xC66D69A7, 0x6493E56D, 0x2FFABF1A, 0xBFB7BB1C, 0x03B55874, -0x2C4FE76E, 0xB7965D89, 0x052AE89C, 0x19A34466, 0x71FB342E, 0x29650FF2, -0x827AFE81, 0x22F1B113, 0x35ECA308, 0x0F7ECD51, 0xA614FF7A, 0x93F85C72, -0x97122FC2, 0xE3C3F370, 0x491C992F, 0x1568D143, 0x261BC2A3, 0x32B388CC, -0x7A6F8ACF, 0x069FB0E8, 0xF51E7A47, 0x79DAD2BB, 0x0821E695, 0xE55C4398, -0x3106D0B8, 0x7BAF11E3, 0x65537E41, 0x2B10CCAA, 0xE49CD8B4, 0xA7D46456, -0x3659FB7C, 0x2084724B, 0x4DF6EA9F, 0xAADF6A5F, 0xDFCE2DC1, 0x68587048, -0xF381CAAF, 0xD8910605, 0x4B695A77, 0x28A594DE, 0x104239DF, 0xC347813B, -0xCAA6FC82, 0xD2C523C8, 0x6CB203F8, 0xD59A080C, 0xAC40DAB7, 0x09E17DB9, -0x342C3824, 0x47A2CF52, 0x74D1DCB2, 0x5B2B63A8, 0x559535D5, 0x7511479E, -0xEBE215E5, 0x30C64B94, 0x14A84A6F, 0x9C869123, 0xCC394C6A, 0xFF4A5F8A, -0x904D0406, 0xDDBBEE99, 0x52CA1E11, 0xC418AAFF, 0x6998EB64, 0xFCFF07FE, -0x5E018B34, 0x0EBE567D, 0x9BD9BAE7, 0xC1324263, 0xDC7B75B5, 0x44179726, -0xCB6667AE, 0x0CCB9525, 0x9567EC9A, 0x2AD05786, 0x37996050, 0xD305B8E4, -0x83BA65AD, 0xAE3519EF, 0xC913A4F6, 0x4AA9C15B, 0x1BD6873E, 0x595EA0F0, -0x8A5B1814, 0x703BAF02, 0xE076AB04, 0x50BFDD49, 0x1863DF4A, 0xB656C6A5, -0x530A853D, 0x1237FA87, 0x94A777B6, 0x517F4665, 0xB109ED61, 0xE6E91BEC, -0x8525D545, 0x3B52F575, 0x413D7FBA, 0x428827CE, 0x4E43B2EB, 0xE997D6BD, -0x9EF3527B, 0x7F456253, 0xFBA02C3A, 0xD1707BBC, 0xF76BB91F, 0x171D121B, -0xEEC8FD79, 0x7CF03A27, 0x45D70C0A, 0x607996DD, 0xF6AB2233, 0x1C89ACFA, -0xBB5DC8AC, 0x7D30A10B, 0xA14BD4BE, 0x0B94BEE1, 0x0A5425CD, 0x4662547E, -0x1182A2F3, 0xA33E17E6, 0x66E62635, 0x0275C358, 0x8B9B8338, 0xBDC27844, -0x48DC0203, 0xA08B4F92, 0xB37C2E39, 0x84E54E69, 0x8F71F088, 0x3927362D, -0xFD3F9CD2, 0x246E01FB, 0x16DD8937, 0x00000000, 0x57E0F68D, 0x986CE293, -0xF815744E, 0xD45A9320, 0x38E7AD01, 0x5DB4D340, 0xC2871A17, 0x6A2DB310, -0xD62F5078, 0x1F3CF48E, 0xA5A1A70E, 0x4C3671B3, 0x25AE9AD7, 0xDB245E71, -0x8750161D, 0xF9D5EF62, 0x86908D31, 0x1A161C12, 0x81CFA6F5, 0x6F075B8C, -0x1D4937D6, 0x3A926E59, 0x776484C6, 0x3FB886C5, 0xCDF9D746, 0xD0B0E090, -0x4F8329C7, 0x40FDE496, 0x0D0B0E09, 0x56206DA1, 0xEA228EC9, 0x882EDB4C, -0x738EF776, 0xB2BCB515, 0x5FC11018, 0xA96A322B, 0x8EB16BA4, 0x5455AEF9, -0x89EE4060, 0xEF086655, 0x2144E967, 0xECBD3E21, 0xBE772030, 0xC7ADF28B, -0xE72980C0, 0xCF8C141E, 0x4348BCE2, 0xFE8AC4A6, 0xC5D831D3, 0xFA60B716, -0xBA9D5380, 0xC0F2D94F, 0x3E781DE9, 0x2E3A2436, 0xF4DEE16B, 0xD7EFCB54, -0xF1F409F7, 0xAFF582C3, 0xB9280BF4, 0xD9519D29, 0x9238C75E, 0x5AEBF884, -0xB8E890D8, 0x3C0DDEB1, 0x8D0433D0, 0xE203685C, 0xDAE4C55D, 0x589E3BDC, -0x9D460A0F, 0xC8D33FDA, 0x27DB598F, 0x8CC4A8FC, 0x99AC79BF, 0x724E6C5A, -0xA2FE8CCA, 0xB5E39ED1, 0x76A41FEA, 0x04EA73B0 }; - -const u32bit Square::TD3[256] = { -0x68BC02E3, 0x85620C55, 0x3F23312A, 0xAB13F761, 0xD46D7298, 0xCB9A1921, -0x22A4613C, 0x9D3DCD45, 0xFDB42305, 0xC4075F2B, 0x2C01C09B, 0xD9800F3D, -0x6C5C7448, 0x7F7E85F9, 0x73AB1FF1, 0xEDDE0EB6, 0x3C6BED28, 0x97781A49, -0x2A918D9F, 0x579F33C9, 0x07A8AAA9, 0x0DED7DA5, 0x422D8F7C, 0x4DB0C976, -0x91E8574D, 0xA963CCCE, 0xEE96D2B4, 0x28E1B630, 0xF161B90D, 0x196726BD, -0x9BAD8041, 0xA06EC7C0, 0x83F24151, 0xDBF03492, 0xA21EFC6F, 0x32CE4C8F, -0xE0337313, 0xA7C66D69, 0x6D6493E5, 0x1A2FFABF, 0x1CBFB7BB, 0x7403B558, -0x6E2C4FE7, 0x89B7965D, 0x9C052AE8, 0x6619A344, 0x2E71FB34, 0xF229650F, -0x81827AFE, 0x1322F1B1, 0x0835ECA3, 0x510F7ECD, 0x7AA614FF, 0x7293F85C, -0xC297122F, 0x70E3C3F3, 0x2F491C99, 0x431568D1, 0xA3261BC2, 0xCC32B388, -0xCF7A6F8A, 0xE8069FB0, 0x47F51E7A, 0xBB79DAD2, 0x950821E6, 0x98E55C43, -0xB83106D0, 0xE37BAF11, 0x4165537E, 0xAA2B10CC, 0xB4E49CD8, 0x56A7D464, -0x7C3659FB, 0x4B208472, 0x9F4DF6EA, 0x5FAADF6A, 0xC1DFCE2D, 0x48685870, -0xAFF381CA, 0x05D89106, 0x774B695A, 0xDE28A594, 0xDF104239, 0x3BC34781, -0x82CAA6FC, 0xC8D2C523, 0xF86CB203, 0x0CD59A08, 0xB7AC40DA, 0xB909E17D, -0x24342C38, 0x5247A2CF, 0xB274D1DC, 0xA85B2B63, 0xD5559535, 0x9E751147, -0xE5EBE215, 0x9430C64B, 0x6F14A84A, 0x239C8691, 0x6ACC394C, 0x8AFF4A5F, -0x06904D04, 0x99DDBBEE, 0x1152CA1E, 0xFFC418AA, 0x646998EB, 0xFEFCFF07, -0x345E018B, 0x7D0EBE56, 0xE79BD9BA, 0x63C13242, 0xB5DC7B75, 0x26441797, -0xAECB6667, 0x250CCB95, 0x9A9567EC, 0x862AD057, 0x50379960, 0xE4D305B8, -0xAD83BA65, 0xEFAE3519, 0xF6C913A4, 0x5B4AA9C1, 0x3E1BD687, 0xF0595EA0, -0x148A5B18, 0x02703BAF, 0x04E076AB, 0x4950BFDD, 0x4A1863DF, 0xA5B656C6, -0x3D530A85, 0x871237FA, 0xB694A777, 0x65517F46, 0x61B109ED, 0xECE6E91B, -0x458525D5, 0x753B52F5, 0xBA413D7F, 0xCE428827, 0xEB4E43B2, 0xBDE997D6, -0x7B9EF352, 0x537F4562, 0x3AFBA02C, 0xBCD1707B, 0x1FF76BB9, 0x1B171D12, -0x79EEC8FD, 0x277CF03A, 0x0A45D70C, 0xDD607996, 0x33F6AB22, 0xFA1C89AC, -0xACBB5DC8, 0x0B7D30A1, 0xBEA14BD4, 0xE10B94BE, 0xCD0A5425, 0x7E466254, -0xF31182A2, 0xE6A33E17, 0x3566E626, 0x580275C3, 0x388B9B83, 0x44BDC278, -0x0348DC02, 0x92A08B4F, 0x39B37C2E, 0x6984E54E, 0x888F71F0, 0x2D392736, -0xD2FD3F9C, 0xFB246E01, 0x3716DD89, 0x00000000, 0x8D57E0F6, 0x93986CE2, -0x4EF81574, 0x20D45A93, 0x0138E7AD, 0x405DB4D3, 0x17C2871A, 0x106A2DB3, -0x78D62F50, 0x8E1F3CF4, 0x0EA5A1A7, 0xB34C3671, 0xD725AE9A, 0x71DB245E, -0x1D875016, 0x62F9D5EF, 0x3186908D, 0x121A161C, 0xF581CFA6, 0x8C6F075B, -0xD61D4937, 0x593A926E, 0xC6776484, 0xC53FB886, 0x46CDF9D7, 0x90D0B0E0, -0xC74F8329, 0x9640FDE4, 0x090D0B0E, 0xA156206D, 0xC9EA228E, 0x4C882EDB, -0x76738EF7, 0x15B2BCB5, 0x185FC110, 0x2BA96A32, 0xA48EB16B, 0xF95455AE, -0x6089EE40, 0x55EF0866, 0x672144E9, 0x21ECBD3E, 0x30BE7720, 0x8BC7ADF2, -0xC0E72980, 0x1ECF8C14, 0xE24348BC, 0xA6FE8AC4, 0xD3C5D831, 0x16FA60B7, -0x80BA9D53, 0x4FC0F2D9, 0xE93E781D, 0x362E3A24, 0x6BF4DEE1, 0x54D7EFCB, -0xF7F1F409, 0xC3AFF582, 0xF4B9280B, 0x29D9519D, 0x5E9238C7, 0x845AEBF8, -0xD8B8E890, 0xB13C0DDE, 0xD08D0433, 0x5CE20368, 0x5DDAE4C5, 0xDC589E3B, -0x0F9D460A, 0xDAC8D33F, 0x8F27DB59, 0xFC8CC4A8, 0xBF99AC79, 0x5A724E6C, -0xCAA2FE8C, 0xD1B5E39E, 0xEA76A41F, 0xB004EA73 }; - -} -/* -* Square -* (C) 1999-2007 Jack Lloyd -* -* Based on the public domain reference implemenation -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -/* -* Square Encryption -*/ -void Square::encrypt_n(const byte in[], byte out[], size_t blocks) const - { - for(size_t i = 0; i != blocks; ++i) - { - u32bit B0, B1, B2, B3; - - B0 = TE0[in[ 0] ^ ME[ 0]] ^ TE1[in[ 4] ^ ME[ 4]] ^ - TE2[in[ 8] ^ ME[ 8]] ^ TE3[in[12] ^ ME[12]] ^ EK[0]; - B1 = TE0[in[ 1] ^ ME[ 1]] ^ TE1[in[ 5] ^ ME[ 5]] ^ - TE2[in[ 9] ^ ME[ 9]] ^ TE3[in[13] ^ ME[13]] ^ EK[1]; - B2 = TE0[in[ 2] ^ ME[ 2]] ^ TE1[in[ 6] ^ ME[ 6]] ^ - TE2[in[10] ^ ME[10]] ^ TE3[in[14] ^ ME[14]] ^ EK[2]; - B3 = TE0[in[ 3] ^ ME[ 3]] ^ TE1[in[ 7] ^ ME[ 7]] ^ - TE2[in[11] ^ ME[11]] ^ TE3[in[15] ^ ME[15]] ^ EK[3]; - - for(size_t j = 1; j != 7; j += 2) - { - u32bit T0, T1, T2, T3; - T0 = TE0[get_byte(0, B0)] ^ TE1[get_byte(0, B1)] ^ - TE2[get_byte(0, B2)] ^ TE3[get_byte(0, B3)] ^ EK[4*j+0]; - T1 = TE0[get_byte(1, B0)] ^ TE1[get_byte(1, B1)] ^ - TE2[get_byte(1, B2)] ^ TE3[get_byte(1, B3)] ^ EK[4*j+1]; - T2 = TE0[get_byte(2, B0)] ^ TE1[get_byte(2, B1)] ^ - TE2[get_byte(2, B2)] ^ TE3[get_byte(2, B3)] ^ EK[4*j+2]; - T3 = TE0[get_byte(3, B0)] ^ TE1[get_byte(3, B1)] ^ - TE2[get_byte(3, B2)] ^ TE3[get_byte(3, B3)] ^ EK[4*j+3]; - - B0 = TE0[get_byte(0, T0)] ^ TE1[get_byte(0, T1)] ^ - TE2[get_byte(0, T2)] ^ TE3[get_byte(0, T3)] ^ EK[4*j+4]; - B1 = TE0[get_byte(1, T0)] ^ TE1[get_byte(1, T1)] ^ - TE2[get_byte(1, T2)] ^ TE3[get_byte(1, T3)] ^ EK[4*j+5]; - B2 = TE0[get_byte(2, T0)] ^ TE1[get_byte(2, T1)] ^ - TE2[get_byte(2, T2)] ^ TE3[get_byte(2, T3)] ^ EK[4*j+6]; - B3 = TE0[get_byte(3, T0)] ^ TE1[get_byte(3, T1)] ^ - TE2[get_byte(3, T2)] ^ TE3[get_byte(3, T3)] ^ EK[4*j+7]; - } - - out[ 0] = SE[get_byte(0, B0)] ^ ME[16]; - out[ 1] = SE[get_byte(0, B1)] ^ ME[17]; - out[ 2] = SE[get_byte(0, B2)] ^ ME[18]; - out[ 3] = SE[get_byte(0, B3)] ^ ME[19]; - out[ 4] = SE[get_byte(1, B0)] ^ ME[20]; - out[ 5] = SE[get_byte(1, B1)] ^ ME[21]; - out[ 6] = SE[get_byte(1, B2)] ^ ME[22]; - out[ 7] = SE[get_byte(1, B3)] ^ ME[23]; - out[ 8] = SE[get_byte(2, B0)] ^ ME[24]; - out[ 9] = SE[get_byte(2, B1)] ^ ME[25]; - out[10] = SE[get_byte(2, B2)] ^ ME[26]; - out[11] = SE[get_byte(2, B3)] ^ ME[27]; - out[12] = SE[get_byte(3, B0)] ^ ME[28]; - out[13] = SE[get_byte(3, B1)] ^ ME[29]; - out[14] = SE[get_byte(3, B2)] ^ ME[30]; - out[15] = SE[get_byte(3, B3)] ^ ME[31]; - - in += BLOCK_SIZE; - out += BLOCK_SIZE; - } - } - -/* -* Square Decryption -*/ -void Square::decrypt_n(const byte in[], byte out[], size_t blocks) const - { - for(size_t i = 0; i != blocks; ++i) - { - u32bit B0, B1, B2, B3; - - B0 = TD0[in[ 0] ^ MD[ 0]] ^ TD1[in[ 4] ^ MD[ 4]] ^ - TD2[in[ 8] ^ MD[ 8]] ^ TD3[in[12] ^ MD[12]] ^ DK[0]; - B1 = TD0[in[ 1] ^ MD[ 1]] ^ TD1[in[ 5] ^ MD[ 5]] ^ - TD2[in[ 9] ^ MD[ 9]] ^ TD3[in[13] ^ MD[13]] ^ DK[1]; - B2 = TD0[in[ 2] ^ MD[ 2]] ^ TD1[in[ 6] ^ MD[ 6]] ^ - TD2[in[10] ^ MD[10]] ^ TD3[in[14] ^ MD[14]] ^ DK[2]; - B3 = TD0[in[ 3] ^ MD[ 3]] ^ TD1[in[ 7] ^ MD[ 7]] ^ - TD2[in[11] ^ MD[11]] ^ TD3[in[15] ^ MD[15]] ^ DK[3]; - - for(size_t j = 1; j != 7; j += 2) - { - u32bit T0, T1, T2, T3; - T0 = TD0[get_byte(0, B0)] ^ TD1[get_byte(0, B1)] ^ - TD2[get_byte(0, B2)] ^ TD3[get_byte(0, B3)] ^ DK[4*j+0]; - T1 = TD0[get_byte(1, B0)] ^ TD1[get_byte(1, B1)] ^ - TD2[get_byte(1, B2)] ^ TD3[get_byte(1, B3)] ^ DK[4*j+1]; - T2 = TD0[get_byte(2, B0)] ^ TD1[get_byte(2, B1)] ^ - TD2[get_byte(2, B2)] ^ TD3[get_byte(2, B3)] ^ DK[4*j+2]; - T3 = TD0[get_byte(3, B0)] ^ TD1[get_byte(3, B1)] ^ - TD2[get_byte(3, B2)] ^ TD3[get_byte(3, B3)] ^ DK[4*j+3]; - - B0 = TD0[get_byte(0, T0)] ^ TD1[get_byte(0, T1)] ^ - TD2[get_byte(0, T2)] ^ TD3[get_byte(0, T3)] ^ DK[4*j+4]; - B1 = TD0[get_byte(1, T0)] ^ TD1[get_byte(1, T1)] ^ - TD2[get_byte(1, T2)] ^ TD3[get_byte(1, T3)] ^ DK[4*j+5]; - B2 = TD0[get_byte(2, T0)] ^ TD1[get_byte(2, T1)] ^ - TD2[get_byte(2, T2)] ^ TD3[get_byte(2, T3)] ^ DK[4*j+6]; - B3 = TD0[get_byte(3, T0)] ^ TD1[get_byte(3, T1)] ^ - TD2[get_byte(3, T2)] ^ TD3[get_byte(3, T3)] ^ DK[4*j+7]; - } - - out[ 0] = SD[get_byte(0, B0)] ^ MD[16]; - out[ 1] = SD[get_byte(0, B1)] ^ MD[17]; - out[ 2] = SD[get_byte(0, B2)] ^ MD[18]; - out[ 3] = SD[get_byte(0, B3)] ^ MD[19]; - out[ 4] = SD[get_byte(1, B0)] ^ MD[20]; - out[ 5] = SD[get_byte(1, B1)] ^ MD[21]; - out[ 6] = SD[get_byte(1, B2)] ^ MD[22]; - out[ 7] = SD[get_byte(1, B3)] ^ MD[23]; - out[ 8] = SD[get_byte(2, B0)] ^ MD[24]; - out[ 9] = SD[get_byte(2, B1)] ^ MD[25]; - out[10] = SD[get_byte(2, B2)] ^ MD[26]; - out[11] = SD[get_byte(2, B3)] ^ MD[27]; - out[12] = SD[get_byte(3, B0)] ^ MD[28]; - out[13] = SD[get_byte(3, B1)] ^ MD[29]; - out[14] = SD[get_byte(3, B2)] ^ MD[30]; - out[15] = SD[get_byte(3, B3)] ^ MD[31]; - - in += BLOCK_SIZE; - out += BLOCK_SIZE; - } - } - -/* -* Square Key Schedule -*/ -void Square::key_schedule(const byte key[], size_t) - { - SecureVector XEK(36), XDK(36); - - for(size_t i = 0; i != 4; ++i) - XEK[i] = load_be(key, i); - - for(size_t i = 0; i != 8; ++i) - { - XEK[4*i+4] = XEK[4*i ] ^ rotate_left(XEK[4*i+3], 8) ^ (0x01000000 << i); - XEK[4*i+5] = XEK[4*i+1] ^ XEK[4*i+4]; - XEK[4*i+6] = XEK[4*i+2] ^ XEK[4*i+5]; - XEK[4*i+7] = XEK[4*i+3] ^ XEK[4*i+6]; - - for(size_t j = 0; j != 4; ++j) - XDK[28 - 4*i + j] = XEK[4*(i+1)+j]; - - transform(&XEK[4*i]); - } - - for(size_t i = 0; i != 4; ++i) - for(size_t j = 0; j != 4; ++j) - { - ME[4*i+j ] = get_byte(j, XEK[i ]); - ME[4*i+j+16] = get_byte(j, XEK[i+32]); - MD[4*i+j ] = get_byte(j, XDK[i ]); - MD[4*i+j+16] = get_byte(j, XEK[i ]); - } - - EK.copy(&XEK[4], 28); - DK.copy(&XDK[4], 28); - } - -/* -* Square's Inverse Linear Transformation -*/ -void Square::transform(u32bit round_key[4]) - { - static const byte G[4][4] = { - { 2, 1, 1, 3 }, - { 3, 2, 1, 1 }, - { 1, 3, 2, 1 }, - { 1, 1, 3, 2 } }; - - for(size_t i = 0; i != 4; ++i) - { - byte A[4] = { 0 }, B[4] = { 0 }; - - store_be(round_key[i], A); - - for(size_t j = 0; j != 4; ++j) - for(size_t k = 0; k != 4; ++k) - { - const byte a = A[k]; - const byte b = G[k][j]; - - if(a && b) - B[j] ^= ALog[(Log[a] + Log[b]) % 255]; - } - - round_key[i] = load_be(B, 0); - } - } - -/* -* Clear memory of sensitive data -*/ -void Square::clear() - { - zeroise(EK); - zeroise(DK); - zeroise(ME); - zeroise(MD); - } - -} -/* -* TEA -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -/* -* TEA Encryption -*/ -void TEA::encrypt_n(const byte in[], byte out[], size_t blocks) const - { - for(size_t i = 0; i != blocks; ++i) - { - u32bit L = load_be(in, 0); - u32bit R = load_be(in, 1); - - u32bit S = 0; - for(size_t j = 0; j != 32; ++j) - { - S += 0x9E3779B9; - L += ((R << 4) + K[0]) ^ (R + S) ^ ((R >> 5) + K[1]); - R += ((L << 4) + K[2]) ^ (L + S) ^ ((L >> 5) + K[3]); - } - - store_be(out, L, R); - - in += BLOCK_SIZE; - out += BLOCK_SIZE; - } - } - -/* -* TEA Decryption -*/ -void TEA::decrypt_n(const byte in[], byte out[], size_t blocks) const - { - for(size_t i = 0; i != blocks; ++i) - { - u32bit L = load_be(in, 0); - u32bit R = load_be(in, 1); - - u32bit S = 0xC6EF3720; - for(size_t j = 0; j != 32; ++j) - { - R -= ((L << 4) + K[2]) ^ (L + S) ^ ((L >> 5) + K[3]); - L -= ((R << 4) + K[0]) ^ (R + S) ^ ((R >> 5) + K[1]); - S -= 0x9E3779B9; - } - - store_be(out, L, R); - - in += BLOCK_SIZE; - out += BLOCK_SIZE; - } - } - -/* -* TEA Key Schedule -*/ -void TEA::key_schedule(const byte key[], size_t) - { - for(size_t i = 0; i != 4; ++i) - K[i] = load_be(key, i); - } - -} -/* -* S-Box and MDS Tables for Twofish -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -const byte Twofish::Q0[256] = { - 0xA9, 0x67, 0xB3, 0xE8, 0x04, 0xFD, 0xA3, 0x76, 0x9A, 0x92, 0x80, 0x78, - 0xE4, 0xDD, 0xD1, 0x38, 0x0D, 0xC6, 0x35, 0x98, 0x18, 0xF7, 0xEC, 0x6C, - 0x43, 0x75, 0x37, 0x26, 0xFA, 0x13, 0x94, 0x48, 0xF2, 0xD0, 0x8B, 0x30, - 0x84, 0x54, 0xDF, 0x23, 0x19, 0x5B, 0x3D, 0x59, 0xF3, 0xAE, 0xA2, 0x82, - 0x63, 0x01, 0x83, 0x2E, 0xD9, 0x51, 0x9B, 0x7C, 0xA6, 0xEB, 0xA5, 0xBE, - 0x16, 0x0C, 0xE3, 0x61, 0xC0, 0x8C, 0x3A, 0xF5, 0x73, 0x2C, 0x25, 0x0B, - 0xBB, 0x4E, 0x89, 0x6B, 0x53, 0x6A, 0xB4, 0xF1, 0xE1, 0xE6, 0xBD, 0x45, - 0xE2, 0xF4, 0xB6, 0x66, 0xCC, 0x95, 0x03, 0x56, 0xD4, 0x1C, 0x1E, 0xD7, - 0xFB, 0xC3, 0x8E, 0xB5, 0xE9, 0xCF, 0xBF, 0xBA, 0xEA, 0x77, 0x39, 0xAF, - 0x33, 0xC9, 0x62, 0x71, 0x81, 0x79, 0x09, 0xAD, 0x24, 0xCD, 0xF9, 0xD8, - 0xE5, 0xC5, 0xB9, 0x4D, 0x44, 0x08, 0x86, 0xE7, 0xA1, 0x1D, 0xAA, 0xED, - 0x06, 0x70, 0xB2, 0xD2, 0x41, 0x7B, 0xA0, 0x11, 0x31, 0xC2, 0x27, 0x90, - 0x20, 0xF6, 0x60, 0xFF, 0x96, 0x5C, 0xB1, 0xAB, 0x9E, 0x9C, 0x52, 0x1B, - 0x5F, 0x93, 0x0A, 0xEF, 0x91, 0x85, 0x49, 0xEE, 0x2D, 0x4F, 0x8F, 0x3B, - 0x47, 0x87, 0x6D, 0x46, 0xD6, 0x3E, 0x69, 0x64, 0x2A, 0xCE, 0xCB, 0x2F, - 0xFC, 0x97, 0x05, 0x7A, 0xAC, 0x7F, 0xD5, 0x1A, 0x4B, 0x0E, 0xA7, 0x5A, - 0x28, 0x14, 0x3F, 0x29, 0x88, 0x3C, 0x4C, 0x02, 0xB8, 0xDA, 0xB0, 0x17, - 0x55, 0x1F, 0x8A, 0x7D, 0x57, 0xC7, 0x8D, 0x74, 0xB7, 0xC4, 0x9F, 0x72, - 0x7E, 0x15, 0x22, 0x12, 0x58, 0x07, 0x99, 0x34, 0x6E, 0x50, 0xDE, 0x68, - 0x65, 0xBC, 0xDB, 0xF8, 0xC8, 0xA8, 0x2B, 0x40, 0xDC, 0xFE, 0x32, 0xA4, - 0xCA, 0x10, 0x21, 0xF0, 0xD3, 0x5D, 0x0F, 0x00, 0x6F, 0x9D, 0x36, 0x42, - 0x4A, 0x5E, 0xC1, 0xE0 }; - -const byte Twofish::Q1[256] = { - 0x75, 0xF3, 0xC6, 0xF4, 0xDB, 0x7B, 0xFB, 0xC8, 0x4A, 0xD3, 0xE6, 0x6B, - 0x45, 0x7D, 0xE8, 0x4B, 0xD6, 0x32, 0xD8, 0xFD, 0x37, 0x71, 0xF1, 0xE1, - 0x30, 0x0F, 0xF8, 0x1B, 0x87, 0xFA, 0x06, 0x3F, 0x5E, 0xBA, 0xAE, 0x5B, - 0x8A, 0x00, 0xBC, 0x9D, 0x6D, 0xC1, 0xB1, 0x0E, 0x80, 0x5D, 0xD2, 0xD5, - 0xA0, 0x84, 0x07, 0x14, 0xB5, 0x90, 0x2C, 0xA3, 0xB2, 0x73, 0x4C, 0x54, - 0x92, 0x74, 0x36, 0x51, 0x38, 0xB0, 0xBD, 0x5A, 0xFC, 0x60, 0x62, 0x96, - 0x6C, 0x42, 0xF7, 0x10, 0x7C, 0x28, 0x27, 0x8C, 0x13, 0x95, 0x9C, 0xC7, - 0x24, 0x46, 0x3B, 0x70, 0xCA, 0xE3, 0x85, 0xCB, 0x11, 0xD0, 0x93, 0xB8, - 0xA6, 0x83, 0x20, 0xFF, 0x9F, 0x77, 0xC3, 0xCC, 0x03, 0x6F, 0x08, 0xBF, - 0x40, 0xE7, 0x2B, 0xE2, 0x79, 0x0C, 0xAA, 0x82, 0x41, 0x3A, 0xEA, 0xB9, - 0xE4, 0x9A, 0xA4, 0x97, 0x7E, 0xDA, 0x7A, 0x17, 0x66, 0x94, 0xA1, 0x1D, - 0x3D, 0xF0, 0xDE, 0xB3, 0x0B, 0x72, 0xA7, 0x1C, 0xEF, 0xD1, 0x53, 0x3E, - 0x8F, 0x33, 0x26, 0x5F, 0xEC, 0x76, 0x2A, 0x49, 0x81, 0x88, 0xEE, 0x21, - 0xC4, 0x1A, 0xEB, 0xD9, 0xC5, 0x39, 0x99, 0xCD, 0xAD, 0x31, 0x8B, 0x01, - 0x18, 0x23, 0xDD, 0x1F, 0x4E, 0x2D, 0xF9, 0x48, 0x4F, 0xF2, 0x65, 0x8E, - 0x78, 0x5C, 0x58, 0x19, 0x8D, 0xE5, 0x98, 0x57, 0x67, 0x7F, 0x05, 0x64, - 0xAF, 0x63, 0xB6, 0xFE, 0xF5, 0xB7, 0x3C, 0xA5, 0xCE, 0xE9, 0x68, 0x44, - 0xE0, 0x4D, 0x43, 0x69, 0x29, 0x2E, 0xAC, 0x15, 0x59, 0xA8, 0x0A, 0x9E, - 0x6E, 0x47, 0xDF, 0x34, 0x35, 0x6A, 0xCF, 0xDC, 0x22, 0xC9, 0xC0, 0x9B, - 0x89, 0xD4, 0xED, 0xAB, 0x12, 0xA2, 0x0D, 0x52, 0xBB, 0x02, 0x2F, 0xA9, - 0xD7, 0x61, 0x1E, 0xB4, 0x50, 0x04, 0xF6, 0xC2, 0x16, 0x25, 0x86, 0x56, - 0x55, 0x09, 0xBE, 0x91 }; - -const byte Twofish::RS[32] = { - 0x01, 0xA4, 0x02, 0xA4, 0xA4, 0x56, 0xA1, 0x55, 0x55, 0x82, 0xFC, 0x87, - 0x87, 0xF3, 0xC1, 0x5A, 0x5A, 0x1E, 0x47, 0x58, 0x58, 0xC6, 0xAE, 0xDB, - 0xDB, 0x68, 0x3D, 0x9E, 0x9E, 0xE5, 0x19, 0x03 }; - -const byte Twofish::EXP_TO_POLY[255] = { - 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x4D, 0x9A, 0x79, 0xF2, - 0xA9, 0x1F, 0x3E, 0x7C, 0xF8, 0xBD, 0x37, 0x6E, 0xDC, 0xF5, 0xA7, 0x03, - 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0xCD, 0xD7, 0xE3, 0x8B, 0x5B, 0xB6, - 0x21, 0x42, 0x84, 0x45, 0x8A, 0x59, 0xB2, 0x29, 0x52, 0xA4, 0x05, 0x0A, - 0x14, 0x28, 0x50, 0xA0, 0x0D, 0x1A, 0x34, 0x68, 0xD0, 0xED, 0x97, 0x63, - 0xC6, 0xC1, 0xCF, 0xD3, 0xEB, 0x9B, 0x7B, 0xF6, 0xA1, 0x0F, 0x1E, 0x3C, - 0x78, 0xF0, 0xAD, 0x17, 0x2E, 0x5C, 0xB8, 0x3D, 0x7A, 0xF4, 0xA5, 0x07, - 0x0E, 0x1C, 0x38, 0x70, 0xE0, 0x8D, 0x57, 0xAE, 0x11, 0x22, 0x44, 0x88, - 0x5D, 0xBA, 0x39, 0x72, 0xE4, 0x85, 0x47, 0x8E, 0x51, 0xA2, 0x09, 0x12, - 0x24, 0x48, 0x90, 0x6D, 0xDA, 0xF9, 0xBF, 0x33, 0x66, 0xCC, 0xD5, 0xE7, - 0x83, 0x4B, 0x96, 0x61, 0xC2, 0xC9, 0xDF, 0xF3, 0xAB, 0x1B, 0x36, 0x6C, - 0xD8, 0xFD, 0xB7, 0x23, 0x46, 0x8C, 0x55, 0xAA, 0x19, 0x32, 0x64, 0xC8, - 0xDD, 0xF7, 0xA3, 0x0B, 0x16, 0x2C, 0x58, 0xB0, 0x2D, 0x5A, 0xB4, 0x25, - 0x4A, 0x94, 0x65, 0xCA, 0xD9, 0xFF, 0xB3, 0x2B, 0x56, 0xAC, 0x15, 0x2A, - 0x54, 0xA8, 0x1D, 0x3A, 0x74, 0xE8, 0x9D, 0x77, 0xEE, 0x91, 0x6F, 0xDE, - 0xF1, 0xAF, 0x13, 0x26, 0x4C, 0x98, 0x7D, 0xFA, 0xB9, 0x3F, 0x7E, 0xFC, - 0xB5, 0x27, 0x4E, 0x9C, 0x75, 0xEA, 0x99, 0x7F, 0xFE, 0xB1, 0x2F, 0x5E, - 0xBC, 0x35, 0x6A, 0xD4, 0xE5, 0x87, 0x43, 0x86, 0x41, 0x82, 0x49, 0x92, - 0x69, 0xD2, 0xE9, 0x9F, 0x73, 0xE6, 0x81, 0x4F, 0x9E, 0x71, 0xE2, 0x89, - 0x5F, 0xBE, 0x31, 0x62, 0xC4, 0xC5, 0xC7, 0xC3, 0xCB, 0xDB, 0xFB, 0xBB, - 0x3B, 0x76, 0xEC, 0x95, 0x67, 0xCE, 0xD1, 0xEF, 0x93, 0x6B, 0xD6, 0xE1, - 0x8F, 0x53, 0xA6 }; - -const byte Twofish::POLY_TO_EXP[255] = { - 0x00, 0x01, 0x17, 0x02, 0x2E, 0x18, 0x53, 0x03, 0x6A, 0x2F, 0x93, 0x19, - 0x34, 0x54, 0x45, 0x04, 0x5C, 0x6B, 0xB6, 0x30, 0xA6, 0x94, 0x4B, 0x1A, - 0x8C, 0x35, 0x81, 0x55, 0xAA, 0x46, 0x0D, 0x05, 0x24, 0x5D, 0x87, 0x6C, - 0x9B, 0xB7, 0xC1, 0x31, 0x2B, 0xA7, 0xA3, 0x95, 0x98, 0x4C, 0xCA, 0x1B, - 0xE6, 0x8D, 0x73, 0x36, 0xCD, 0x82, 0x12, 0x56, 0x62, 0xAB, 0xF0, 0x47, - 0x4F, 0x0E, 0xBD, 0x06, 0xD4, 0x25, 0xD2, 0x5E, 0x27, 0x88, 0x66, 0x6D, - 0xD6, 0x9C, 0x79, 0xB8, 0x08, 0xC2, 0xDF, 0x32, 0x68, 0x2C, 0xFD, 0xA8, - 0x8A, 0xA4, 0x5A, 0x96, 0x29, 0x99, 0x22, 0x4D, 0x60, 0xCB, 0xE4, 0x1C, - 0x7B, 0xE7, 0x3B, 0x8E, 0x9E, 0x74, 0xF4, 0x37, 0xD8, 0xCE, 0xF9, 0x83, - 0x6F, 0x13, 0xB2, 0x57, 0xE1, 0x63, 0xDC, 0xAC, 0xC4, 0xF1, 0xAF, 0x48, - 0x0A, 0x50, 0x42, 0x0F, 0xBA, 0xBE, 0xC7, 0x07, 0xDE, 0xD5, 0x78, 0x26, - 0x65, 0xD3, 0xD1, 0x5F, 0xE3, 0x28, 0x21, 0x89, 0x59, 0x67, 0xFC, 0x6E, - 0xB1, 0xD7, 0xF8, 0x9D, 0xF3, 0x7A, 0x3A, 0xB9, 0xC6, 0x09, 0x41, 0xC3, - 0xAE, 0xE0, 0xDB, 0x33, 0x44, 0x69, 0x92, 0x2D, 0x52, 0xFE, 0x16, 0xA9, - 0x0C, 0x8B, 0x80, 0xA5, 0x4A, 0x5B, 0xB5, 0x97, 0xC9, 0x2A, 0xA2, 0x9A, - 0xC0, 0x23, 0x86, 0x4E, 0xBC, 0x61, 0xEF, 0xCC, 0x11, 0xE5, 0x72, 0x1D, - 0x3D, 0x7C, 0xEB, 0xE8, 0xE9, 0x3C, 0xEA, 0x8F, 0x7D, 0x9F, 0xEC, 0x75, - 0x1E, 0xF5, 0x3E, 0x38, 0xF6, 0xD9, 0x3F, 0xCF, 0x76, 0xFA, 0x1F, 0x84, - 0xA0, 0x70, 0xED, 0x14, 0x90, 0xB3, 0x7E, 0x58, 0xFB, 0xE2, 0x20, 0x64, - 0xD0, 0xDD, 0x77, 0xAD, 0xDA, 0xC5, 0x40, 0xF2, 0x39, 0xB0, 0xF7, 0x49, - 0xB4, 0x0B, 0x7F, 0x51, 0x15, 0x43, 0x91, 0x10, 0x71, 0xBB, 0xEE, 0xBF, - 0x85, 0xC8, 0xA1 }; - -const u32bit Twofish::MDS0[256] = { - 0xBCBC3275, 0xECEC21F3, 0x202043C6, 0xB3B3C9F4, 0xDADA03DB, 0x02028B7B, - 0xE2E22BFB, 0x9E9EFAC8, 0xC9C9EC4A, 0xD4D409D3, 0x18186BE6, 0x1E1E9F6B, - 0x98980E45, 0xB2B2387D, 0xA6A6D2E8, 0x2626B74B, 0x3C3C57D6, 0x93938A32, - 0x8282EED8, 0x525298FD, 0x7B7BD437, 0xBBBB3771, 0x5B5B97F1, 0x474783E1, - 0x24243C30, 0x5151E20F, 0xBABAC6F8, 0x4A4AF31B, 0xBFBF4887, 0x0D0D70FA, - 0xB0B0B306, 0x7575DE3F, 0xD2D2FD5E, 0x7D7D20BA, 0x666631AE, 0x3A3AA35B, - 0x59591C8A, 0x00000000, 0xCDCD93BC, 0x1A1AE09D, 0xAEAE2C6D, 0x7F7FABC1, - 0x2B2BC7B1, 0xBEBEB90E, 0xE0E0A080, 0x8A8A105D, 0x3B3B52D2, 0x6464BAD5, - 0xD8D888A0, 0xE7E7A584, 0x5F5FE807, 0x1B1B1114, 0x2C2CC2B5, 0xFCFCB490, - 0x3131272C, 0x808065A3, 0x73732AB2, 0x0C0C8173, 0x79795F4C, 0x6B6B4154, - 0x4B4B0292, 0x53536974, 0x94948F36, 0x83831F51, 0x2A2A3638, 0xC4C49CB0, - 0x2222C8BD, 0xD5D5F85A, 0xBDBDC3FC, 0x48487860, 0xFFFFCE62, 0x4C4C0796, - 0x4141776C, 0xC7C7E642, 0xEBEB24F7, 0x1C1C1410, 0x5D5D637C, 0x36362228, - 0x6767C027, 0xE9E9AF8C, 0x4444F913, 0x1414EA95, 0xF5F5BB9C, 0xCFCF18C7, - 0x3F3F2D24, 0xC0C0E346, 0x7272DB3B, 0x54546C70, 0x29294CCA, 0xF0F035E3, - 0x0808FE85, 0xC6C617CB, 0xF3F34F11, 0x8C8CE4D0, 0xA4A45993, 0xCACA96B8, - 0x68683BA6, 0xB8B84D83, 0x38382820, 0xE5E52EFF, 0xADAD569F, 0x0B0B8477, - 0xC8C81DC3, 0x9999FFCC, 0x5858ED03, 0x19199A6F, 0x0E0E0A08, 0x95957EBF, - 0x70705040, 0xF7F730E7, 0x6E6ECF2B, 0x1F1F6EE2, 0xB5B53D79, 0x09090F0C, - 0x616134AA, 0x57571682, 0x9F9F0B41, 0x9D9D803A, 0x111164EA, 0x2525CDB9, - 0xAFAFDDE4, 0x4545089A, 0xDFDF8DA4, 0xA3A35C97, 0xEAEAD57E, 0x353558DA, - 0xEDEDD07A, 0x4343FC17, 0xF8F8CB66, 0xFBFBB194, 0x3737D3A1, 0xFAFA401D, - 0xC2C2683D, 0xB4B4CCF0, 0x32325DDE, 0x9C9C71B3, 0x5656E70B, 0xE3E3DA72, - 0x878760A7, 0x15151B1C, 0xF9F93AEF, 0x6363BFD1, 0x3434A953, 0x9A9A853E, - 0xB1B1428F, 0x7C7CD133, 0x88889B26, 0x3D3DA65F, 0xA1A1D7EC, 0xE4E4DF76, - 0x8181942A, 0x91910149, 0x0F0FFB81, 0xEEEEAA88, 0x161661EE, 0xD7D77321, - 0x9797F5C4, 0xA5A5A81A, 0xFEFE3FEB, 0x6D6DB5D9, 0x7878AEC5, 0xC5C56D39, - 0x1D1DE599, 0x7676A4CD, 0x3E3EDCAD, 0xCBCB6731, 0xB6B6478B, 0xEFEF5B01, - 0x12121E18, 0x6060C523, 0x6A6AB0DD, 0x4D4DF61F, 0xCECEE94E, 0xDEDE7C2D, - 0x55559DF9, 0x7E7E5A48, 0x2121B24F, 0x03037AF2, 0xA0A02665, 0x5E5E198E, - 0x5A5A6678, 0x65654B5C, 0x62624E58, 0xFDFD4519, 0x0606F48D, 0x404086E5, - 0xF2F2BE98, 0x3333AC57, 0x17179067, 0x05058E7F, 0xE8E85E05, 0x4F4F7D64, - 0x89896AAF, 0x10109563, 0x74742FB6, 0x0A0A75FE, 0x5C5C92F5, 0x9B9B74B7, - 0x2D2D333C, 0x3030D6A5, 0x2E2E49CE, 0x494989E9, 0x46467268, 0x77775544, - 0xA8A8D8E0, 0x9696044D, 0x2828BD43, 0xA9A92969, 0xD9D97929, 0x8686912E, - 0xD1D187AC, 0xF4F44A15, 0x8D8D1559, 0xD6D682A8, 0xB9B9BC0A, 0x42420D9E, - 0xF6F6C16E, 0x2F2FB847, 0xDDDD06DF, 0x23233934, 0xCCCC6235, 0xF1F1C46A, - 0xC1C112CF, 0x8585EBDC, 0x8F8F9E22, 0x7171A1C9, 0x9090F0C0, 0xAAAA539B, - 0x0101F189, 0x8B8BE1D4, 0x4E4E8CED, 0x8E8E6FAB, 0xABABA212, 0x6F6F3EA2, - 0xE6E6540D, 0xDBDBF252, 0x92927BBB, 0xB7B7B602, 0x6969CA2F, 0x3939D9A9, - 0xD3D30CD7, 0xA7A72361, 0xA2A2AD1E, 0xC3C399B4, 0x6C6C4450, 0x07070504, - 0x04047FF6, 0x272746C2, 0xACACA716, 0xD0D07625, 0x50501386, 0xDCDCF756, - 0x84841A55, 0xE1E15109, 0x7A7A25BE, 0x1313EF91 }; - -const u32bit Twofish::MDS1[256] = { - 0xA9D93939, 0x67901717, 0xB3719C9C, 0xE8D2A6A6, 0x04050707, 0xFD985252, - 0xA3658080, 0x76DFE4E4, 0x9A084545, 0x92024B4B, 0x80A0E0E0, 0x78665A5A, - 0xE4DDAFAF, 0xDDB06A6A, 0xD1BF6363, 0x38362A2A, 0x0D54E6E6, 0xC6432020, - 0x3562CCCC, 0x98BEF2F2, 0x181E1212, 0xF724EBEB, 0xECD7A1A1, 0x6C774141, - 0x43BD2828, 0x7532BCBC, 0x37D47B7B, 0x269B8888, 0xFA700D0D, 0x13F94444, - 0x94B1FBFB, 0x485A7E7E, 0xF27A0303, 0xD0E48C8C, 0x8B47B6B6, 0x303C2424, - 0x84A5E7E7, 0x54416B6B, 0xDF06DDDD, 0x23C56060, 0x1945FDFD, 0x5BA33A3A, - 0x3D68C2C2, 0x59158D8D, 0xF321ECEC, 0xAE316666, 0xA23E6F6F, 0x82165757, - 0x63951010, 0x015BEFEF, 0x834DB8B8, 0x2E918686, 0xD9B56D6D, 0x511F8383, - 0x9B53AAAA, 0x7C635D5D, 0xA63B6868, 0xEB3FFEFE, 0xA5D63030, 0xBE257A7A, - 0x16A7ACAC, 0x0C0F0909, 0xE335F0F0, 0x6123A7A7, 0xC0F09090, 0x8CAFE9E9, - 0x3A809D9D, 0xF5925C5C, 0x73810C0C, 0x2C273131, 0x2576D0D0, 0x0BE75656, - 0xBB7B9292, 0x4EE9CECE, 0x89F10101, 0x6B9F1E1E, 0x53A93434, 0x6AC4F1F1, - 0xB499C3C3, 0xF1975B5B, 0xE1834747, 0xE66B1818, 0xBDC82222, 0x450E9898, - 0xE26E1F1F, 0xF4C9B3B3, 0xB62F7474, 0x66CBF8F8, 0xCCFF9999, 0x95EA1414, - 0x03ED5858, 0x56F7DCDC, 0xD4E18B8B, 0x1C1B1515, 0x1EADA2A2, 0xD70CD3D3, - 0xFB2BE2E2, 0xC31DC8C8, 0x8E195E5E, 0xB5C22C2C, 0xE9894949, 0xCF12C1C1, - 0xBF7E9595, 0xBA207D7D, 0xEA641111, 0x77840B0B, 0x396DC5C5, 0xAF6A8989, - 0x33D17C7C, 0xC9A17171, 0x62CEFFFF, 0x7137BBBB, 0x81FB0F0F, 0x793DB5B5, - 0x0951E1E1, 0xADDC3E3E, 0x242D3F3F, 0xCDA47676, 0xF99D5555, 0xD8EE8282, - 0xE5864040, 0xC5AE7878, 0xB9CD2525, 0x4D049696, 0x44557777, 0x080A0E0E, - 0x86135050, 0xE730F7F7, 0xA1D33737, 0x1D40FAFA, 0xAA346161, 0xED8C4E4E, - 0x06B3B0B0, 0x706C5454, 0xB22A7373, 0xD2523B3B, 0x410B9F9F, 0x7B8B0202, - 0xA088D8D8, 0x114FF3F3, 0x3167CBCB, 0xC2462727, 0x27C06767, 0x90B4FCFC, - 0x20283838, 0xF67F0404, 0x60784848, 0xFF2EE5E5, 0x96074C4C, 0x5C4B6565, - 0xB1C72B2B, 0xAB6F8E8E, 0x9E0D4242, 0x9CBBF5F5, 0x52F2DBDB, 0x1BF34A4A, - 0x5FA63D3D, 0x9359A4A4, 0x0ABCB9B9, 0xEF3AF9F9, 0x91EF1313, 0x85FE0808, - 0x49019191, 0xEE611616, 0x2D7CDEDE, 0x4FB22121, 0x8F42B1B1, 0x3BDB7272, - 0x47B82F2F, 0x8748BFBF, 0x6D2CAEAE, 0x46E3C0C0, 0xD6573C3C, 0x3E859A9A, - 0x6929A9A9, 0x647D4F4F, 0x2A948181, 0xCE492E2E, 0xCB17C6C6, 0x2FCA6969, - 0xFCC3BDBD, 0x975CA3A3, 0x055EE8E8, 0x7AD0EDED, 0xAC87D1D1, 0x7F8E0505, - 0xD5BA6464, 0x1AA8A5A5, 0x4BB72626, 0x0EB9BEBE, 0xA7608787, 0x5AF8D5D5, - 0x28223636, 0x14111B1B, 0x3FDE7575, 0x2979D9D9, 0x88AAEEEE, 0x3C332D2D, - 0x4C5F7979, 0x02B6B7B7, 0xB896CACA, 0xDA583535, 0xB09CC4C4, 0x17FC4343, - 0x551A8484, 0x1FF64D4D, 0x8A1C5959, 0x7D38B2B2, 0x57AC3333, 0xC718CFCF, - 0x8DF40606, 0x74695353, 0xB7749B9B, 0xC4F59797, 0x9F56ADAD, 0x72DAE3E3, - 0x7ED5EAEA, 0x154AF4F4, 0x229E8F8F, 0x12A2ABAB, 0x584E6262, 0x07E85F5F, - 0x99E51D1D, 0x34392323, 0x6EC1F6F6, 0x50446C6C, 0xDE5D3232, 0x68724646, - 0x6526A0A0, 0xBC93CDCD, 0xDB03DADA, 0xF8C6BABA, 0xC8FA9E9E, 0xA882D6D6, - 0x2BCF6E6E, 0x40507070, 0xDCEB8585, 0xFE750A0A, 0x328A9393, 0xA48DDFDF, - 0xCA4C2929, 0x10141C1C, 0x2173D7D7, 0xF0CCB4B4, 0xD309D4D4, 0x5D108A8A, - 0x0FE25151, 0x00000000, 0x6F9A1919, 0x9DE01A1A, 0x368F9494, 0x42E6C7C7, - 0x4AECC9C9, 0x5EFDD2D2, 0xC1AB7F7F, 0xE0D8A8A8 }; - -const u32bit Twofish::MDS2[256] = { - 0xBC75BC32, 0xECF3EC21, 0x20C62043, 0xB3F4B3C9, 0xDADBDA03, 0x027B028B, - 0xE2FBE22B, 0x9EC89EFA, 0xC94AC9EC, 0xD4D3D409, 0x18E6186B, 0x1E6B1E9F, - 0x9845980E, 0xB27DB238, 0xA6E8A6D2, 0x264B26B7, 0x3CD63C57, 0x9332938A, - 0x82D882EE, 0x52FD5298, 0x7B377BD4, 0xBB71BB37, 0x5BF15B97, 0x47E14783, - 0x2430243C, 0x510F51E2, 0xBAF8BAC6, 0x4A1B4AF3, 0xBF87BF48, 0x0DFA0D70, - 0xB006B0B3, 0x753F75DE, 0xD25ED2FD, 0x7DBA7D20, 0x66AE6631, 0x3A5B3AA3, - 0x598A591C, 0x00000000, 0xCDBCCD93, 0x1A9D1AE0, 0xAE6DAE2C, 0x7FC17FAB, - 0x2BB12BC7, 0xBE0EBEB9, 0xE080E0A0, 0x8A5D8A10, 0x3BD23B52, 0x64D564BA, - 0xD8A0D888, 0xE784E7A5, 0x5F075FE8, 0x1B141B11, 0x2CB52CC2, 0xFC90FCB4, - 0x312C3127, 0x80A38065, 0x73B2732A, 0x0C730C81, 0x794C795F, 0x6B546B41, - 0x4B924B02, 0x53745369, 0x9436948F, 0x8351831F, 0x2A382A36, 0xC4B0C49C, - 0x22BD22C8, 0xD55AD5F8, 0xBDFCBDC3, 0x48604878, 0xFF62FFCE, 0x4C964C07, - 0x416C4177, 0xC742C7E6, 0xEBF7EB24, 0x1C101C14, 0x5D7C5D63, 0x36283622, - 0x672767C0, 0xE98CE9AF, 0x441344F9, 0x149514EA, 0xF59CF5BB, 0xCFC7CF18, - 0x3F243F2D, 0xC046C0E3, 0x723B72DB, 0x5470546C, 0x29CA294C, 0xF0E3F035, - 0x088508FE, 0xC6CBC617, 0xF311F34F, 0x8CD08CE4, 0xA493A459, 0xCAB8CA96, - 0x68A6683B, 0xB883B84D, 0x38203828, 0xE5FFE52E, 0xAD9FAD56, 0x0B770B84, - 0xC8C3C81D, 0x99CC99FF, 0x580358ED, 0x196F199A, 0x0E080E0A, 0x95BF957E, - 0x70407050, 0xF7E7F730, 0x6E2B6ECF, 0x1FE21F6E, 0xB579B53D, 0x090C090F, - 0x61AA6134, 0x57825716, 0x9F419F0B, 0x9D3A9D80, 0x11EA1164, 0x25B925CD, - 0xAFE4AFDD, 0x459A4508, 0xDFA4DF8D, 0xA397A35C, 0xEA7EEAD5, 0x35DA3558, - 0xED7AEDD0, 0x431743FC, 0xF866F8CB, 0xFB94FBB1, 0x37A137D3, 0xFA1DFA40, - 0xC23DC268, 0xB4F0B4CC, 0x32DE325D, 0x9CB39C71, 0x560B56E7, 0xE372E3DA, - 0x87A78760, 0x151C151B, 0xF9EFF93A, 0x63D163BF, 0x345334A9, 0x9A3E9A85, - 0xB18FB142, 0x7C337CD1, 0x8826889B, 0x3D5F3DA6, 0xA1ECA1D7, 0xE476E4DF, - 0x812A8194, 0x91499101, 0x0F810FFB, 0xEE88EEAA, 0x16EE1661, 0xD721D773, - 0x97C497F5, 0xA51AA5A8, 0xFEEBFE3F, 0x6DD96DB5, 0x78C578AE, 0xC539C56D, - 0x1D991DE5, 0x76CD76A4, 0x3EAD3EDC, 0xCB31CB67, 0xB68BB647, 0xEF01EF5B, - 0x1218121E, 0x602360C5, 0x6ADD6AB0, 0x4D1F4DF6, 0xCE4ECEE9, 0xDE2DDE7C, - 0x55F9559D, 0x7E487E5A, 0x214F21B2, 0x03F2037A, 0xA065A026, 0x5E8E5E19, - 0x5A785A66, 0x655C654B, 0x6258624E, 0xFD19FD45, 0x068D06F4, 0x40E54086, - 0xF298F2BE, 0x335733AC, 0x17671790, 0x057F058E, 0xE805E85E, 0x4F644F7D, - 0x89AF896A, 0x10631095, 0x74B6742F, 0x0AFE0A75, 0x5CF55C92, 0x9BB79B74, - 0x2D3C2D33, 0x30A530D6, 0x2ECE2E49, 0x49E94989, 0x46684672, 0x77447755, - 0xA8E0A8D8, 0x964D9604, 0x284328BD, 0xA969A929, 0xD929D979, 0x862E8691, - 0xD1ACD187, 0xF415F44A, 0x8D598D15, 0xD6A8D682, 0xB90AB9BC, 0x429E420D, - 0xF66EF6C1, 0x2F472FB8, 0xDDDFDD06, 0x23342339, 0xCC35CC62, 0xF16AF1C4, - 0xC1CFC112, 0x85DC85EB, 0x8F228F9E, 0x71C971A1, 0x90C090F0, 0xAA9BAA53, - 0x018901F1, 0x8BD48BE1, 0x4EED4E8C, 0x8EAB8E6F, 0xAB12ABA2, 0x6FA26F3E, - 0xE60DE654, 0xDB52DBF2, 0x92BB927B, 0xB702B7B6, 0x692F69CA, 0x39A939D9, - 0xD3D7D30C, 0xA761A723, 0xA21EA2AD, 0xC3B4C399, 0x6C506C44, 0x07040705, - 0x04F6047F, 0x27C22746, 0xAC16ACA7, 0xD025D076, 0x50865013, 0xDC56DCF7, - 0x8455841A, 0xE109E151, 0x7ABE7A25, 0x139113EF }; - -const u32bit Twofish::MDS3[256] = { - 0xD939A9D9, 0x90176790, 0x719CB371, 0xD2A6E8D2, 0x05070405, 0x9852FD98, - 0x6580A365, 0xDFE476DF, 0x08459A08, 0x024B9202, 0xA0E080A0, 0x665A7866, - 0xDDAFE4DD, 0xB06ADDB0, 0xBF63D1BF, 0x362A3836, 0x54E60D54, 0x4320C643, - 0x62CC3562, 0xBEF298BE, 0x1E12181E, 0x24EBF724, 0xD7A1ECD7, 0x77416C77, - 0xBD2843BD, 0x32BC7532, 0xD47B37D4, 0x9B88269B, 0x700DFA70, 0xF94413F9, - 0xB1FB94B1, 0x5A7E485A, 0x7A03F27A, 0xE48CD0E4, 0x47B68B47, 0x3C24303C, - 0xA5E784A5, 0x416B5441, 0x06DDDF06, 0xC56023C5, 0x45FD1945, 0xA33A5BA3, - 0x68C23D68, 0x158D5915, 0x21ECF321, 0x3166AE31, 0x3E6FA23E, 0x16578216, - 0x95106395, 0x5BEF015B, 0x4DB8834D, 0x91862E91, 0xB56DD9B5, 0x1F83511F, - 0x53AA9B53, 0x635D7C63, 0x3B68A63B, 0x3FFEEB3F, 0xD630A5D6, 0x257ABE25, - 0xA7AC16A7, 0x0F090C0F, 0x35F0E335, 0x23A76123, 0xF090C0F0, 0xAFE98CAF, - 0x809D3A80, 0x925CF592, 0x810C7381, 0x27312C27, 0x76D02576, 0xE7560BE7, - 0x7B92BB7B, 0xE9CE4EE9, 0xF10189F1, 0x9F1E6B9F, 0xA93453A9, 0xC4F16AC4, - 0x99C3B499, 0x975BF197, 0x8347E183, 0x6B18E66B, 0xC822BDC8, 0x0E98450E, - 0x6E1FE26E, 0xC9B3F4C9, 0x2F74B62F, 0xCBF866CB, 0xFF99CCFF, 0xEA1495EA, - 0xED5803ED, 0xF7DC56F7, 0xE18BD4E1, 0x1B151C1B, 0xADA21EAD, 0x0CD3D70C, - 0x2BE2FB2B, 0x1DC8C31D, 0x195E8E19, 0xC22CB5C2, 0x8949E989, 0x12C1CF12, - 0x7E95BF7E, 0x207DBA20, 0x6411EA64, 0x840B7784, 0x6DC5396D, 0x6A89AF6A, - 0xD17C33D1, 0xA171C9A1, 0xCEFF62CE, 0x37BB7137, 0xFB0F81FB, 0x3DB5793D, - 0x51E10951, 0xDC3EADDC, 0x2D3F242D, 0xA476CDA4, 0x9D55F99D, 0xEE82D8EE, - 0x8640E586, 0xAE78C5AE, 0xCD25B9CD, 0x04964D04, 0x55774455, 0x0A0E080A, - 0x13508613, 0x30F7E730, 0xD337A1D3, 0x40FA1D40, 0x3461AA34, 0x8C4EED8C, - 0xB3B006B3, 0x6C54706C, 0x2A73B22A, 0x523BD252, 0x0B9F410B, 0x8B027B8B, - 0x88D8A088, 0x4FF3114F, 0x67CB3167, 0x4627C246, 0xC06727C0, 0xB4FC90B4, - 0x28382028, 0x7F04F67F, 0x78486078, 0x2EE5FF2E, 0x074C9607, 0x4B655C4B, - 0xC72BB1C7, 0x6F8EAB6F, 0x0D429E0D, 0xBBF59CBB, 0xF2DB52F2, 0xF34A1BF3, - 0xA63D5FA6, 0x59A49359, 0xBCB90ABC, 0x3AF9EF3A, 0xEF1391EF, 0xFE0885FE, - 0x01914901, 0x6116EE61, 0x7CDE2D7C, 0xB2214FB2, 0x42B18F42, 0xDB723BDB, - 0xB82F47B8, 0x48BF8748, 0x2CAE6D2C, 0xE3C046E3, 0x573CD657, 0x859A3E85, - 0x29A96929, 0x7D4F647D, 0x94812A94, 0x492ECE49, 0x17C6CB17, 0xCA692FCA, - 0xC3BDFCC3, 0x5CA3975C, 0x5EE8055E, 0xD0ED7AD0, 0x87D1AC87, 0x8E057F8E, - 0xBA64D5BA, 0xA8A51AA8, 0xB7264BB7, 0xB9BE0EB9, 0x6087A760, 0xF8D55AF8, - 0x22362822, 0x111B1411, 0xDE753FDE, 0x79D92979, 0xAAEE88AA, 0x332D3C33, - 0x5F794C5F, 0xB6B702B6, 0x96CAB896, 0x5835DA58, 0x9CC4B09C, 0xFC4317FC, - 0x1A84551A, 0xF64D1FF6, 0x1C598A1C, 0x38B27D38, 0xAC3357AC, 0x18CFC718, - 0xF4068DF4, 0x69537469, 0x749BB774, 0xF597C4F5, 0x56AD9F56, 0xDAE372DA, - 0xD5EA7ED5, 0x4AF4154A, 0x9E8F229E, 0xA2AB12A2, 0x4E62584E, 0xE85F07E8, - 0xE51D99E5, 0x39233439, 0xC1F66EC1, 0x446C5044, 0x5D32DE5D, 0x72466872, - 0x26A06526, 0x93CDBC93, 0x03DADB03, 0xC6BAF8C6, 0xFA9EC8FA, 0x82D6A882, - 0xCF6E2BCF, 0x50704050, 0xEB85DCEB, 0x750AFE75, 0x8A93328A, 0x8DDFA48D, - 0x4C29CA4C, 0x141C1014, 0x73D72173, 0xCCB4F0CC, 0x09D4D309, 0x108A5D10, - 0xE2510FE2, 0x00000000, 0x9A196F9A, 0xE01A9DE0, 0x8F94368F, 0xE6C742E6, - 0xECC94AEC, 0xFDD25EFD, 0xAB7FC1AB, 0xD8A8E0D8 }; - -} -/* -* Twofish -* (C) 1999-2007 Jack Lloyd -* -* The key schedule implemenation is based on a public domain -* implementation by Matthew Skala -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -/* -* Twofish Encryption -*/ -void Twofish::encrypt_n(const byte in[], byte out[], size_t blocks) const - { - for(size_t i = 0; i != blocks; ++i) - { - u32bit A = load_le(in, 0) ^ RK[0]; - u32bit B = load_le(in, 1) ^ RK[1]; - u32bit C = load_le(in, 2) ^ RK[2]; - u32bit D = load_le(in, 3) ^ RK[3]; - - for(size_t j = 0; j != 16; j += 2) - { - u32bit X, Y; - - X = SB[ get_byte(3, A)] ^ SB[256+get_byte(2, A)] ^ - SB[512+get_byte(1, A)] ^ SB[768+get_byte(0, A)]; - Y = SB[ get_byte(0, B)] ^ SB[256+get_byte(3, B)] ^ - SB[512+get_byte(2, B)] ^ SB[768+get_byte(1, B)]; - X += Y; - Y += X + RK[2*j + 9]; - X += RK[2*j + 8]; - - C = rotate_right(C ^ X, 1); - D = rotate_left(D, 1) ^ Y; - - X = SB[ get_byte(3, C)] ^ SB[256+get_byte(2, C)] ^ - SB[512+get_byte(1, C)] ^ SB[768+get_byte(0, C)]; - Y = SB[ get_byte(0, D)] ^ SB[256+get_byte(3, D)] ^ - SB[512+get_byte(2, D)] ^ SB[768+get_byte(1, D)]; - X += Y; - Y += X + RK[2*j + 11]; - X += RK[2*j + 10]; - - A = rotate_right(A ^ X, 1); - B = rotate_left(B, 1) ^ Y; - } - - C ^= RK[4]; - D ^= RK[5]; - A ^= RK[6]; - B ^= RK[7]; - - store_le(out, C, D, A, B); - - in += BLOCK_SIZE; - out += BLOCK_SIZE; - } - } - -/* -* Twofish Decryption -*/ -void Twofish::decrypt_n(const byte in[], byte out[], size_t blocks) const - { - for(size_t i = 0; i != blocks; ++i) - { - u32bit A = load_le(in, 0) ^ RK[4]; - u32bit B = load_le(in, 1) ^ RK[5]; - u32bit C = load_le(in, 2) ^ RK[6]; - u32bit D = load_le(in, 3) ^ RK[7]; - - for(size_t j = 0; j != 16; j += 2) - { - u32bit X, Y; - - X = SB[ get_byte(3, A)] ^ SB[256+get_byte(2, A)] ^ - SB[512+get_byte(1, A)] ^ SB[768+get_byte(0, A)]; - Y = SB[ get_byte(0, B)] ^ SB[256+get_byte(3, B)] ^ - SB[512+get_byte(2, B)] ^ SB[768+get_byte(1, B)]; - X += Y; - Y += X + RK[39 - 2*j]; - X += RK[38 - 2*j]; - - C = rotate_left(C, 1) ^ X; - D = rotate_right(D ^ Y, 1); - - X = SB[ get_byte(3, C)] ^ SB[256+get_byte(2, C)] ^ - SB[512+get_byte(1, C)] ^ SB[768+get_byte(0, C)]; - Y = SB[ get_byte(0, D)] ^ SB[256+get_byte(3, D)] ^ - SB[512+get_byte(2, D)] ^ SB[768+get_byte(1, D)]; - X += Y; - Y += X + RK[37 - 2*j]; - X += RK[36 - 2*j]; - - A = rotate_left(A, 1) ^ X; - B = rotate_right(B ^ Y, 1); - } - - C ^= RK[0]; - D ^= RK[1]; - A ^= RK[2]; - B ^= RK[3]; - - store_le(out, C, D, A, B); - - in += BLOCK_SIZE; - out += BLOCK_SIZE; - } - } - -/* -* Twofish Key Schedule -*/ -void Twofish::key_schedule(const byte key[], size_t length) - { - SecureVector S(16); - - for(size_t i = 0; i != length; ++i) - rs_mul(&S[4*(i/8)], key[i], i); - - if(length == 16) - { - for(size_t i = 0; i != 256; ++i) - { - SB[ i] = MDS0[Q0[Q0[i]^S[ 0]]^S[ 4]]; - SB[256+i] = MDS1[Q0[Q1[i]^S[ 1]]^S[ 5]]; - SB[512+i] = MDS2[Q1[Q0[i]^S[ 2]]^S[ 6]]; - SB[768+i] = MDS3[Q1[Q1[i]^S[ 3]]^S[ 7]]; - } - - for(size_t i = 0; i != 40; i += 2) - { - u32bit X = MDS0[Q0[Q0[i ]^key[ 8]]^key[ 0]] ^ - MDS1[Q0[Q1[i ]^key[ 9]]^key[ 1]] ^ - MDS2[Q1[Q0[i ]^key[10]]^key[ 2]] ^ - MDS3[Q1[Q1[i ]^key[11]]^key[ 3]]; - u32bit Y = MDS0[Q0[Q0[i+1]^key[12]]^key[ 4]] ^ - MDS1[Q0[Q1[i+1]^key[13]]^key[ 5]] ^ - MDS2[Q1[Q0[i+1]^key[14]]^key[ 6]] ^ - MDS3[Q1[Q1[i+1]^key[15]]^key[ 7]]; - Y = rotate_left(Y, 8); - X += Y; Y += X; - - RK[i] = X; - RK[i+1] = rotate_left(Y, 9); - } - } - else if(length == 24) - { - for(size_t i = 0; i != 256; ++i) - { - SB[ i] = MDS0[Q0[Q0[Q1[i]^S[ 0]]^S[ 4]]^S[ 8]]; - SB[256+i] = MDS1[Q0[Q1[Q1[i]^S[ 1]]^S[ 5]]^S[ 9]]; - SB[512+i] = MDS2[Q1[Q0[Q0[i]^S[ 2]]^S[ 6]]^S[10]]; - SB[768+i] = MDS3[Q1[Q1[Q0[i]^S[ 3]]^S[ 7]]^S[11]]; - } - - for(size_t i = 0; i != 40; i += 2) - { - u32bit X = MDS0[Q0[Q0[Q1[i ]^key[16]]^key[ 8]]^key[ 0]] ^ - MDS1[Q0[Q1[Q1[i ]^key[17]]^key[ 9]]^key[ 1]] ^ - MDS2[Q1[Q0[Q0[i ]^key[18]]^key[10]]^key[ 2]] ^ - MDS3[Q1[Q1[Q0[i ]^key[19]]^key[11]]^key[ 3]]; - u32bit Y = MDS0[Q0[Q0[Q1[i+1]^key[20]]^key[12]]^key[ 4]] ^ - MDS1[Q0[Q1[Q1[i+1]^key[21]]^key[13]]^key[ 5]] ^ - MDS2[Q1[Q0[Q0[i+1]^key[22]]^key[14]]^key[ 6]] ^ - MDS3[Q1[Q1[Q0[i+1]^key[23]]^key[15]]^key[ 7]]; - Y = rotate_left(Y, 8); - X += Y; Y += X; - - RK[i] = X; - RK[i+1] = rotate_left(Y, 9); - } - } - else if(length == 32) - { - for(size_t i = 0; i != 256; ++i) - { - SB[ i] = MDS0[Q0[Q0[Q1[Q1[i]^S[ 0]]^S[ 4]]^S[ 8]]^S[12]]; - SB[256+i] = MDS1[Q0[Q1[Q1[Q0[i]^S[ 1]]^S[ 5]]^S[ 9]]^S[13]]; - SB[512+i] = MDS2[Q1[Q0[Q0[Q0[i]^S[ 2]]^S[ 6]]^S[10]]^S[14]]; - SB[768+i] = MDS3[Q1[Q1[Q0[Q1[i]^S[ 3]]^S[ 7]]^S[11]]^S[15]]; - } - - for(size_t i = 0; i != 40; i += 2) - { - u32bit X = MDS0[Q0[Q0[Q1[Q1[i ]^key[24]]^key[16]]^key[ 8]]^key[ 0]] ^ - MDS1[Q0[Q1[Q1[Q0[i ]^key[25]]^key[17]]^key[ 9]]^key[ 1]] ^ - MDS2[Q1[Q0[Q0[Q0[i ]^key[26]]^key[18]]^key[10]]^key[ 2]] ^ - MDS3[Q1[Q1[Q0[Q1[i ]^key[27]]^key[19]]^key[11]]^key[ 3]]; - u32bit Y = MDS0[Q0[Q0[Q1[Q1[i+1]^key[28]]^key[20]]^key[12]]^key[ 4]] ^ - MDS1[Q0[Q1[Q1[Q0[i+1]^key[29]]^key[21]]^key[13]]^key[ 5]] ^ - MDS2[Q1[Q0[Q0[Q0[i+1]^key[30]]^key[22]]^key[14]]^key[ 6]] ^ - MDS3[Q1[Q1[Q0[Q1[i+1]^key[31]]^key[23]]^key[15]]^key[ 7]]; - Y = rotate_left(Y, 8); - X += Y; Y += X; - - RK[i] = X; - RK[i+1] = rotate_left(Y, 9); - } - } - } - -/* -* Do one column of the RS matrix multiplcation -*/ -void Twofish::rs_mul(byte S[4], byte key, size_t offset) - { - if(key) - { - byte X = POLY_TO_EXP[key - 1]; - - byte RS1 = RS[(4*offset ) % 32]; - byte RS2 = RS[(4*offset+1) % 32]; - byte RS3 = RS[(4*offset+2) % 32]; - byte RS4 = RS[(4*offset+3) % 32]; - - S[0] ^= EXP_TO_POLY[(X + POLY_TO_EXP[RS1 - 1]) % 255]; - S[1] ^= EXP_TO_POLY[(X + POLY_TO_EXP[RS2 - 1]) % 255]; - S[2] ^= EXP_TO_POLY[(X + POLY_TO_EXP[RS3 - 1]) % 255]; - S[3] ^= EXP_TO_POLY[(X + POLY_TO_EXP[RS4 - 1]) % 255]; - } - } - -/* -* Clear memory of sensitive data -*/ -void Twofish::clear() - { - zeroise(SB); - zeroise(RK); - } - -} -/* -* XTEA -* (C) 1999-2009 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -namespace { - -void xtea_encrypt_4(const byte in[32], byte out[32], const u32bit EK[64]) - { - u32bit L0, R0, L1, R1, L2, R2, L3, R3; - load_be(in, L0, R0, L1, R1, L2, R2, L3, R3); - - for(size_t i = 0; i != 32; ++i) - { - L0 += (((R0 << 4) ^ (R0 >> 5)) + R0) ^ EK[2*i]; - L1 += (((R1 << 4) ^ (R1 >> 5)) + R1) ^ EK[2*i]; - L2 += (((R2 << 4) ^ (R2 >> 5)) + R2) ^ EK[2*i]; - L3 += (((R3 << 4) ^ (R3 >> 5)) + R3) ^ EK[2*i]; - - R0 += (((L0 << 4) ^ (L0 >> 5)) + L0) ^ EK[2*i+1]; - R1 += (((L1 << 4) ^ (L1 >> 5)) + L1) ^ EK[2*i+1]; - R2 += (((L2 << 4) ^ (L2 >> 5)) + L2) ^ EK[2*i+1]; - R3 += (((L3 << 4) ^ (L3 >> 5)) + L3) ^ EK[2*i+1]; - } - - store_be(out, L0, R0, L1, R1, L2, R2, L3, R3); - } - -void xtea_decrypt_4(const byte in[32], byte out[32], const u32bit EK[64]) - { - u32bit L0, R0, L1, R1, L2, R2, L3, R3; - load_be(in, L0, R0, L1, R1, L2, R2, L3, R3); - - for(size_t i = 0; i != 32; ++i) - { - R0 -= (((L0 << 4) ^ (L0 >> 5)) + L0) ^ EK[63 - 2*i]; - R1 -= (((L1 << 4) ^ (L1 >> 5)) + L1) ^ EK[63 - 2*i]; - R2 -= (((L2 << 4) ^ (L2 >> 5)) + L2) ^ EK[63 - 2*i]; - R3 -= (((L3 << 4) ^ (L3 >> 5)) + L3) ^ EK[63 - 2*i]; - - L0 -= (((R0 << 4) ^ (R0 >> 5)) + R0) ^ EK[62 - 2*i]; - L1 -= (((R1 << 4) ^ (R1 >> 5)) + R1) ^ EK[62 - 2*i]; - L2 -= (((R2 << 4) ^ (R2 >> 5)) + R2) ^ EK[62 - 2*i]; - L3 -= (((R3 << 4) ^ (R3 >> 5)) + R3) ^ EK[62 - 2*i]; - } - - store_be(out, L0, R0, L1, R1, L2, R2, L3, R3); - } - -} - -/* -* XTEA Encryption -*/ -void XTEA::encrypt_n(const byte in[], byte out[], size_t blocks) const - { - while(blocks >= 4) - { - xtea_encrypt_4(in, out, &(this->EK[0])); - in += 4 * BLOCK_SIZE; - out += 4 * BLOCK_SIZE; - blocks -= 4; - } - - for(size_t i = 0; i != blocks; ++i) - { - u32bit L = load_be(in, 0); - u32bit R = load_be(in, 1); - - for(size_t j = 0; j != 32; ++j) - { - L += (((R << 4) ^ (R >> 5)) + R) ^ EK[2*j]; - R += (((L << 4) ^ (L >> 5)) + L) ^ EK[2*j+1]; - } - - store_be(out, L, R); - - in += BLOCK_SIZE; - out += BLOCK_SIZE; - } - } - -/* -* XTEA Decryption -*/ -void XTEA::decrypt_n(const byte in[], byte out[], size_t blocks) const - { - while(blocks >= 4) - { - xtea_decrypt_4(in, out, &(this->EK[0])); - in += 4 * BLOCK_SIZE; - out += 4 * BLOCK_SIZE; - blocks -= 4; - } - - for(size_t i = 0; i != blocks; ++i) - { - u32bit L = load_be(in, 0); - u32bit R = load_be(in, 1); - - for(size_t j = 0; j != 32; ++j) - { - R -= (((L << 4) ^ (L >> 5)) + L) ^ EK[63 - 2*j]; - L -= (((R << 4) ^ (R >> 5)) + R) ^ EK[62 - 2*j]; - } - - store_be(out, L, R); - - in += BLOCK_SIZE; - out += BLOCK_SIZE; - } - } - -/* -* XTEA Key Schedule -*/ -void XTEA::key_schedule(const byte key[], size_t) - { - SecureVector UK(4); - for(size_t i = 0; i != 4; ++i) - UK[i] = load_be(key, i); - - u32bit D = 0; - for(size_t i = 0; i != 64; i += 2) - { - EK[i ] = D + UK[D % 4]; - D += 0x9E3779B9; - EK[i+1] = D + UK[(D >> 11) % 4]; - } - } - -} -/* -* XTEA in SIMD -* (C) 2009 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -namespace { - -void xtea_encrypt_8(const byte in[64], byte out[64], const u32bit EK[64]) - { - SIMD_32 L0 = SIMD_32::load_be(in ); - SIMD_32 R0 = SIMD_32::load_be(in + 16); - SIMD_32 L1 = SIMD_32::load_be(in + 32); - SIMD_32 R1 = SIMD_32::load_be(in + 48); - - SIMD_32::transpose(L0, R0, L1, R1); - - for(size_t i = 0; i != 32; i += 2) - { - SIMD_32 K0(EK[2*i ]); - SIMD_32 K1(EK[2*i+1]); - SIMD_32 K2(EK[2*i+2]); - SIMD_32 K3(EK[2*i+3]); - - L0 += (((R0 << 4) ^ (R0 >> 5)) + R0) ^ K0; - L1 += (((R1 << 4) ^ (R1 >> 5)) + R1) ^ K0; - - R0 += (((L0 << 4) ^ (L0 >> 5)) + L0) ^ K1; - R1 += (((L1 << 4) ^ (L1 >> 5)) + L1) ^ K1; - - L0 += (((R0 << 4) ^ (R0 >> 5)) + R0) ^ K2; - L1 += (((R1 << 4) ^ (R1 >> 5)) + R1) ^ K2; - - R0 += (((L0 << 4) ^ (L0 >> 5)) + L0) ^ K3; - R1 += (((L1 << 4) ^ (L1 >> 5)) + L1) ^ K3; - } - - SIMD_32::transpose(L0, R0, L1, R1); - - L0.store_be(out); - R0.store_be(out + 16); - L1.store_be(out + 32); - R1.store_be(out + 48); - } - -void xtea_decrypt_8(const byte in[64], byte out[64], const u32bit EK[64]) - { - SIMD_32 L0 = SIMD_32::load_be(in ); - SIMD_32 R0 = SIMD_32::load_be(in + 16); - SIMD_32 L1 = SIMD_32::load_be(in + 32); - SIMD_32 R1 = SIMD_32::load_be(in + 48); - - SIMD_32::transpose(L0, R0, L1, R1); - - for(size_t i = 0; i != 32; i += 2) - { - SIMD_32 K0(EK[63 - 2*i]); - SIMD_32 K1(EK[62 - 2*i]); - SIMD_32 K2(EK[61 - 2*i]); - SIMD_32 K3(EK[60 - 2*i]); - - R0 -= (((L0 << 4) ^ (L0 >> 5)) + L0) ^ K0; - R1 -= (((L1 << 4) ^ (L1 >> 5)) + L1) ^ K0; - - L0 -= (((R0 << 4) ^ (R0 >> 5)) + R0) ^ K1; - L1 -= (((R1 << 4) ^ (R1 >> 5)) + R1) ^ K1; - - R0 -= (((L0 << 4) ^ (L0 >> 5)) + L0) ^ K2; - R1 -= (((L1 << 4) ^ (L1 >> 5)) + L1) ^ K2; - - L0 -= (((R0 << 4) ^ (R0 >> 5)) + R0) ^ K3; - L1 -= (((R1 << 4) ^ (R1 >> 5)) + R1) ^ K3; - } - - SIMD_32::transpose(L0, R0, L1, R1); - - L0.store_be(out); - R0.store_be(out + 16); - L1.store_be(out + 32); - R1.store_be(out + 48); - } - -} - -/* -* XTEA Encryption -*/ -void XTEA_SIMD::encrypt_n(const byte in[], byte out[], size_t blocks) const - { - const u32bit* KS = &(this->get_EK()[0]); - - while(blocks >= 8) - { - xtea_encrypt_8(in, out, KS); - in += 8 * BLOCK_SIZE; - out += 8 * BLOCK_SIZE; - blocks -= 8; - } - - if(blocks) - XTEA::encrypt_n(in, out, blocks); - } - -/* -* XTEA Decryption -*/ -void XTEA_SIMD::decrypt_n(const byte in[], byte out[], size_t blocks) const - { - const u32bit* KS = &(this->get_EK()[0]); - - while(blocks >= 8) - { - xtea_decrypt_8(in, out, KS); - in += 8 * BLOCK_SIZE; - out += 8 * BLOCK_SIZE; - blocks -= 8; - } - - if(blocks) - XTEA::decrypt_n(in, out, blocks); - } - -} -/* -* Certificate Store -* (C) 1999-2010 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -Certificate_Store* Certificate_Store_Memory::clone() const - { - return new Certificate_Store_Memory(*this); - } - -void Certificate_Store_Memory::add_certificate(const X509_Certificate& cert) - { - for(size_t i = 0; i != certs.size(); ++i) - { - if(certs[i] == cert) - return; - } - - certs.push_back(cert); - } - -std::vector -Certificate_Store_Memory::find_cert_by_subject_and_key_id( - const X509_DN& subject_dn, - const MemoryRegion& key_id) const - { - std::vector result; - - for(size_t i = 0; i != certs.size(); ++i) - { - // Only compare key ids if set in both call and in the cert - if(key_id.size()) - { - MemoryVector skid = certs[i].subject_key_id(); - - if(skid.size() && skid != key_id) // no match - continue; - } - - if(certs[i].subject_dn() == subject_dn) - result.push_back(certs[i]); - } - - return result; - } - -void Certificate_Store_Memory::add_crl(const X509_CRL& crl) - { - X509_DN crl_issuer = crl.issuer_dn(); - - for(size_t i = 0; i != crls.size(); ++i) - { - // Found an update of a previously existing one; replace it - if(crls[i].issuer_dn() == crl_issuer) - { - if(crls[i].this_update() < crl.this_update()) - { - crls[i] = crl; - return; - } - } - } - - // Totally new CRL, add to the list - crls.push_back(crl); - } - -std::vector -Certificate_Store_Memory::find_crl_by_subject_and_key_id( - const X509_DN& issuer_dn, - const MemoryRegion& key_id) const - { - std::vector result; - - for(size_t i = 0; i != crls.size(); ++i) - { - // Only compare key ids if set in both call and in the CRL - if(key_id.size()) - { - MemoryVector akid = crls[i].authority_key_id(); - - if(akid.size() && akid != key_id) // no match - continue; - } - - if(crls[i].issuer_dn() == issuer_dn) - result.push_back(crls[i]); - } - - return result; - } - -} -/* -* PKCS #10 -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -/* -* PKCS10_Request Constructor -*/ -PKCS10_Request::PKCS10_Request(DataSource& in) : - X509_Object(in, "CERTIFICATE REQUEST/NEW CERTIFICATE REQUEST") - { - do_decode(); - } - -/* -* PKCS10_Request Constructor -*/ -PKCS10_Request::PKCS10_Request(const std::string& in) : - X509_Object(in, "CERTIFICATE REQUEST/NEW CERTIFICATE REQUEST") - { - do_decode(); - } - -/* -* Deocde the CertificateRequestInfo -*/ -void PKCS10_Request::force_decode() - { - BER_Decoder cert_req_info(tbs_bits); - - size_t version; - cert_req_info.decode(version); - if(version != 0) - throw Decoding_Error("Unknown version code in PKCS #10 request: " + - to_string(version)); - - X509_DN dn_subject; - cert_req_info.decode(dn_subject); - - info.add(dn_subject.contents()); - - BER_Object public_key = cert_req_info.get_next_object(); - if(public_key.type_tag != SEQUENCE || public_key.class_tag != CONSTRUCTED) - throw BER_Bad_Tag("PKCS10_Request: Unexpected tag for public key", - public_key.type_tag, public_key.class_tag); - - info.add("X509.Certificate.public_key", - PEM_Code::encode( - ASN1::put_in_sequence(public_key.value), - "PUBLIC KEY" - ) - ); - - BER_Object attr_bits = cert_req_info.get_next_object(); - - if(attr_bits.type_tag == 0 && - attr_bits.class_tag == ASN1_Tag(CONSTRUCTED | CONTEXT_SPECIFIC)) - { - BER_Decoder attributes(attr_bits.value); - while(attributes.more_items()) - { - Attribute attr; - attributes.decode(attr); - handle_attribute(attr); - } - attributes.verify_end(); - } - else if(attr_bits.type_tag != NO_OBJECT) - throw BER_Bad_Tag("PKCS10_Request: Unexpected tag for attributes", - attr_bits.type_tag, attr_bits.class_tag); - - cert_req_info.verify_end(); - - if(!this->check_signature(subject_public_key())) - throw Decoding_Error("PKCS #10 request: Bad signature detected"); - } - -/* -* Handle attributes in a PKCS #10 request -*/ -void PKCS10_Request::handle_attribute(const Attribute& attr) - { - BER_Decoder value(attr.parameters); - - if(attr.oid == OIDS::lookup("PKCS9.EmailAddress")) - { - ASN1_String email; - value.decode(email); - info.add("RFC822", email.value()); - } - else if(attr.oid == OIDS::lookup("PKCS9.ChallengePassword")) - { - ASN1_String challenge_password; - value.decode(challenge_password); - info.add("PKCS9.ChallengePassword", challenge_password.value()); - } - else if(attr.oid == OIDS::lookup("PKCS9.ExtensionRequest")) - { - Extensions extensions; - value.decode(extensions).verify_end(); - - Data_Store issuer_info; - extensions.contents_to(info, issuer_info); - } - } - -/* -* Return the challenge password (if any) -*/ -std::string PKCS10_Request::challenge_password() const - { - return info.get1("PKCS9.ChallengePassword"); - } - -/* -* Return the name of the requestor -*/ -X509_DN PKCS10_Request::subject_dn() const - { - return create_dn(info); - } - -/* -* Return the public key of the requestor -*/ -MemoryVector PKCS10_Request::raw_public_key() const - { - DataSource_Memory source(info.get1("X509.Certificate.public_key")); - return PEM_Code::decode_check_label(source, "PUBLIC KEY"); - } - -/* -* Return the public key of the requestor -*/ -Public_Key* PKCS10_Request::subject_public_key() const - { - DataSource_Memory source(info.get1("X509.Certificate.public_key")); - return X509::load_key(source); - } - -/* -* Return the alternative names of the requestor -*/ -AlternativeName PKCS10_Request::subject_alt_name() const - { - return create_alt_name(info); - } - -/* -* Return the key constraints (if any) -*/ -Key_Constraints PKCS10_Request::constraints() const - { - return Key_Constraints(info.get1_u32bit("X509v3.KeyUsage", NO_CONSTRAINTS)); - } - -/* -* Return the extendend key constraints (if any) -*/ -std::vector PKCS10_Request::ex_constraints() const - { - std::vector oids = info.get("X509v3.ExtendedKeyUsage"); - - std::vector result; - for(size_t i = 0; i != oids.size(); ++i) - result.push_back(OID(oids[i])); - return result; - } - -/* -* Return is a CA certificate is requested -*/ -bool PKCS10_Request::is_CA() const - { - return (info.get1_u32bit("X509v3.BasicConstraints.is_ca") > 0); - } - -/* -* Return the desired path limit (if any) -*/ -u32bit PKCS10_Request::path_limit() const - { - return info.get1_u32bit("X509v3.BasicConstraints.path_constraint", 0); - } - -} -/* -* X.509 Certificate Authority -* (C) 1999-2010 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include -#include -#include -#include -#include - -namespace Botan { - -/* -* Load the certificate and private key -*/ -X509_CA::X509_CA(const X509_Certificate& c, - const Private_Key& key, - const std::string& hash_fn) : cert(c) - { - if(!cert.is_CA_cert()) - throw Invalid_Argument("X509_CA: This certificate is not for a CA"); - - signer = choose_sig_format(key, hash_fn, ca_sig_algo); - } - -/* -* X509_CA Destructor -*/ -X509_CA::~X509_CA() - { - delete signer; - } - -/* -* Sign a PKCS #10 certificate request -*/ -X509_Certificate X509_CA::sign_request(const PKCS10_Request& req, - RandomNumberGenerator& rng, - const X509_Time& not_before, - const X509_Time& not_after) - { - Key_Constraints constraints; - if(req.is_CA()) - constraints = Key_Constraints(KEY_CERT_SIGN | CRL_SIGN); - else - { - std::unique_ptr key(req.subject_public_key()); - constraints = X509::find_constraints(*key, req.constraints()); - } - - Extensions extensions; - - extensions.add( - new Cert_Extension::Basic_Constraints(req.is_CA(), req.path_limit()), - true); - - extensions.add(new Cert_Extension::Key_Usage(constraints), true); - - extensions.add(new Cert_Extension::Authority_Key_ID(cert.subject_key_id())); - extensions.add(new Cert_Extension::Subject_Key_ID(req.raw_public_key())); - - extensions.add( - new Cert_Extension::Subject_Alternative_Name(req.subject_alt_name())); - - extensions.add( - new Cert_Extension::Extended_Key_Usage(req.ex_constraints())); - - return make_cert(signer, rng, ca_sig_algo, - req.raw_public_key(), - not_before, not_after, - cert.subject_dn(), req.subject_dn(), - extensions); - } - -/* -* Create a new certificate -*/ -X509_Certificate X509_CA::make_cert(PK_Signer* signer, - RandomNumberGenerator& rng, - const AlgorithmIdentifier& sig_algo, - const MemoryRegion& pub_key, - const X509_Time& not_before, - const X509_Time& not_after, - const X509_DN& issuer_dn, - const X509_DN& subject_dn, - const Extensions& extensions) - { - const size_t X509_CERT_VERSION = 3; - const size_t SERIAL_BITS = 128; - - BigInt serial_no(rng, SERIAL_BITS); - - DataSource_Memory source(X509_Object::make_signed(signer, rng, sig_algo, - DER_Encoder().start_cons(SEQUENCE) - .start_explicit(0) - .encode(X509_CERT_VERSION-1) - .end_explicit() - - .encode(serial_no) - - .encode(sig_algo) - .encode(issuer_dn) - - .start_cons(SEQUENCE) - .encode(not_before) - .encode(not_after) - .end_cons() - - .encode(subject_dn) - .raw_bytes(pub_key) - - .start_explicit(3) - .start_cons(SEQUENCE) - .encode(extensions) - .end_cons() - .end_explicit() - .end_cons() - .get_contents() - )); - - return X509_Certificate(source); - } - -/* -* Create a new, empty CRL -*/ -X509_CRL X509_CA::new_crl(RandomNumberGenerator& rng, - u32bit next_update) const - { - std::vector empty; - return make_crl(empty, 1, next_update, rng); - } - -/* -* Update a CRL with new entries -*/ -X509_CRL X509_CA::update_crl(const X509_CRL& crl, - const std::vector& new_revoked, - RandomNumberGenerator& rng, - u32bit next_update) const - { - std::vector revoked = crl.get_revoked(); - - std::copy(new_revoked.begin(), new_revoked.end(), - std::back_inserter(revoked)); - - return make_crl(revoked, crl.crl_number() + 1, next_update, rng); - } - -/* -* Create a CRL -*/ -X509_CRL X509_CA::make_crl(const std::vector& revoked, - u32bit crl_number, u32bit next_update, - RandomNumberGenerator& rng) const - { - const size_t X509_CRL_VERSION = 2; - - if(next_update == 0) - next_update = timespec_to_u32bit("7d"); - - // Totally stupid: ties encoding logic to the return of std::time!! - const u64bit current_time = system_time(); - - Extensions extensions; - extensions.add( - new Cert_Extension::Authority_Key_ID(cert.subject_key_id())); - extensions.add(new Cert_Extension::CRL_Number(crl_number)); - - DataSource_Memory source(X509_Object::make_signed(signer, rng, ca_sig_algo, - DER_Encoder().start_cons(SEQUENCE) - .encode(X509_CRL_VERSION-1) - .encode(ca_sig_algo) - .encode(cert.issuer_dn()) - .encode(X509_Time(current_time)) - .encode(X509_Time(current_time + next_update)) - .encode_if(revoked.size() > 0, - DER_Encoder() - .start_cons(SEQUENCE) - .encode_list(revoked) - .end_cons() - ) - .start_explicit(0) - .start_cons(SEQUENCE) - .encode(extensions) - .end_cons() - .end_explicit() - .end_cons() - .get_contents() - )); - - return X509_CRL(source); - } - -/* -* Return the CA's certificate -*/ -X509_Certificate X509_CA::ca_certificate() const - { - return cert; - } - -/* -* Choose a signing format for the key -*/ -PK_Signer* choose_sig_format(const Private_Key& key, - const std::string& hash_fn, - AlgorithmIdentifier& sig_algo) - { - std::string padding; - - const std::string algo_name = key.algo_name(); - - const HashFunction* proto_hash = retrieve_hash(hash_fn); - if(!proto_hash) - throw Algorithm_Not_Found(hash_fn); - - if(key.max_input_bits() < proto_hash->output_length()*8) - throw Invalid_Argument("Key is too small for chosen hash function"); - - if(algo_name == "RSA") - padding = "EMSA3"; - else if(algo_name == "DSA") - padding = "EMSA1"; - else if(algo_name == "ECDSA") - padding = "EMSA1_BSI"; - else - throw Invalid_Argument("Unknown X.509 signing key type: " + algo_name); - - Signature_Format format = - (key.message_parts() > 1) ? DER_SEQUENCE : IEEE_1363; - - padding = padding + '(' + proto_hash->name() + ')'; - - sig_algo.oid = OIDS::lookup(algo_name + "/" + padding); - sig_algo.parameters = key.algorithm_identifier().parameters; - - return new PK_Signer(key, padding, format); - } - -} -/* -* X.509 Certificate Extensions -* (C) 1999-2010 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include -#include - -namespace Botan { - -/* -* List of X.509 Certificate Extensions -*/ -Certificate_Extension* Extensions::get_extension(const OID& oid) - { -#define X509_EXTENSION(NAME, TYPE) \ - if(OIDS::name_of(oid, NAME)) \ - return new Cert_Extension::TYPE(); - - X509_EXTENSION("X509v3.KeyUsage", Key_Usage); - X509_EXTENSION("X509v3.BasicConstraints", Basic_Constraints); - X509_EXTENSION("X509v3.SubjectKeyIdentifier", Subject_Key_ID); - X509_EXTENSION("X509v3.AuthorityKeyIdentifier", Authority_Key_ID); - X509_EXTENSION("X509v3.ExtendedKeyUsage", Extended_Key_Usage); - X509_EXTENSION("X509v3.IssuerAlternativeName", Issuer_Alternative_Name); - X509_EXTENSION("X509v3.SubjectAlternativeName", Subject_Alternative_Name); - X509_EXTENSION("X509v3.CRLNumber", CRL_Number); - X509_EXTENSION("X509v3.CertificatePolicies", Certificate_Policies); - X509_EXTENSION("X509v3.ReasonCode", CRL_ReasonCode); - - return 0; - } - -/* -* Extensions Copy Constructor -*/ -Extensions::Extensions(const Extensions& extensions) : ASN1_Object() - { - *this = extensions; - } - -/* -* Extensions Assignment Operator -*/ -Extensions& Extensions::operator=(const Extensions& other) - { - for(size_t i = 0; i != extensions.size(); ++i) - delete extensions[i].first; - extensions.clear(); - - for(size_t i = 0; i != other.extensions.size(); ++i) - extensions.push_back( - std::make_pair(other.extensions[i].first->copy(), - other.extensions[i].second)); - - should_throw = other.should_throw; - - return (*this); - } - -/* -* Return the OID of this extension -*/ -OID Certificate_Extension::oid_of() const - { - return OIDS::lookup(oid_name()); - } - -void Extensions::add(Certificate_Extension* extn, bool critical) - { - extensions.push_back(std::make_pair(extn, critical)); - } - -/* -* Encode an Extensions list -*/ -void Extensions::encode_into(DER_Encoder& to_object) const - { - for(size_t i = 0; i != extensions.size(); ++i) - { - const Certificate_Extension* ext = extensions[i].first; - const bool is_critical = extensions[i].second; - - const bool should_encode = ext->should_encode(); - - if(should_encode) - { - to_object.start_cons(SEQUENCE) - .encode(ext->oid_of()) - .encode_optional(is_critical, false) - .encode(ext->encode_inner(), OCTET_STRING) - .end_cons(); - } - } - } - -/* -* Decode a list of Extensions -*/ -void Extensions::decode_from(BER_Decoder& from_source) - { - for(size_t i = 0; i != extensions.size(); ++i) - delete extensions[i].first; - extensions.clear(); - - BER_Decoder sequence = from_source.start_cons(SEQUENCE); - - while(sequence.more_items()) - { - OID oid; - MemoryVector value; - bool critical; - - sequence.start_cons(SEQUENCE) - .decode(oid) - .decode_optional(critical, BOOLEAN, UNIVERSAL, false) - .decode(value, OCTET_STRING) - .verify_end() - .end_cons(); - - Certificate_Extension* ext = get_extension(oid); - - if(!ext) - { - if(!critical || !should_throw) - continue; - - throw Decoding_Error("Encountered unknown X.509 extension marked " - "as critical; OID = " + oid.as_string()); - } - - ext->decode_inner(value); - - extensions.push_back(std::make_pair(ext, critical)); - } - sequence.verify_end(); - } - -/* -* Write the extensions to an info store -*/ -void Extensions::contents_to(Data_Store& subject_info, - Data_Store& issuer_info) const - { - for(size_t i = 0; i != extensions.size(); ++i) - extensions[i].first->contents_to(subject_info, issuer_info); - } - -/* -* Delete an Extensions list -*/ -Extensions::~Extensions() - { - for(size_t i = 0; i != extensions.size(); ++i) - delete extensions[i].first; - } - -namespace Cert_Extension { - -/* -* Checked accessor for the path_limit member -*/ -size_t Basic_Constraints::get_path_limit() const - { - if(!is_ca) - throw Invalid_State("Basic_Constraints::get_path_limit: Not a CA"); - return path_limit; - } - -/* -* Encode the extension -*/ -MemoryVector Basic_Constraints::encode_inner() const - { - return DER_Encoder() - .start_cons(SEQUENCE) - .encode_if(is_ca, - DER_Encoder() - .encode(is_ca) - .encode_optional(path_limit, NO_CERT_PATH_LIMIT) - ) - .end_cons() - .get_contents(); - } - -/* -* Decode the extension -*/ -void Basic_Constraints::decode_inner(const MemoryRegion& in) - { - BER_Decoder(in) - .start_cons(SEQUENCE) - .decode_optional(is_ca, BOOLEAN, UNIVERSAL, false) - .decode_optional(path_limit, INTEGER, UNIVERSAL, NO_CERT_PATH_LIMIT) - .verify_end() - .end_cons(); - - if(is_ca == false) - path_limit = 0; - } - -/* -* Return a textual representation -*/ -void Basic_Constraints::contents_to(Data_Store& subject, Data_Store&) const - { - subject.add("X509v3.BasicConstraints.is_ca", (is_ca ? 1 : 0)); - subject.add("X509v3.BasicConstraints.path_constraint", path_limit); - } - -/* -* Encode the extension -*/ -MemoryVector Key_Usage::encode_inner() const - { - if(constraints == NO_CONSTRAINTS) - throw Encoding_Error("Cannot encode zero usage constraints"); - - const size_t unused_bits = low_bit(constraints) - 1; - - MemoryVector der; - der.push_back(BIT_STRING); - der.push_back(2 + ((unused_bits < 8) ? 1 : 0)); - der.push_back(unused_bits % 8); - der.push_back((constraints >> 8) & 0xFF); - if(constraints & 0xFF) - der.push_back(constraints & 0xFF); - - return der; - } - -/* -* Decode the extension -*/ -void Key_Usage::decode_inner(const MemoryRegion& in) - { - BER_Decoder ber(in); - - BER_Object obj = ber.get_next_object(); - - if(obj.type_tag != BIT_STRING || obj.class_tag != UNIVERSAL) - throw BER_Bad_Tag("Bad tag for usage constraint", - obj.type_tag, obj.class_tag); - - if(obj.value.size() != 2 && obj.value.size() != 3) - throw BER_Decoding_Error("Bad size for BITSTRING in usage constraint"); - - if(obj.value[0] >= 8) - throw BER_Decoding_Error("Invalid unused bits in usage constraint"); - - obj.value[obj.value.size()-1] &= (0xFF << obj.value[0]); - - u16bit usage = 0; - for(size_t i = 1; i != obj.value.size(); ++i) - usage = (obj.value[i] << 8) | usage; - - constraints = Key_Constraints(usage); - } - -/* -* Return a textual representation -*/ -void Key_Usage::contents_to(Data_Store& subject, Data_Store&) const - { - subject.add("X509v3.KeyUsage", constraints); - } - -/* -* Encode the extension -*/ -MemoryVector Subject_Key_ID::encode_inner() const - { - return DER_Encoder().encode(key_id, OCTET_STRING).get_contents(); - } - -/* -* Decode the extension -*/ -void Subject_Key_ID::decode_inner(const MemoryRegion& in) - { - BER_Decoder(in).decode(key_id, OCTET_STRING).verify_end(); - } - -/* -* Return a textual representation -*/ -void Subject_Key_ID::contents_to(Data_Store& subject, Data_Store&) const - { - subject.add("X509v3.SubjectKeyIdentifier", key_id); - } - -/* -* Subject_Key_ID Constructor -*/ -Subject_Key_ID::Subject_Key_ID(const MemoryRegion& pub_key) - { - SHA_160 hash; - key_id = hash.process(pub_key); - } - -/* -* Encode the extension -*/ -MemoryVector Authority_Key_ID::encode_inner() const - { - return DER_Encoder() - .start_cons(SEQUENCE) - .encode(key_id, OCTET_STRING, ASN1_Tag(0), CONTEXT_SPECIFIC) - .end_cons() - .get_contents(); - } - -/* -* Decode the extension -*/ -void Authority_Key_ID::decode_inner(const MemoryRegion& in) - { - BER_Decoder(in) - .start_cons(SEQUENCE) - .decode_optional_string(key_id, OCTET_STRING, 0); - } - -/* -* Return a textual representation -*/ -void Authority_Key_ID::contents_to(Data_Store&, Data_Store& issuer) const - { - if(key_id.size()) - issuer.add("X509v3.AuthorityKeyIdentifier", key_id); - } - -/* -* Encode the extension -*/ -MemoryVector Alternative_Name::encode_inner() const - { - return DER_Encoder().encode(alt_name).get_contents(); - } - -/* -* Decode the extension -*/ -void Alternative_Name::decode_inner(const MemoryRegion& in) - { - BER_Decoder(in).decode(alt_name); - } - -/* -* Return a textual representation -*/ -void Alternative_Name::contents_to(Data_Store& subject_info, - Data_Store& issuer_info) const - { - std::multimap contents = - get_alt_name().contents(); - - if(oid_name_str == "X509v3.SubjectAlternativeName") - subject_info.add(contents); - else if(oid_name_str == "X509v3.IssuerAlternativeName") - issuer_info.add(contents); - else - throw Internal_Error("In Alternative_Name, unknown type " + - oid_name_str); - } - -/* -* Alternative_Name Constructor -*/ -Alternative_Name::Alternative_Name(const AlternativeName& alt_name, - const std::string& oid_name_str, - const std::string& config_name_str) - { - this->alt_name = alt_name; - this->oid_name_str = oid_name_str; - this->config_name_str = config_name_str; - } - -/* -* Subject_Alternative_Name Constructor -*/ -Subject_Alternative_Name::Subject_Alternative_Name( - const AlternativeName& name) : - - Alternative_Name(name, "X509v3.SubjectAlternativeName", - "subject_alternative_name") - { - } - -/* -* Issuer_Alternative_Name Constructor -*/ -Issuer_Alternative_Name::Issuer_Alternative_Name(const AlternativeName& name) : - Alternative_Name(name, "X509v3.IssuerAlternativeName", - "issuer_alternative_name") - { - } - -/* -* Encode the extension -*/ -MemoryVector Extended_Key_Usage::encode_inner() const - { - return DER_Encoder() - .start_cons(SEQUENCE) - .encode_list(oids) - .end_cons() - .get_contents(); - } - -/* -* Decode the extension -*/ -void Extended_Key_Usage::decode_inner(const MemoryRegion& in) - { - BER_Decoder(in) - .start_cons(SEQUENCE) - .decode_list(oids) - .end_cons(); - } - -/* -* Return a textual representation -*/ -void Extended_Key_Usage::contents_to(Data_Store& subject, Data_Store&) const - { - for(size_t i = 0; i != oids.size(); ++i) - subject.add("X509v3.ExtendedKeyUsage", oids[i].as_string()); - } - -/* -* A policy specifier -*/ -class Policy_Information : public ASN1_Object - { - public: - OID oid; - - Policy_Information() {} - Policy_Information(const OID& oid) : oid(oid) {} - - void encode_into(DER_Encoder& codec) const - { - codec.start_cons(SEQUENCE) - .encode(oid) - .end_cons(); - } - - void decode_from(BER_Decoder& codec) - { - codec.start_cons(SEQUENCE) - .decode(oid) - .discard_remaining() - .end_cons(); - } - }; - -/* -* Encode the extension -*/ -MemoryVector Certificate_Policies::encode_inner() const - { - std::vector policies; - - for(size_t i = 0; i != oids.size(); ++i) - policies.push_back(oids[i]); - - return DER_Encoder() - .start_cons(SEQUENCE) - .encode_list(policies) - .end_cons() - .get_contents(); - } - -/* -* Decode the extension -*/ -void Certificate_Policies::decode_inner(const MemoryRegion& in) - { - std::vector policies; - - BER_Decoder(in) - .start_cons(SEQUENCE) - .decode_list(policies) - .end_cons(); - - oids.clear(); - for(size_t i = 0; i != policies.size(); ++i) - oids.push_back(policies[i].oid); - } - -/* -* Return a textual representation -*/ -void Certificate_Policies::contents_to(Data_Store& info, Data_Store&) const - { - for(size_t i = 0; i != oids.size(); ++i) - info.add("X509v3.ExtendedKeyUsage", oids[i].as_string()); - } - -/* -* Checked accessor for the crl_number member -*/ -size_t CRL_Number::get_crl_number() const - { - if(!has_value) - throw Invalid_State("CRL_Number::get_crl_number: Not set"); - return crl_number; - } - -/* -* Copy a CRL_Number extension -*/ -CRL_Number* CRL_Number::copy() const - { - if(!has_value) - throw Invalid_State("CRL_Number::copy: Not set"); - return new CRL_Number(crl_number); - } - -/* -* Encode the extension -*/ -MemoryVector CRL_Number::encode_inner() const - { - return DER_Encoder().encode(crl_number).get_contents(); - } - -/* -* Decode the extension -*/ -void CRL_Number::decode_inner(const MemoryRegion& in) - { - BER_Decoder(in).decode(crl_number); - } - -/* -* Return a textual representation -*/ -void CRL_Number::contents_to(Data_Store& info, Data_Store&) const - { - info.add("X509v3.CRLNumber", crl_number); - } - -/* -* Encode the extension -*/ -MemoryVector CRL_ReasonCode::encode_inner() const - { - return DER_Encoder() - .encode(static_cast(reason), ENUMERATED, UNIVERSAL) - .get_contents(); - } - -/* -* Decode the extension -*/ -void CRL_ReasonCode::decode_inner(const MemoryRegion& in) - { - size_t reason_code = 0; - BER_Decoder(in).decode(reason_code, ENUMERATED, UNIVERSAL); - reason = static_cast(reason_code); - } - -/* -* Return a textual representation -*/ -void CRL_ReasonCode::contents_to(Data_Store& info, Data_Store&) const - { - info.add("X509v3.CRLReasonCode", reason); - } - -} - -} -/* -* X.509 SIGNED Object -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include -#include - -namespace Botan { - -/* -* Create a generic X.509 object -*/ -X509_Object::X509_Object(DataSource& stream, const std::string& labels) - { - init(stream, labels); - } - -/* -* Createa a generic X.509 object -*/ -X509_Object::X509_Object(const std::string& file, const std::string& labels) - { - DataSource_Stream stream(file, true); - init(stream, labels); - } - -/* -* Read a PEM or BER X.509 object -*/ -void X509_Object::init(DataSource& in, const std::string& labels) - { - PEM_labels_allowed = split_on(labels, '/'); - if(PEM_labels_allowed.size() < 1) - throw Invalid_Argument("Bad labels argument to X509_Object"); - - PEM_label_pref = PEM_labels_allowed[0]; - std::sort(PEM_labels_allowed.begin(), PEM_labels_allowed.end()); - - try { - if(ASN1::maybe_BER(in) && !PEM_Code::matches(in)) - decode_info(in); - else - { - std::string got_label; - DataSource_Memory ber(PEM_Code::decode(in, got_label)); - - if(!std::binary_search(PEM_labels_allowed.begin(), - PEM_labels_allowed.end(), got_label)) - throw Decoding_Error("Invalid PEM label: " + got_label); - decode_info(ber); - } - } - catch(Decoding_Error& e) - { - throw Decoding_Error(PEM_label_pref + " decoding failed: " + e.what()); - } - } - -/* -* Read a BER encoded X.509 object -*/ -void X509_Object::decode_info(DataSource& source) - { - BER_Decoder(source) - .start_cons(SEQUENCE) - .start_cons(SEQUENCE) - .raw_bytes(tbs_bits) - .end_cons() - .decode(sig_algo) - .decode(sig, BIT_STRING) - .verify_end() - .end_cons(); - } - -/* -* Return a BER or PEM encoded X.509 object -*/ -void X509_Object::encode(Pipe& out, X509_Encoding encoding) const - { - if(encoding == PEM) - out.write(this->PEM_encode()); - else - out.write(this->BER_encode()); - } - -/* -* Return a BER encoded X.509 object -*/ -MemoryVector X509_Object::BER_encode() const - { - return DER_Encoder() - .start_cons(SEQUENCE) - .start_cons(SEQUENCE) - .raw_bytes(tbs_bits) - .end_cons() - .encode(sig_algo) - .encode(sig, BIT_STRING) - .end_cons() - .get_contents(); - } - -/* -* Return a PEM encoded X.509 object -*/ -std::string X509_Object::PEM_encode() const - { - return PEM_Code::encode(BER_encode(), PEM_label_pref); - } - -/* -* Return the TBS data -*/ -MemoryVector X509_Object::tbs_data() const - { - return ASN1::put_in_sequence(tbs_bits); - } - -/* -* Return the signature of this object -*/ -MemoryVector X509_Object::signature() const - { - return sig; - } - -/* -* Return the algorithm used to sign this object -*/ -AlgorithmIdentifier X509_Object::signature_algorithm() const - { - return sig_algo; - } - -/* -* Return the hash used in generating the signature -*/ -std::string X509_Object::hash_used_for_signature() const - { - std::vector sig_info = - split_on(OIDS::lookup(sig_algo.oid), '/'); - - if(sig_info.size() != 2) - throw Internal_Error("Invalid name format found for " + - sig_algo.oid.as_string()); - - std::vector pad_and_hash = - parse_algorithm_name(sig_info[1]); - - if(pad_and_hash.size() != 2) - throw Internal_Error("Invalid name format " + sig_info[1]); - - return pad_and_hash[1]; - } - -/* -* Check the signature on an object -*/ -bool X509_Object::check_signature(Public_Key* pub_key) const - { - std::unique_ptr key(pub_key); - return check_signature(*key); - } - -/* -* Check the signature on an object -*/ -bool X509_Object::check_signature(Public_Key& pub_key) const - { - try { - std::vector sig_info = - split_on(OIDS::lookup(sig_algo.oid), '/'); - - if(sig_info.size() != 2 || sig_info[0] != pub_key.algo_name()) - return false; - - std::string padding = sig_info[1]; - Signature_Format format = - (pub_key.message_parts() >= 2) ? DER_SEQUENCE : IEEE_1363; - - PK_Verifier verifier(pub_key, padding, format); - - return verifier.verify_message(tbs_data(), signature()); - } - catch(...) - { - return false; - } - } - -/* -* Apply the X.509 SIGNED macro -*/ -MemoryVector X509_Object::make_signed(PK_Signer* signer, - RandomNumberGenerator& rng, - const AlgorithmIdentifier& algo, - const MemoryRegion& tbs_bits) - { - return DER_Encoder() - .start_cons(SEQUENCE) - .raw_bytes(tbs_bits) - .encode(algo) - .encode(signer->sign_message(tbs_bits, rng), BIT_STRING) - .end_cons() - .get_contents(); - } - -/* -* Try to decode the actual information -*/ -void X509_Object::do_decode() - { - try { - force_decode(); - } - catch(Decoding_Error& e) - { - throw Decoding_Error(PEM_label_pref + " decoding failed (" + - e.what() + ")"); - } - catch(Invalid_Argument& e) - { - throw Decoding_Error(PEM_label_pref + " decoding failed (" + - e.what() + ")"); - } - } - -} -/* -* X.509 Certificates -* (C) 1999-2010 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include -#include -#include - -namespace Botan { - -namespace { - -/* -* Lookup each OID in the vector -*/ -std::vector lookup_oids(const std::vector& in) - { - std::vector out; - - std::vector::const_iterator i = in.begin(); - while(i != in.end()) - { - out.push_back(OIDS::lookup(OID(*i))); - ++i; - } - return out; - } - -} - -/* -* X509_Certificate Constructor -*/ -X509_Certificate::X509_Certificate(DataSource& in) : - X509_Object(in, "CERTIFICATE/X509 CERTIFICATE") - { - self_signed = false; - do_decode(); - } - -/* -* X509_Certificate Constructor -*/ -X509_Certificate::X509_Certificate(const std::string& in) : - X509_Object(in, "CERTIFICATE/X509 CERTIFICATE") - { - self_signed = false; - do_decode(); - } - -/* -* Decode the TBSCertificate data -*/ -void X509_Certificate::force_decode() - { - size_t version; - BigInt serial_bn; - AlgorithmIdentifier sig_algo_inner; - X509_DN dn_issuer, dn_subject; - X509_Time start, end; - - BER_Decoder tbs_cert(tbs_bits); - - tbs_cert.decode_optional(version, ASN1_Tag(0), - ASN1_Tag(CONSTRUCTED | CONTEXT_SPECIFIC)) - .decode(serial_bn) - .decode(sig_algo_inner) - .decode(dn_issuer) - .start_cons(SEQUENCE) - .decode(start) - .decode(end) - .verify_end() - .end_cons() - .decode(dn_subject); - - if(version > 2) - throw Decoding_Error("Unknown X.509 cert version " + Botan::to_string(version)); - if(sig_algo != sig_algo_inner) - throw Decoding_Error("Algorithm identifier mismatch"); - - self_signed = (dn_subject == dn_issuer); - - subject.add(dn_subject.contents()); - issuer.add(dn_issuer.contents()); - - BER_Object public_key = tbs_cert.get_next_object(); - if(public_key.type_tag != SEQUENCE || public_key.class_tag != CONSTRUCTED) - throw BER_Bad_Tag("X509_Certificate: Unexpected tag for public key", - public_key.type_tag, public_key.class_tag); - - MemoryVector v2_issuer_key_id, v2_subject_key_id; - - tbs_cert.decode_optional_string(v2_issuer_key_id, BIT_STRING, 1); - tbs_cert.decode_optional_string(v2_subject_key_id, BIT_STRING, 2); - - BER_Object v3_exts_data = tbs_cert.get_next_object(); - if(v3_exts_data.type_tag == 3 && - v3_exts_data.class_tag == ASN1_Tag(CONSTRUCTED | CONTEXT_SPECIFIC)) - { - Extensions extensions; - - BER_Decoder(v3_exts_data.value).decode(extensions).verify_end(); - - extensions.contents_to(subject, issuer); - } - else if(v3_exts_data.type_tag != NO_OBJECT) - throw BER_Bad_Tag("Unknown tag in X.509 cert", - v3_exts_data.type_tag, v3_exts_data.class_tag); - - if(tbs_cert.more_items()) - throw Decoding_Error("TBSCertificate has more items that expected"); - - subject.add("X509.Certificate.version", version); - subject.add("X509.Certificate.serial", BigInt::encode(serial_bn)); - subject.add("X509.Certificate.start", start.readable_string()); - subject.add("X509.Certificate.end", end.readable_string()); - - issuer.add("X509.Certificate.v2.key_id", v2_issuer_key_id); - subject.add("X509.Certificate.v2.key_id", v2_subject_key_id); - - subject.add("X509.Certificate.public_key", - PEM_Code::encode( - ASN1::put_in_sequence(public_key.value), - "PUBLIC KEY" - ) - ); - - if(is_CA_cert() && - !subject.has_value("X509v3.BasicConstraints.path_constraint")) - { - const size_t limit = (x509_version() < 3) ? - Cert_Extension::NO_CERT_PATH_LIMIT : 0; - - subject.add("X509v3.BasicConstraints.path_constraint", limit); - } - } - -/* -* Return the X.509 version in use -*/ -u32bit X509_Certificate::x509_version() const - { - return (subject.get1_u32bit("X509.Certificate.version") + 1); - } - -/* -* Return the time this cert becomes valid -*/ -std::string X509_Certificate::start_time() const - { - return subject.get1("X509.Certificate.start"); - } - -/* -* Return the time this cert becomes invalid -*/ -std::string X509_Certificate::end_time() const - { - return subject.get1("X509.Certificate.end"); - } - -/* -* Return information about the subject -*/ -std::vector -X509_Certificate::subject_info(const std::string& what) const - { - return subject.get(X509_DN::deref_info_field(what)); - } - -/* -* Return information about the issuer -*/ -std::vector -X509_Certificate::issuer_info(const std::string& what) const - { - return issuer.get(X509_DN::deref_info_field(what)); - } - -/* -* Return the public key in this certificate -*/ -Public_Key* X509_Certificate::subject_public_key() const - { - DataSource_Memory source(subject.get1("X509.Certificate.public_key")); - return X509::load_key(source); - } - -/* -* Check if the certificate is for a CA -*/ -bool X509_Certificate::is_CA_cert() const - { - if(!subject.get1_u32bit("X509v3.BasicConstraints.is_ca")) - return false; - if((constraints() & KEY_CERT_SIGN) || (constraints() == NO_CONSTRAINTS)) - return true; - return false; - } - -/* -* Return the path length constraint -*/ -u32bit X509_Certificate::path_limit() const - { - return subject.get1_u32bit("X509v3.BasicConstraints.path_constraint", 0); - } - -/* -* Return the key usage constraints -*/ -Key_Constraints X509_Certificate::constraints() const - { - return Key_Constraints(subject.get1_u32bit("X509v3.KeyUsage", - NO_CONSTRAINTS)); - } - -/* -* Return the list of extended key usage OIDs -*/ -std::vector X509_Certificate::ex_constraints() const - { - return lookup_oids(subject.get("X509v3.ExtendedKeyUsage")); - } - -/* -* Return the list of certificate policies -*/ -std::vector X509_Certificate::policies() const - { - return lookup_oids(subject.get("X509v3.CertificatePolicies")); - } - -/* -* Return the authority key id -*/ -MemoryVector X509_Certificate::authority_key_id() const - { - return issuer.get1_memvec("X509v3.AuthorityKeyIdentifier"); - } - -/* -* Return the subject key id -*/ -MemoryVector X509_Certificate::subject_key_id() const - { - return subject.get1_memvec("X509v3.SubjectKeyIdentifier"); - } - -/* -* Return the certificate serial number -*/ -MemoryVector X509_Certificate::serial_number() const - { - return subject.get1_memvec("X509.Certificate.serial"); - } - -/* -* Return the distinguished name of the issuer -*/ -X509_DN X509_Certificate::issuer_dn() const - { - return create_dn(issuer); - } - -/* -* Return the distinguished name of the subject -*/ -X509_DN X509_Certificate::subject_dn() const - { - return create_dn(subject); - } - -/* -* Compare two certificates for equality -*/ -bool X509_Certificate::operator==(const X509_Certificate& other) const - { - return (sig == other.sig && - sig_algo == other.sig_algo && - self_signed == other.self_signed && - issuer == other.issuer && - subject == other.subject); - } - -/* -* X.509 Certificate Comparison -*/ -bool operator!=(const X509_Certificate& cert1, const X509_Certificate& cert2) - { - return !(cert1 == cert2); - } - -std::string X509_Certificate::to_string() const - { - const char* dn_fields[] = { "Name", - "Email", - "Organization", - "Organizational Unit", - "Locality", - "State", - "Country", - "IP", - "DNS", - "URI", - "PKIX.XMPPAddr", - 0 }; - - std::ostringstream out; - - for(size_t i = 0; dn_fields[i]; ++i) - { - const std::vector vals = this->subject_info(dn_fields[i]); - - if(vals.empty()) - continue; - - out << "Subject " << dn_fields[i] << ":"; - for(size_t j = 0; j != vals.size(); ++j) - out << " " << vals[j]; - out << "\n"; - } - - for(size_t i = 0; dn_fields[i]; ++i) - { - const std::vector vals = this->issuer_info(dn_fields[i]); - - if(vals.empty()) - continue; - - out << "Issuer " << dn_fields[i] << ":"; - for(size_t j = 0; j != vals.size(); ++j) - out << " " << vals[j]; - out << "\n"; - } - - out << "Version: " << this->x509_version() << "\n"; - - out << "Not valid before: " << this->start_time() << "\n"; - out << "Not valid after: " << this->end_time() << "\n"; - - out << "Constraints:\n"; - Key_Constraints constraints = this->constraints(); - if(constraints == NO_CONSTRAINTS) - out << " None\n"; - else - { - if(constraints & DIGITAL_SIGNATURE) - out << " Digital Signature\n"; - if(constraints & NON_REPUDIATION) - out << " Non-Repuidation\n"; - if(constraints & KEY_ENCIPHERMENT) - out << " Key Encipherment\n"; - if(constraints & DATA_ENCIPHERMENT) - out << " Data Encipherment\n"; - if(constraints & KEY_AGREEMENT) - out << " Key Agreement\n"; - if(constraints & KEY_CERT_SIGN) - out << " Cert Sign\n"; - if(constraints & CRL_SIGN) - out << " CRL Sign\n"; - } - - std::vector policies = this->policies(); - if(policies.size()) - { - out << "Policies: " << "\n"; - for(size_t i = 0; i != policies.size(); i++) - out << " " << policies[i] << "\n"; - } - - std::vector ex_constraints = this->ex_constraints(); - if(ex_constraints.size()) - { - out << "Extended Constraints:\n"; - for(size_t i = 0; i != ex_constraints.size(); i++) - out << " " << ex_constraints[i] << "\n"; - } - - out << "Signature algorithm: " << - OIDS::lookup(this->signature_algorithm().oid) << "\n"; - - out << "Serial number: " << hex_encode(this->serial_number()) << "\n"; - - if(this->authority_key_id().size()) - out << "Authority keyid: " << hex_encode(this->authority_key_id()) << "\n"; - - if(this->subject_key_id().size()) - out << "Subject keyid: " << hex_encode(this->subject_key_id()) << "\n"; - - X509_PublicKey* pubkey = this->subject_public_key(); - out << "Public Key:\n" << X509::PEM_encode(*pubkey); - delete pubkey; - - return out.str(); - } - -/* -* Create and populate a X509_DN -*/ -X509_DN create_dn(const Data_Store& info) - { - class DN_Matcher : public Data_Store::Matcher - { - public: - bool operator()(const std::string& key, const std::string&) const - { - if(key.find("X520.") != std::string::npos) - return true; - return false; - } - }; - - std::multimap names = - info.search_with(DN_Matcher()); - - X509_DN dn; - - std::multimap::iterator i; - for(i = names.begin(); i != names.end(); ++i) - dn.add_attribute(i->first, i->second); - - return dn; - } - -/* -* Create and populate an AlternativeName -*/ -AlternativeName create_alt_name(const Data_Store& info) - { - class AltName_Matcher : public Data_Store::Matcher - { - public: - bool operator()(const std::string& key, const std::string&) const - { - for(size_t i = 0; i != matches.size(); ++i) - if(key.compare(matches[i]) == 0) - return true; - return false; - } - - AltName_Matcher(const std::string& match_any_of) - { - matches = split_on(match_any_of, '/'); - } - private: - std::vector matches; - }; - - std::multimap names = - info.search_with(AltName_Matcher("RFC822/DNS/URI/IP")); - - AlternativeName alt_name; - - std::multimap::iterator i; - for(i = names.begin(); i != names.end(); ++i) - alt_name.add_attribute(i->first, i->second); - - return alt_name; - } - -} -/* -* CRL Entry -* (C) 1999-2010 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -/* -* Create a CRL_Entry -*/ -CRL_Entry::CRL_Entry(bool t_on_unknown_crit) : - throw_on_unknown_critical(t_on_unknown_crit) - { - reason = UNSPECIFIED; - } - -/* -* Create a CRL_Entry -*/ -CRL_Entry::CRL_Entry(const X509_Certificate& cert, CRL_Code why) : - throw_on_unknown_critical(false) - { - serial = cert.serial_number(); - time = X509_Time(system_time()); - reason = why; - } - -/* -* Compare two CRL_Entrys for equality -*/ -bool operator==(const CRL_Entry& a1, const CRL_Entry& a2) - { - if(a1.serial_number() != a2.serial_number()) - return false; - if(a1.expire_time() != a2.expire_time()) - return false; - if(a1.reason_code() != a2.reason_code()) - return false; - return true; - } - -/* -* Compare two CRL_Entrys for inequality -*/ -bool operator!=(const CRL_Entry& a1, const CRL_Entry& a2) - { - return !(a1 == a2); - } - -/* -* DER encode a CRL_Entry -*/ -void CRL_Entry::encode_into(DER_Encoder& der) const - { - Extensions extensions; - - extensions.add(new Cert_Extension::CRL_ReasonCode(reason)); - - der.start_cons(SEQUENCE) - .encode(BigInt::decode(serial)) - .encode(time) - .start_cons(SEQUENCE) - .encode(extensions) - .end_cons() - .end_cons(); - } - -/* -* Decode a BER encoded CRL_Entry -*/ -void CRL_Entry::decode_from(BER_Decoder& source) - { - BigInt serial_number_bn; - reason = UNSPECIFIED; - - BER_Decoder entry = source.start_cons(SEQUENCE); - - entry.decode(serial_number_bn).decode(time); - - if(entry.more_items()) - { - Extensions extensions(throw_on_unknown_critical); - entry.decode(extensions); - Data_Store info; - extensions.contents_to(info, info); - reason = CRL_Code(info.get1_u32bit("X509v3.CRLReasonCode")); - } - - entry.end_cons(); - - serial = BigInt::encode(serial_number_bn); - } - -} -/* -* X.509 CRL -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -/* -* Load a X.509 CRL -*/ -X509_CRL::X509_CRL(DataSource& in, bool touc) : - X509_Object(in, "X509 CRL/CRL"), throw_on_unknown_critical(touc) - { - do_decode(); - } - -/* -* Load a X.509 CRL -*/ -X509_CRL::X509_CRL(const std::string& in, bool touc) : - X509_Object(in, "CRL/X509 CRL"), throw_on_unknown_critical(touc) - { - do_decode(); - } - -/* -* Decode the TBSCertList data -*/ -void X509_CRL::force_decode() - { - BER_Decoder tbs_crl(tbs_bits); - - size_t version; - tbs_crl.decode_optional(version, INTEGER, UNIVERSAL); - - if(version != 0 && version != 1) - throw X509_CRL_Error("Unknown X.509 CRL version " + - to_string(version+1)); - - AlgorithmIdentifier sig_algo_inner; - tbs_crl.decode(sig_algo_inner); - - if(sig_algo != sig_algo_inner) - throw X509_CRL_Error("Algorithm identifier mismatch"); - - X509_DN dn_issuer; - tbs_crl.decode(dn_issuer); - info.add(dn_issuer.contents()); - - X509_Time start, end; - tbs_crl.decode(start).decode(end); - info.add("X509.CRL.start", start.readable_string()); - info.add("X509.CRL.end", end.readable_string()); - - BER_Object next = tbs_crl.get_next_object(); - - if(next.type_tag == SEQUENCE && next.class_tag == CONSTRUCTED) - { - BER_Decoder cert_list(next.value); - - while(cert_list.more_items()) - { - CRL_Entry entry(throw_on_unknown_critical); - cert_list.decode(entry); - revoked.push_back(entry); - } - next = tbs_crl.get_next_object(); - } - - if(next.type_tag == 0 && - next.class_tag == ASN1_Tag(CONSTRUCTED | CONTEXT_SPECIFIC)) - { - BER_Decoder crl_options(next.value); - - Extensions extensions(throw_on_unknown_critical); - - crl_options.decode(extensions).verify_end(); - - extensions.contents_to(info, info); - - next = tbs_crl.get_next_object(); - } - - if(next.type_tag != NO_OBJECT) - throw X509_CRL_Error("Unknown tag in CRL"); - - tbs_crl.verify_end(); - } - -/* -* Return the list of revoked certificates -*/ -std::vector X509_CRL::get_revoked() const - { - return revoked; - } - -/* -* Return the distinguished name of the issuer -*/ -X509_DN X509_CRL::issuer_dn() const - { - return create_dn(info); - } - -/* -* Return the key identifier of the issuer -*/ -MemoryVector X509_CRL::authority_key_id() const - { - return info.get1_memvec("X509v3.AuthorityKeyIdentifier"); - } - -/* -* Return the CRL number of this CRL -*/ -u32bit X509_CRL::crl_number() const - { - return info.get1_u32bit("X509v3.CRLNumber"); - } - -/* -* Return the issue data of the CRL -*/ -X509_Time X509_CRL::this_update() const - { - return info.get1("X509.CRL.start"); - } - -/* -* Return the date when a new CRL will be issued -*/ -X509_Time X509_CRL::next_update() const - { - return info.get1("X509.CRL.end"); - } - -} -/* -* X.509 Certificate Options -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -/* -* Set when the certificate should become valid -*/ -void X509_Cert_Options::not_before(const std::string& time_string) - { - start = X509_Time(time_string); - } - -/* -* Set when the certificate should expire -*/ -void X509_Cert_Options::not_after(const std::string& time_string) - { - end = X509_Time(time_string); - } - -/* -* Set key constraint information -*/ -void X509_Cert_Options::add_constraints(Key_Constraints usage) - { - constraints = usage; - } - -/* -* Set key constraint information -*/ -void X509_Cert_Options::add_ex_constraint(const OID& oid) - { - ex_constraints.push_back(oid); - } - -/* -* Set key constraint information -*/ -void X509_Cert_Options::add_ex_constraint(const std::string& oid_str) - { - ex_constraints.push_back(OIDS::lookup(oid_str)); - } - -/* -* Mark this certificate for CA usage -*/ -void X509_Cert_Options::CA_key(size_t limit) - { - is_CA = true; - path_limit = limit; - } - -/* -* Do basic sanity checks -*/ -void X509_Cert_Options::sanity_check() const - { - if(common_name == "" || country == "") - throw Encoding_Error("X.509 certificate: name and country MUST be set"); - if(country.size() != 2) - throw Encoding_Error("Invalid ISO country code: " + country); - if(start >= end) - throw Encoding_Error("X509_Cert_Options: invalid time constraints"); - } - -/* -* Initialize the certificate options -*/ -X509_Cert_Options::X509_Cert_Options(const std::string& initial_opts, - u32bit expiration_time_in_seconds) - { - is_CA = false; - path_limit = 0; - constraints = NO_CONSTRAINTS; - - const u64bit now = system_time(); - - start = X509_Time(now); - end = X509_Time(now + expiration_time_in_seconds); - - if(initial_opts == "") - return; - - std::vector parsed = split_on(initial_opts, '/'); - - if(parsed.size() > 4) - throw Invalid_Argument("X.509 cert options: Too many names: " - + initial_opts); - - if(parsed.size() >= 1) common_name = parsed[0]; - if(parsed.size() >= 2) country = parsed[1]; - if(parsed.size() >= 3) organization = parsed[2]; - if(parsed.size() == 4) org_unit = parsed[3]; - } - -} -/* -* PKCS #10/Self Signed Cert Creation -* (C) 1999-2008 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include - -namespace Botan { - -namespace { - -/* -* Load information from the X509_Cert_Options -*/ -void load_info(const X509_Cert_Options& opts, X509_DN& subject_dn, - AlternativeName& subject_alt) - { - subject_dn.add_attribute("X520.CommonName", opts.common_name); - subject_dn.add_attribute("X520.Country", opts.country); - subject_dn.add_attribute("X520.State", opts.state); - subject_dn.add_attribute("X520.Locality", opts.locality); - subject_dn.add_attribute("X520.Organization", opts.organization); - subject_dn.add_attribute("X520.OrganizationalUnit", opts.org_unit); - subject_dn.add_attribute("X520.SerialNumber", opts.serial_number); - subject_alt = AlternativeName(opts.email, opts.uri, opts.dns, opts.ip); - subject_alt.add_othername(OIDS::lookup("PKIX.XMPPAddr"), - opts.xmpp, UTF8_STRING); - } - -} - -namespace X509 { - -/* -* Create a new self-signed X.509 certificate -*/ -X509_Certificate create_self_signed_cert(const X509_Cert_Options& opts, - const Private_Key& key, - const std::string& hash_fn, - RandomNumberGenerator& rng) - { - AlgorithmIdentifier sig_algo; - X509_DN subject_dn; - AlternativeName subject_alt; - - opts.sanity_check(); - - MemoryVector pub_key = X509::BER_encode(key); - std::unique_ptr signer(choose_sig_format(key, hash_fn, sig_algo)); - load_info(opts, subject_dn, subject_alt); - - Key_Constraints constraints; - if(opts.is_CA) - constraints = Key_Constraints(KEY_CERT_SIGN | CRL_SIGN); - else - constraints = find_constraints(key, opts.constraints); - - Extensions extensions; - - extensions.add( - new Cert_Extension::Basic_Constraints(opts.is_CA, opts.path_limit), - true); - - extensions.add(new Cert_Extension::Key_Usage(constraints), true); - - extensions.add(new Cert_Extension::Subject_Key_ID(pub_key)); - - extensions.add( - new Cert_Extension::Subject_Alternative_Name(subject_alt)); - - extensions.add( - new Cert_Extension::Extended_Key_Usage(opts.ex_constraints)); - - return X509_CA::make_cert(signer.get(), rng, sig_algo, pub_key, - opts.start, opts.end, - subject_dn, subject_dn, - extensions); - } - -/* -* Create a PKCS #10 certificate request -*/ -PKCS10_Request create_cert_req(const X509_Cert_Options& opts, - const Private_Key& key, - const std::string& hash_fn, - RandomNumberGenerator& rng) - { - AlgorithmIdentifier sig_algo; - X509_DN subject_dn; - AlternativeName subject_alt; - - opts.sanity_check(); - - MemoryVector pub_key = X509::BER_encode(key); - std::unique_ptr signer(choose_sig_format(key, hash_fn, sig_algo)); - load_info(opts, subject_dn, subject_alt); - - const size_t PKCS10_VERSION = 0; - - Extensions extensions; - - extensions.add( - new Cert_Extension::Basic_Constraints(opts.is_CA, opts.path_limit)); - extensions.add( - new Cert_Extension::Key_Usage( - opts.is_CA ? Key_Constraints(KEY_CERT_SIGN | CRL_SIGN) : - find_constraints(key, opts.constraints) - ) - ); - extensions.add( - new Cert_Extension::Extended_Key_Usage(opts.ex_constraints)); - extensions.add( - new Cert_Extension::Subject_Alternative_Name(subject_alt)); - - DER_Encoder tbs_req; - - tbs_req.start_cons(SEQUENCE) - .encode(PKCS10_VERSION) - .encode(subject_dn) - .raw_bytes(pub_key) - .start_explicit(0); - - if(opts.challenge != "") - { - ASN1_String challenge(opts.challenge, DIRECTORY_STRING); - - tbs_req.encode( - Attribute("PKCS9.ChallengePassword", - DER_Encoder().encode(challenge).get_contents() - ) - ); - } - - tbs_req.encode( - Attribute("PKCS9.ExtensionRequest", - DER_Encoder() - .start_cons(SEQUENCE) - .encode(extensions) - .end_cons() - .get_contents() - ) - ) - .end_explicit() - .end_cons(); - - DataSource_Memory source( - X509_Object::make_signed(signer.get(), - rng, - sig_algo, - tbs_req.get_contents()) - ); - - return PKCS10_Request(source); - } - -} - -} -/* -* X.509 Certificate Store -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include -#include - -namespace Botan { - -namespace { - -/* -* Do a validity check -*/ -s32bit validity_check(const X509_Time& start, const X509_Time& end, - u64bit current_time, u32bit slack) - { - const s32bit NOT_YET_VALID = -1, VALID_TIME = 0, EXPIRED = 1; - - if(start.cmp(current_time + slack) > 0) - return NOT_YET_VALID; - if(end.cmp(current_time - slack) < 0) - return EXPIRED; - return VALID_TIME; - } - -/* -* Compare the value of unique ID fields -*/ -bool compare_ids(const MemoryVector& id1, - const MemoryVector& id2) - { - if(!id1.size() || !id2.size()) - return true; - return (id1 == id2); - } - -/* -* Check a particular usage restriction -*/ -bool check_usage(const X509_Certificate& cert, X509_Store::Cert_Usage usage, - X509_Store::Cert_Usage check_for, Key_Constraints constraints) - { - if((usage & check_for) == 0) - return true; - if(cert.constraints() == NO_CONSTRAINTS) - return true; - if(cert.constraints() & constraints) - return true; - return false; - } - -/* -* Check a particular usage restriction -*/ -bool check_usage(const X509_Certificate& cert, X509_Store::Cert_Usage usage, - X509_Store::Cert_Usage check_for, - const std::string& usage_oid) - { - if((usage & check_for) == 0) - return true; - - const std::vector constraints = cert.ex_constraints(); - - if(constraints.empty()) - return true; - - return std::binary_search(constraints.begin(), constraints.end(), - usage_oid); - } - -/* -* Check the usage restrictions -*/ -X509_Code usage_check(const X509_Certificate& cert, - X509_Store::Cert_Usage usage) - { - if(usage == X509_Store::ANY) - return VERIFIED; - - if(!check_usage(cert, usage, X509_Store::CRL_SIGNING, CRL_SIGN)) - return CA_CERT_NOT_FOR_CRL_ISSUER; - - if(!check_usage(cert, usage, X509_Store::TLS_SERVER, "PKIX.ServerAuth")) - return INVALID_USAGE; - if(!check_usage(cert, usage, X509_Store::TLS_CLIENT, "PKIX.ClientAuth")) - return INVALID_USAGE; - if(!check_usage(cert, usage, X509_Store::CODE_SIGNING, "PKIX.CodeSigning")) - return INVALID_USAGE; - if(!check_usage(cert, usage, X509_Store::EMAIL_PROTECTION, - "PKIX.EmailProtection")) - return INVALID_USAGE; - if(!check_usage(cert, usage, X509_Store::TIME_STAMPING, - "PKIX.TimeStamping")) - return INVALID_USAGE; - - return VERIFIED; - } - -} - -/* -* Define equality for revocation data -*/ -bool X509_Store::CRL_Data::operator==(const CRL_Data& other) const - { - if(issuer != other.issuer) - return false; - if(serial != other.serial) - return false; - return compare_ids(auth_key_id, other.auth_key_id); - } - -/* -* Define inequality for revocation data -*/ -bool X509_Store::CRL_Data::operator!=(const CRL_Data& other) const - { - return !((*this) == other); - } - -/* -* Define an ordering for revocation data -*/ -bool X509_Store::CRL_Data::operator<(const X509_Store::CRL_Data& other) const - { - if(*this == other) - return false; - - const MemoryVector& serial1 = serial; - const MemoryVector& key_id1 = auth_key_id; - const MemoryVector& serial2 = other.serial; - const MemoryVector& key_id2 = other.auth_key_id; - - if(compare_ids(key_id1, key_id2) == false) - { - if(std::lexicographical_compare(key_id1.begin(), key_id1.end(), - key_id2.begin(), key_id2.end())) - return true; - - if(std::lexicographical_compare(key_id2.begin(), key_id2.end(), - key_id1.begin(), key_id1.end())) - return false; - } - - if(compare_ids(serial1, serial2) == false) - { - if(std::lexicographical_compare(serial1.begin(), serial1.end(), - serial2.begin(), serial2.end())) - return true; - - if(std::lexicographical_compare(serial2.begin(), serial2.end(), - serial1.begin(), serial1.end())) - return false; - } - - return (issuer < other.issuer); - } - -/* -* X509_Store Constructor -*/ -X509_Store::X509_Store(u32bit slack, u32bit cache_timeout) - { - revoked_info_valid = true; - - validation_cache_timeout = cache_timeout; - time_slack = slack; - } - -/* -* X509_Store Copy Constructor -*/ -X509_Store::X509_Store(const X509_Store& other) - { - certs = other.certs; - revoked = other.revoked; - revoked_info_valid = other.revoked_info_valid; - for(size_t j = 0; j != other.stores.size(); ++j) - stores[j] = other.stores[j]->clone(); - time_slack = other.time_slack; - validation_cache_timeout = other.validation_cache_timeout; - } - -/* -* X509_Store Destructor -*/ -X509_Store::~X509_Store() - { - for(size_t j = 0; j != stores.size(); ++j) - delete stores[j]; - } - -/* -* Verify a certificate's authenticity -*/ -X509_Code X509_Store::validate_cert(const X509_Certificate& cert, - Cert_Usage cert_usage) - { - recompute_revoked_info(); - - std::vector indexes; - X509_Code chaining_result = construct_cert_chain(cert, indexes); - if(chaining_result != VERIFIED) - return chaining_result; - - const u64bit current_time = system_time(); - - s32bit time_check = validity_check(cert.start_time(), cert.end_time(), - current_time, time_slack); - if(time_check < 0) return CERT_NOT_YET_VALID; - else if(time_check > 0) return CERT_HAS_EXPIRED; - - X509_Code sig_check_result = check_sig(cert, certs[indexes[0]]); - if(sig_check_result != VERIFIED) - return sig_check_result; - - if(is_revoked(cert)) - return CERT_IS_REVOKED; - - for(size_t j = 0; j != indexes.size() - 1; ++j) - { - const X509_Certificate& current_cert = certs[indexes[j]].cert; - - time_check = validity_check(current_cert.start_time(), - current_cert.end_time(), - current_time, - time_slack); - - if(time_check < 0) return CERT_NOT_YET_VALID; - else if(time_check > 0) return CERT_HAS_EXPIRED; - - sig_check_result = check_sig(certs[indexes[j]], certs[indexes[j+1]]); - if(sig_check_result != VERIFIED) - return sig_check_result; - } - - return usage_check(cert, cert_usage); - } - -/* -* Find this certificate -*/ -size_t X509_Store::find_cert(const X509_DN& subject_dn, - const MemoryRegion& subject_key_id) const - { - for(size_t j = 0; j != certs.size(); ++j) - { - const X509_Certificate& this_cert = certs[j].cert; - if(compare_ids(this_cert.subject_key_id(), subject_key_id) && - this_cert.subject_dn() == subject_dn) - return j; - } - return NO_CERT_FOUND; - } - -/* -* Find the parent of this certificate -*/ -size_t X509_Store::find_parent_of(const X509_Certificate& cert) - { - const X509_DN issuer_dn = cert.issuer_dn(); - const MemoryVector auth_key_id = cert.authority_key_id(); - - size_t index = find_cert(issuer_dn, auth_key_id); - - if(index != NO_CERT_FOUND) - return index; - - for(size_t j = 0; j != stores.size(); ++j) - { - std::vector got = - stores[j]->find_cert_by_subject_and_key_id(issuer_dn, auth_key_id); - - for(size_t k = 0; k != got.size(); ++k) - add_cert(got[k]); - } - - return find_cert(issuer_dn, auth_key_id); - } - -/* -* Construct a chain of certificate relationships -*/ -X509_Code X509_Store::construct_cert_chain(const X509_Certificate& end_cert, - std::vector& indexes, - bool need_full_chain) - { - size_t parent = find_parent_of(end_cert); - - while(true) - { - if(parent == NO_CERT_FOUND) - return CERT_ISSUER_NOT_FOUND; - indexes.push_back(parent); - - if(certs[parent].is_verified(validation_cache_timeout)) - if(certs[parent].verify_result() != VERIFIED) - return certs[parent].verify_result(); - - const X509_Certificate& parent_cert = certs[parent].cert; - if(!parent_cert.is_CA_cert()) - return CA_CERT_NOT_FOR_CERT_ISSUER; - - if(certs[parent].is_trusted()) - break; - if(parent_cert.is_self_signed()) - return CANNOT_ESTABLISH_TRUST; - - if(parent_cert.path_limit() < indexes.size() - 1) - return CERT_CHAIN_TOO_LONG; - - parent = find_parent_of(parent_cert); - } - - if(need_full_chain) - return VERIFIED; - - while(true) - { - if(indexes.size() < 2) - break; - - const size_t cert = indexes.back(); - - if(certs[cert].is_verified(validation_cache_timeout)) - { - if(certs[cert].verify_result() != VERIFIED) - throw Internal_Error("X509_Store::construct_cert_chain"); - indexes.pop_back(); - } - else - break; - } - - const size_t last_cert = indexes.back(); - const size_t parent_of_last_cert = find_parent_of(certs[last_cert].cert); - if(parent_of_last_cert == NO_CERT_FOUND) - return CERT_ISSUER_NOT_FOUND; - indexes.push_back(parent_of_last_cert); - - return VERIFIED; - } - -/* -* Check the CAs signature on a certificate -*/ -X509_Code X509_Store::check_sig(const Cert_Info& cert_info, - const Cert_Info& ca_cert_info) const - { - if(cert_info.is_verified(validation_cache_timeout)) - return cert_info.verify_result(); - - const X509_Certificate& cert = cert_info.cert; - const X509_Certificate& ca_cert = ca_cert_info.cert; - - X509_Code verify_code = check_sig(cert, ca_cert.subject_public_key()); - - cert_info.set_result(verify_code); - - return verify_code; - } - -/* -* Check a CA's signature -*/ -X509_Code X509_Store::check_sig(const X509_Object& object, Public_Key* key) - { - std::unique_ptr pub_key(key); - - try { - std::vector sig_info = - split_on(OIDS::lookup(object.signature_algorithm().oid), '/'); - - if(sig_info.size() != 2 || sig_info[0] != pub_key->algo_name()) - return SIGNATURE_ERROR; - - std::string padding = sig_info[1]; - Signature_Format format; - if(key->message_parts() >= 2) format = DER_SEQUENCE; - else format = IEEE_1363; - - PK_Verifier verifier(*pub_key.get(), padding, format); - - bool valid = verifier.verify_message(object.tbs_data(), - object.signature()); - - if(valid) - return VERIFIED; - else - return SIGNATURE_ERROR; - } - catch(Lookup_Error) { return CA_CERT_CANNOT_SIGN; } - catch(Decoding_Error) { return CERT_FORMAT_ERROR; } - catch(Exception) {} - - return UNKNOWN_X509_ERROR; - } - -/* -* Recompute the revocation status of the certs -*/ -void X509_Store::recompute_revoked_info() const - { - if(revoked_info_valid) - return; - - for(size_t j = 0; j != certs.size(); ++j) - { - if((certs[j].is_verified(validation_cache_timeout)) && - (certs[j].verify_result() != VERIFIED)) - continue; - - if(is_revoked(certs[j].cert)) - certs[j].set_result(CERT_IS_REVOKED); - } - - revoked_info_valid = true; - } - -/* -* Check if a certificate is revoked -*/ -bool X509_Store::is_revoked(const X509_Certificate& cert) const - { - CRL_Data revoked_info; - revoked_info.issuer = cert.issuer_dn(); - revoked_info.serial = cert.serial_number(); - revoked_info.auth_key_id = cert.authority_key_id(); - - if(std::binary_search(revoked.begin(), revoked.end(), revoked_info)) - return true; - return false; - } - -/* -* Construct a path back to a root for this cert -*/ -std::vector -X509_Store::get_cert_chain(const X509_Certificate& cert) - { - std::vector result; - std::vector indexes; - X509_Code chaining_result = construct_cert_chain(cert, indexes, true); - - if(chaining_result != VERIFIED) - throw Invalid_State("X509_Store::get_cert_chain: Can't construct chain"); - - for(size_t j = 0; j != indexes.size(); ++j) - result.push_back(certs[indexes[j]].cert); - return result; - } - -/* -* Add a certificate store to the list of stores -*/ -void X509_Store::add_new_certstore(Certificate_Store* certstore) - { - stores.push_back(certstore); - } - -/* -* Add a certificate to the store -*/ -void X509_Store::add_cert(const X509_Certificate& cert, bool trusted) - { - if(trusted && !cert.is_self_signed()) - throw Invalid_Argument("X509_Store: Trusted certs must be self-signed"); - - if(find_cert(cert.subject_dn(), cert.subject_key_id()) == NO_CERT_FOUND) - { - revoked_info_valid = false; - Cert_Info info(cert, trusted); - certs.push_back(info); - } - else if(trusted) - { - for(size_t j = 0; j != certs.size(); ++j) - { - const X509_Certificate& this_cert = certs[j].cert; - if(this_cert == cert) - certs[j].trusted = trusted; - } - } - } - -/* -* Add one or more certificates to the store -*/ -void X509_Store::do_add_certs(DataSource& source, bool trusted) - { - while(!source.end_of_data()) - { - try { - X509_Certificate cert(source); - add_cert(cert, trusted); - } - catch(Decoding_Error) {} - catch(Invalid_Argument) {} - } - } - -/* -* Add one or more certificates to the store -*/ -void X509_Store::add_certs(DataSource& source) - { - do_add_certs(source, false); - } - -/* -* Add one or more certificates to the store -*/ -void X509_Store::add_trusted_certs(DataSource& source) - { - do_add_certs(source, true); - } - -/* -* Add one or more certificates to the store -*/ -X509_Code X509_Store::add_crl(const X509_CRL& crl) - { - s32bit time_check = validity_check(crl.this_update(), crl.next_update(), - system_time(), time_slack); - - if(time_check < 0) return CRL_NOT_YET_VALID; - else if(time_check > 0) return CRL_HAS_EXPIRED; - - size_t cert_index = NO_CERT_FOUND; - - for(size_t j = 0; j != certs.size(); ++j) - { - const X509_Certificate& this_cert = certs[j].cert; - if(compare_ids(this_cert.subject_key_id(), crl.authority_key_id())) - { - if(this_cert.subject_dn() == crl.issuer_dn()) - cert_index = j; - } - } - - if(cert_index == NO_CERT_FOUND) - return CRL_ISSUER_NOT_FOUND; - - const X509_Certificate& ca_cert = certs[cert_index].cert; - - X509_Code verify_result = validate_cert(ca_cert, CRL_SIGNING); - if(verify_result != VERIFIED) - return verify_result; - - verify_result = check_sig(crl, ca_cert.subject_public_key()); - if(verify_result != VERIFIED) - return verify_result; - - std::vector revoked_certs = crl.get_revoked(); - - for(size_t j = 0; j != revoked_certs.size(); ++j) - { - CRL_Data revoked_info; - revoked_info.issuer = crl.issuer_dn(); - revoked_info.serial = revoked_certs[j].serial_number(); - revoked_info.auth_key_id = crl.authority_key_id(); - - std::vector::iterator p = - std::find(revoked.begin(), revoked.end(), revoked_info); - - if(revoked_certs[j].reason_code() == REMOVE_FROM_CRL) - { - if(p == revoked.end()) continue; - revoked.erase(p); - } - else - { - if(p != revoked.end()) continue; - revoked.push_back(revoked_info); - } - } - - std::sort(revoked.begin(), revoked.end()); - revoked_info_valid = false; - - return VERIFIED; - } - -/* -* PEM encode the set of certificates -*/ -std::string X509_Store::PEM_encode() const - { - std::string cert_store; - for(size_t j = 0; j != certs.size(); ++j) - cert_store += certs[j].cert.PEM_encode(); - return cert_store; - } - -/* -* Create a Cert_Info structure -*/ -X509_Store::Cert_Info::Cert_Info(const X509_Certificate& c, - bool t) : cert(c), trusted(t) - { - checked = false; - result = UNKNOWN_X509_ERROR; - last_checked = 0; - } - -/* -* Return the verification results -*/ -X509_Code X509_Store::Cert_Info::verify_result() const - { - if(!checked) - throw Invalid_State("Cert_Info::verify_result() called; not checked"); - return result; - } - -/* -* Set the verification results -*/ -void X509_Store::Cert_Info::set_result(X509_Code code) const - { - result = code; - last_checked = system_time(); - checked = true; - } - -/* -* Check if this certificate can be trusted -*/ -bool X509_Store::Cert_Info::is_trusted() const - { - return trusted; - } - -/* -* Check if this certificate has been verified -*/ -bool X509_Store::Cert_Info::is_verified(u32bit timeout) const - { - if(!checked) - return false; - if(result != VERIFIED && result != CERT_NOT_YET_VALID) - return true; - - const u64bit current_time = system_time(); - - if(current_time > last_checked + timeout) - checked = false; - - return checked; - } - -} -/* -* Adler32 -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -namespace { - -void adler32_update(const byte input[], size_t length, - u16bit& S1, u16bit& S2) - { - u32bit S1x = S1; - u32bit S2x = S2; - - while(length >= 16) - { - S1x += input[ 0]; S2x += S1x; - S1x += input[ 1]; S2x += S1x; - S1x += input[ 2]; S2x += S1x; - S1x += input[ 3]; S2x += S1x; - S1x += input[ 4]; S2x += S1x; - S1x += input[ 5]; S2x += S1x; - S1x += input[ 6]; S2x += S1x; - S1x += input[ 7]; S2x += S1x; - S1x += input[ 8]; S2x += S1x; - S1x += input[ 9]; S2x += S1x; - S1x += input[10]; S2x += S1x; - S1x += input[11]; S2x += S1x; - S1x += input[12]; S2x += S1x; - S1x += input[13]; S2x += S1x; - S1x += input[14]; S2x += S1x; - S1x += input[15]; S2x += S1x; - input += 16; - length -= 16; - } - - for(size_t j = 0; j != length; ++j) - { - S1x += input[j]; - S2x += S1x; - } - - S1 = S1x % 65521; - S2 = S2x % 65521; - } - -} - -/* -* Update an Adler32 Checksum -*/ -void Adler32::add_data(const byte input[], size_t length) - { - const size_t PROCESS_AMOUNT = 5552; - - while(length >= PROCESS_AMOUNT) - { - adler32_update(input, PROCESS_AMOUNT, S1, S2); - input += PROCESS_AMOUNT; - length -= PROCESS_AMOUNT; - } - - adler32_update(input, length, S1, S2); - } - -/* -* Finalize an Adler32 Checksum -*/ -void Adler32::final_result(byte output[]) - { - store_be(output, S2, S1); - clear(); - } - -} -/* -* CRC24 -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -/* -* Update a CRC24 Checksum -*/ -void CRC24::add_data(const byte input[], size_t length) - { - const u32bit TABLE[256] = { - 0x00000000, 0x00864CFB, 0x008AD50D, 0x000C99F6, 0x0093E6E1, 0x0015AA1A, - 0x001933EC, 0x009F7F17, 0x00A18139, 0x0027CDC2, 0x002B5434, 0x00AD18CF, - 0x003267D8, 0x00B42B23, 0x00B8B2D5, 0x003EFE2E, 0x00C54E89, 0x00430272, - 0x004F9B84, 0x00C9D77F, 0x0056A868, 0x00D0E493, 0x00DC7D65, 0x005A319E, - 0x0064CFB0, 0x00E2834B, 0x00EE1ABD, 0x00685646, 0x00F72951, 0x007165AA, - 0x007DFC5C, 0x00FBB0A7, 0x000CD1E9, 0x008A9D12, 0x008604E4, 0x0000481F, - 0x009F3708, 0x00197BF3, 0x0015E205, 0x0093AEFE, 0x00AD50D0, 0x002B1C2B, - 0x002785DD, 0x00A1C926, 0x003EB631, 0x00B8FACA, 0x00B4633C, 0x00322FC7, - 0x00C99F60, 0x004FD39B, 0x00434A6D, 0x00C50696, 0x005A7981, 0x00DC357A, - 0x00D0AC8C, 0x0056E077, 0x00681E59, 0x00EE52A2, 0x00E2CB54, 0x006487AF, - 0x00FBF8B8, 0x007DB443, 0x00712DB5, 0x00F7614E, 0x0019A3D2, 0x009FEF29, - 0x009376DF, 0x00153A24, 0x008A4533, 0x000C09C8, 0x0000903E, 0x0086DCC5, - 0x00B822EB, 0x003E6E10, 0x0032F7E6, 0x00B4BB1D, 0x002BC40A, 0x00AD88F1, - 0x00A11107, 0x00275DFC, 0x00DCED5B, 0x005AA1A0, 0x00563856, 0x00D074AD, - 0x004F0BBA, 0x00C94741, 0x00C5DEB7, 0x0043924C, 0x007D6C62, 0x00FB2099, - 0x00F7B96F, 0x0071F594, 0x00EE8A83, 0x0068C678, 0x00645F8E, 0x00E21375, - 0x0015723B, 0x00933EC0, 0x009FA736, 0x0019EBCD, 0x008694DA, 0x0000D821, - 0x000C41D7, 0x008A0D2C, 0x00B4F302, 0x0032BFF9, 0x003E260F, 0x00B86AF4, - 0x002715E3, 0x00A15918, 0x00ADC0EE, 0x002B8C15, 0x00D03CB2, 0x00567049, - 0x005AE9BF, 0x00DCA544, 0x0043DA53, 0x00C596A8, 0x00C90F5E, 0x004F43A5, - 0x0071BD8B, 0x00F7F170, 0x00FB6886, 0x007D247D, 0x00E25B6A, 0x00641791, - 0x00688E67, 0x00EEC29C, 0x003347A4, 0x00B50B5F, 0x00B992A9, 0x003FDE52, - 0x00A0A145, 0x0026EDBE, 0x002A7448, 0x00AC38B3, 0x0092C69D, 0x00148A66, - 0x00181390, 0x009E5F6B, 0x0001207C, 0x00876C87, 0x008BF571, 0x000DB98A, - 0x00F6092D, 0x007045D6, 0x007CDC20, 0x00FA90DB, 0x0065EFCC, 0x00E3A337, - 0x00EF3AC1, 0x0069763A, 0x00578814, 0x00D1C4EF, 0x00DD5D19, 0x005B11E2, - 0x00C46EF5, 0x0042220E, 0x004EBBF8, 0x00C8F703, 0x003F964D, 0x00B9DAB6, - 0x00B54340, 0x00330FBB, 0x00AC70AC, 0x002A3C57, 0x0026A5A1, 0x00A0E95A, - 0x009E1774, 0x00185B8F, 0x0014C279, 0x00928E82, 0x000DF195, 0x008BBD6E, - 0x00872498, 0x00016863, 0x00FAD8C4, 0x007C943F, 0x00700DC9, 0x00F64132, - 0x00693E25, 0x00EF72DE, 0x00E3EB28, 0x0065A7D3, 0x005B59FD, 0x00DD1506, - 0x00D18CF0, 0x0057C00B, 0x00C8BF1C, 0x004EF3E7, 0x00426A11, 0x00C426EA, - 0x002AE476, 0x00ACA88D, 0x00A0317B, 0x00267D80, 0x00B90297, 0x003F4E6C, - 0x0033D79A, 0x00B59B61, 0x008B654F, 0x000D29B4, 0x0001B042, 0x0087FCB9, - 0x001883AE, 0x009ECF55, 0x009256A3, 0x00141A58, 0x00EFAAFF, 0x0069E604, - 0x00657FF2, 0x00E33309, 0x007C4C1E, 0x00FA00E5, 0x00F69913, 0x0070D5E8, - 0x004E2BC6, 0x00C8673D, 0x00C4FECB, 0x0042B230, 0x00DDCD27, 0x005B81DC, - 0x0057182A, 0x00D154D1, 0x0026359F, 0x00A07964, 0x00ACE092, 0x002AAC69, - 0x00B5D37E, 0x00339F85, 0x003F0673, 0x00B94A88, 0x0087B4A6, 0x0001F85D, - 0x000D61AB, 0x008B2D50, 0x00145247, 0x00921EBC, 0x009E874A, 0x0018CBB1, - 0x00E37B16, 0x006537ED, 0x0069AE1B, 0x00EFE2E0, 0x00709DF7, 0x00F6D10C, - 0x00FA48FA, 0x007C0401, 0x0042FA2F, 0x00C4B6D4, 0x00C82F22, 0x004E63D9, - 0x00D11CCE, 0x00575035, 0x005BC9C3, 0x00DD8538 }; - - u32bit tmp = crc; - while(length >= 16) - { - tmp = TABLE[((tmp >> 16) ^ input[ 0]) & 0xFF] ^ (tmp << 8); - tmp = TABLE[((tmp >> 16) ^ input[ 1]) & 0xFF] ^ (tmp << 8); - tmp = TABLE[((tmp >> 16) ^ input[ 2]) & 0xFF] ^ (tmp << 8); - tmp = TABLE[((tmp >> 16) ^ input[ 3]) & 0xFF] ^ (tmp << 8); - tmp = TABLE[((tmp >> 16) ^ input[ 4]) & 0xFF] ^ (tmp << 8); - tmp = TABLE[((tmp >> 16) ^ input[ 5]) & 0xFF] ^ (tmp << 8); - tmp = TABLE[((tmp >> 16) ^ input[ 6]) & 0xFF] ^ (tmp << 8); - tmp = TABLE[((tmp >> 16) ^ input[ 7]) & 0xFF] ^ (tmp << 8); - tmp = TABLE[((tmp >> 16) ^ input[ 8]) & 0xFF] ^ (tmp << 8); - tmp = TABLE[((tmp >> 16) ^ input[ 9]) & 0xFF] ^ (tmp << 8); - tmp = TABLE[((tmp >> 16) ^ input[10]) & 0xFF] ^ (tmp << 8); - tmp = TABLE[((tmp >> 16) ^ input[11]) & 0xFF] ^ (tmp << 8); - tmp = TABLE[((tmp >> 16) ^ input[12]) & 0xFF] ^ (tmp << 8); - tmp = TABLE[((tmp >> 16) ^ input[13]) & 0xFF] ^ (tmp << 8); - tmp = TABLE[((tmp >> 16) ^ input[14]) & 0xFF] ^ (tmp << 8); - tmp = TABLE[((tmp >> 16) ^ input[15]) & 0xFF] ^ (tmp << 8); - input += 16; - length -= 16; - } - - for(size_t i = 0; i != length; ++i) - tmp = TABLE[((tmp >> 16) ^ input[i]) & 0xFF] ^ (tmp << 8); - - crc = tmp; - } - -/* -* Finalize a CRC24 Checksum -*/ -void CRC24::final_result(byte output[]) - { - for(size_t i = 0; i != 3; ++i) - output[i] = get_byte(i+1, crc); - clear(); - } - -} -/* -* CRC32 -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -/* -* Update a CRC32 Checksum -*/ -void CRC32::add_data(const byte input[], size_t length) - { - const u32bit TABLE[256] = { - 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, - 0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, - 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2, - 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, - 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, - 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, - 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C, - 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, - 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, - 0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, - 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106, - 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, - 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, - 0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, - 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950, - 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, - 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, - 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, - 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA, - 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, - 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, - 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, - 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84, - 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, - 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, - 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, - 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E, - 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, - 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, - 0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, - 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28, - 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, - 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, - 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, - 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242, - 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, - 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, - 0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, - 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC, - 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, - 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, - 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, - 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D }; - - u32bit tmp = crc; - while(length >= 16) - { - tmp = TABLE[(tmp ^ input[ 0]) & 0xFF] ^ (tmp >> 8); - tmp = TABLE[(tmp ^ input[ 1]) & 0xFF] ^ (tmp >> 8); - tmp = TABLE[(tmp ^ input[ 2]) & 0xFF] ^ (tmp >> 8); - tmp = TABLE[(tmp ^ input[ 3]) & 0xFF] ^ (tmp >> 8); - tmp = TABLE[(tmp ^ input[ 4]) & 0xFF] ^ (tmp >> 8); - tmp = TABLE[(tmp ^ input[ 5]) & 0xFF] ^ (tmp >> 8); - tmp = TABLE[(tmp ^ input[ 6]) & 0xFF] ^ (tmp >> 8); - tmp = TABLE[(tmp ^ input[ 7]) & 0xFF] ^ (tmp >> 8); - tmp = TABLE[(tmp ^ input[ 8]) & 0xFF] ^ (tmp >> 8); - tmp = TABLE[(tmp ^ input[ 9]) & 0xFF] ^ (tmp >> 8); - tmp = TABLE[(tmp ^ input[10]) & 0xFF] ^ (tmp >> 8); - tmp = TABLE[(tmp ^ input[11]) & 0xFF] ^ (tmp >> 8); - tmp = TABLE[(tmp ^ input[12]) & 0xFF] ^ (tmp >> 8); - tmp = TABLE[(tmp ^ input[13]) & 0xFF] ^ (tmp >> 8); - tmp = TABLE[(tmp ^ input[14]) & 0xFF] ^ (tmp >> 8); - tmp = TABLE[(tmp ^ input[15]) & 0xFF] ^ (tmp >> 8); - input += 16; - length -= 16; - } - - for(size_t i = 0; i != length; ++i) - tmp = TABLE[(tmp ^ input[i]) & 0xFF] ^ (tmp >> 8); - - crc = tmp; - } - -/* -* Finalize a CRC32 Checksum -*/ -void CRC32::final_result(byte output[]) - { - crc ^= 0xFFFFFFFF; - store_be(crc, output); - clear(); - } - -} -/* -* Base64 Encoding and Decoding -* (C) 2010 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include - -namespace Botan { - -namespace { - -static const byte 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 byte in[3]) - { - 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) )]; - } - -} - -size_t base64_encode(char out[], - const byte in[], - size_t input_length, - 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) - { - byte 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; - } - -std::string base64_encode(const byte input[], - size_t input_length) - { - std::string output((round_up(input_length, 3) / 3) * 4, 0); - - size_t consumed = 0; - size_t produced = base64_encode(&output[0], - input, input_length, - consumed, true); - - BOTAN_ASSERT_EQUAL(consumed, input_length, "Did not consume all input"); - BOTAN_ASSERT_EQUAL(produced, output.size(), "Did not produce right amount"); - - return output; - } - -std::string base64_encode(const MemoryRegion& input) - { - return base64_encode(&input[0], input.size()); - } - -size_t base64_decode(byte output[], - const char input[], - size_t input_length, - size_t& input_consumed, - bool final_inputs, - bool ignore_ws) - { - /* - * Base64 Decoder Lookup Table - * Warning: assumes ASCII encodings - */ - static const byte 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 }; - - byte* out_ptr = output; - byte 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 byte bin = BASE64_TO_BIN[static_cast(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 std::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 i = decode_buf_pos; i != 4; ++i) - decode_buf[i] = 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(input[input_consumed])] == 0x80) - { - ++input_consumed; - } - - size_t written = (out_ptr - output) - final_truncate; - - return written; - } - -size_t base64_decode(byte output[], - const char input[], - size_t input_length, - bool ignore_ws) - { - size_t consumed = 0; - size_t written = base64_decode(output, input, input_length, - consumed, true, ignore_ws); - - if(consumed != input_length) - throw std::invalid_argument("base64_decode: input did not have full bytes"); - - return written; - } - -size_t base64_decode(byte output[], - const std::string& input, - bool ignore_ws) - { - return base64_decode(output, &input[0], input.length(), ignore_ws); - } - -SecureVector base64_decode(const char input[], - size_t input_length, - bool ignore_ws) - { - SecureVector bin((round_up(input_length, 4) * 3) / 4); - - size_t written = base64_decode(&bin[0], - input, - input_length, - ignore_ws); - - bin.resize(written); - return bin; - } - -SecureVector base64_decode(const std::string& input, - bool ignore_ws) - { - return base64_decode(&input[0], input.size(), ignore_ws); - } - - -} -/* -* Hex Encoding and Decoding -* (C) 2010 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include - -namespace Botan { - -void hex_encode(char output[], - const byte input[], - size_t input_length, - bool uppercase) - { - static const byte BIN_TO_HEX_UPPER[16] = { - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', - 'A', 'B', 'C', 'D', 'E', 'F' }; - - static const byte BIN_TO_HEX_LOWER[16] = { - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', - 'a', 'b', 'c', 'd', 'e', 'f' }; - - const byte* tbl = uppercase ? BIN_TO_HEX_UPPER : BIN_TO_HEX_LOWER; - - for(size_t i = 0; i != input_length; ++i) - { - byte x = input[i]; - output[2*i ] = tbl[(x >> 4) & 0x0F]; - output[2*i+1] = tbl[(x ) & 0x0F]; - } - } - -std::string hex_encode(const MemoryRegion& input, - bool uppercase) - { - return hex_encode(&input[0], input.size(), uppercase); - } - -std::string hex_encode(const byte input[], - size_t input_length, - bool uppercase) - { - std::string output(2 * input_length, 0); - - if(input_length) - hex_encode(&output[0], input, input_length, uppercase); - - return output; - } - -size_t hex_decode(byte output[], - const char input[], - size_t input_length, - size_t& input_consumed, - bool ignore_ws) - { - /* - * Mapping of hex characters to either their binary equivalent - * or to an error code. - * If valid hex (0-9 A-F a-f), the value. - * If whitespace, then 0x80 - * Otherwise 0xFF - * Warning: this table assumes ASCII character encodings - */ - - static const byte HEX_TO_BIN[256] = { - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, - 0x80, 0xFF, 0xFF, 0xFF, 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, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, - 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, - 0x0F, 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, 0x0A, 0x0B, 0x0C, - 0x0D, 0x0E, 0x0F, 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, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; - - byte* out_ptr = output; - bool top_nibble = true; - - clear_mem(output, input_length / 2); - - for(size_t i = 0; i != input_length; ++i) - { - const byte bin = HEX_TO_BIN[static_cast(input[i])]; - - if(bin >= 0x10) - { - if(bin == 0x80 && ignore_ws) - continue; - - std::string bad_char(1, input[i]); - if(bad_char == "\t") - bad_char = "\\t"; - else if(bad_char == "\n") - bad_char = "\\n"; - - throw std::invalid_argument( - std::string("hex_decode: invalid hex character '") + - bad_char + "'"); - } - - *out_ptr |= bin << (top_nibble*4); - - top_nibble = !top_nibble; - if(top_nibble) - ++out_ptr; - } - - input_consumed = input_length; - size_t written = (out_ptr - output); - - /* - * We only got half of a byte at the end; zap the half-written - * output and mark it as unread - */ - if(!top_nibble) - { - *out_ptr = 0; - input_consumed -= 1; - } - - return written; - } - -size_t hex_decode(byte output[], - const char input[], - size_t input_length, - bool ignore_ws) - { - size_t consumed = 0; - size_t written = hex_decode(output, input, input_length, - consumed, ignore_ws); - - if(consumed != input_length) - throw std::invalid_argument("hex_decode: input did not have full bytes"); - - return written; - } - -size_t hex_decode(byte output[], - const std::string& input, - bool ignore_ws) - { - return hex_decode(output, &input[0], input.length(), ignore_ws); - } - -SecureVector hex_decode(const char input[], - size_t input_length, - bool ignore_ws) - { - SecureVector bin(1 + input_length / 2); - - size_t written = hex_decode(&bin[0], - input, - input_length, - ignore_ws); - - bin.resize(written); - return bin; - } - -SecureVector hex_decode(const std::string& input, - bool ignore_ws) - { - return hex_decode(&input[0], input.size(), ignore_ws); - } - -} -/* -* OpenPGP Codec -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -/* -* OpenPGP Base64 encoding -*/ -std::string PGP_encode( - const byte input[], size_t length, - const std::string& label, - const std::map& headers) - { - const std::string PGP_HEADER = "-----BEGIN PGP " + label + "-----\n"; - const std::string PGP_TRAILER = "-----END PGP " + label + "-----\n"; - const size_t PGP_WIDTH = 64; - - std::string pgp_encoded = PGP_HEADER; - - if(headers.find("Version") != headers.end()) - pgp_encoded += "Version: " + headers.find("Version")->second + '\n'; - - std::map::const_iterator i = headers.begin(); - while(i != headers.end()) - { - if(i->first != "Version") - pgp_encoded += i->first + ": " + i->second + '\n'; - ++i; - } - pgp_encoded += '\n'; - - Pipe pipe(new Fork( - new Base64_Encoder(true, PGP_WIDTH), - new Chain(new Hash_Filter(new CRC24), new Base64_Encoder) - ) - ); - - pipe.process_msg(input, length); - - pgp_encoded += pipe.read_all_as_string(0); - pgp_encoded += '=' + pipe.read_all_as_string(1) + '\n'; - pgp_encoded += PGP_TRAILER; - - return pgp_encoded; - } - -/* -* OpenPGP Base64 encoding -*/ -std::string PGP_encode(const byte input[], size_t length, - const std::string& type) - { - std::map empty; - return PGP_encode(input, length, type, empty); - } - -/* -* OpenPGP Base64 decoding -*/ -SecureVector PGP_decode(DataSource& source, - std::string& label, - std::map& headers) - { - const size_t RANDOM_CHAR_LIMIT = 5; - - const std::string PGP_HEADER1 = "-----BEGIN PGP "; - const std::string PGP_HEADER2 = "-----"; - size_t position = 0; - - while(position != PGP_HEADER1.length()) - { - byte b; - if(!source.read_byte(b)) - throw Decoding_Error("PGP: No PGP header found"); - if(b == PGP_HEADER1[position]) - ++position; - else if(position >= RANDOM_CHAR_LIMIT) - throw Decoding_Error("PGP: Malformed PGP header"); - else - position = 0; - } - position = 0; - while(position != PGP_HEADER2.length()) - { - byte b; - if(!source.read_byte(b)) - throw Decoding_Error("PGP: No PGP header found"); - if(b == PGP_HEADER2[position]) - ++position; - else if(position) - throw Decoding_Error("PGP: Malformed PGP header"); - - if(position == 0) - label += static_cast(b); - } - - headers.clear(); - bool end_of_headers = false; - while(!end_of_headers) - { - std::string this_header; - byte b = 0; - while(b != '\n') - { - if(!source.read_byte(b)) - throw Decoding_Error("PGP: Bad armor header"); - if(b != '\n') - this_header += static_cast(b); - } - - end_of_headers = true; - for(size_t j = 0; j != this_header.length(); ++j) - if(!Charset::is_space(this_header[j])) - end_of_headers = false; - - if(!end_of_headers) - { - std::string::size_type pos = this_header.find(": "); - if(pos == std::string::npos) - throw Decoding_Error("OpenPGP: Bad headers"); - - std::string key = this_header.substr(0, pos); - std::string value = this_header.substr(pos + 2, std::string::npos); - headers[key] = value; - } - } - - Pipe base64(new Base64_Decoder, - new Fork(0, - new Chain(new Hash_Filter(new CRC24), - new Base64_Encoder) - ) - ); - base64.start_msg(); - - const std::string PGP_TRAILER = "-----END PGP " + label + "-----"; - position = 0; - bool newline_seen = 0; - std::string crc; - while(position != PGP_TRAILER.length()) - { - byte b; - if(!source.read_byte(b)) - throw Decoding_Error("PGP: No PGP trailer found"); - if(b == PGP_TRAILER[position]) - ++position; - else if(position) - throw Decoding_Error("PGP: Malformed PGP trailer"); - - if(b == '=' && newline_seen) - { - while(b != '\n') - { - if(!source.read_byte(b)) - throw Decoding_Error("PGP: Bad CRC tail"); - if(b != '\n') - crc += static_cast(b); - } - } - else if(b == '\n') - newline_seen = true; - else if(position == 0) - { - base64.write(b); - newline_seen = false; - } - } - base64.end_msg(); - - if(crc != "" && crc != base64.read_all_as_string(1)) - throw Decoding_Error("PGP: Corrupt CRC"); - - return base64.read_all(); - } - -/* -* OpenPGP Base64 decoding -*/ -SecureVector PGP_decode(DataSource& source, std::string& label) - { - std::map ignored; - return PGP_decode(source, label, ignored); - } - -} - -/* -* PEM Encoding/Decoding -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -namespace PEM_Code { - -/* -* PEM encode BER/DER-encoded objects -*/ -std::string encode(const byte der[], size_t length, const std::string& label, - size_t width) - { - const std::string PEM_HEADER = "-----BEGIN " + label + "-----\n"; - const std::string PEM_TRAILER = "-----END " + label + "-----\n"; - - Pipe pipe(new Base64_Encoder(true, width)); - pipe.process_msg(der, length); - return (PEM_HEADER + pipe.read_all_as_string() + PEM_TRAILER); - } - -/* -* PEM encode BER/DER-encoded objects -*/ -std::string encode(const MemoryRegion& data, const std::string& label, - size_t width) - { - return encode(&data[0], data.size(), label, width); - } - -/* -* Decode PEM down to raw BER/DER -*/ -SecureVector decode_check_label(DataSource& source, - const std::string& label_want) - { - std::string label_got; - SecureVector ber = decode(source, label_got); - if(label_got != label_want) - throw Decoding_Error("PEM: Label mismatch, wanted " + label_want + - ", got " + label_got); - return ber; - } - -/* -* Decode PEM down to raw BER/DER -*/ -SecureVector decode(DataSource& source, std::string& label) - { - const size_t RANDOM_CHAR_LIMIT = 8; - - const std::string PEM_HEADER1 = "-----BEGIN "; - const std::string PEM_HEADER2 = "-----"; - size_t position = 0; - - while(position != PEM_HEADER1.length()) - { - byte b; - if(!source.read_byte(b)) - throw Decoding_Error("PEM: No PEM header found"); - if(b == PEM_HEADER1[position]) - ++position; - else if(position >= RANDOM_CHAR_LIMIT) - throw Decoding_Error("PEM: Malformed PEM header"); - else - position = 0; - } - position = 0; - while(position != PEM_HEADER2.length()) - { - byte b; - if(!source.read_byte(b)) - throw Decoding_Error("PEM: No PEM header found"); - if(b == PEM_HEADER2[position]) - ++position; - else if(position) - throw Decoding_Error("PEM: Malformed PEM header"); - - if(position == 0) - label += static_cast(b); - } - - Pipe base64(new Base64_Decoder); - base64.start_msg(); - - const std::string PEM_TRAILER = "-----END " + label + "-----"; - position = 0; - while(position != PEM_TRAILER.length()) - { - byte b; - if(!source.read_byte(b)) - throw Decoding_Error("PEM: No PEM trailer found"); - if(b == PEM_TRAILER[position]) - ++position; - else if(position) - throw Decoding_Error("PEM: Malformed PEM trailer"); - - if(position == 0) - base64.write(b); - } - base64.end_msg(); - return base64.read_all(); - } - -/* -* Search for a PEM signature -*/ -bool matches(DataSource& source, const std::string& extra, - size_t search_range) - { - const std::string PEM_HEADER = "-----BEGIN " + extra; - - SecureVector search_buf(search_range); - size_t got = source.peek(&search_buf[0], search_buf.size(), 0); - - if(got < PEM_HEADER.length()) - return false; - - size_t index = 0; - - for(size_t j = 0; j != got; ++j) - { - if(search_buf[j] == PEM_HEADER[index]) - ++index; - else - index = 0; - if(index == PEM_HEADER.size()) - return true; - } - return false; - } - -} - -} -/* -* Rivest's Package Tranform -* -* (C) 2009 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -void aont_package(RandomNumberGenerator& rng, - BlockCipher* cipher, - const byte input[], size_t input_len, - byte output[]) - { - const size_t BLOCK_SIZE = cipher->block_size(); - - if(!cipher->valid_keylength(BLOCK_SIZE)) - throw Invalid_Argument("AONT::package: Invalid cipher"); - - // The all-zero string which is used both as the CTR IV and as K0 - const std::string all_zeros(BLOCK_SIZE*2, '0'); - - SymmetricKey package_key(rng, BLOCK_SIZE); - - Pipe pipe(new StreamCipher_Filter(new CTR_BE(cipher), package_key)); - - pipe.process_msg(input, input_len); - pipe.read(output, pipe.remaining()); - - // Set K0 (the all zero key) - cipher->set_key(SymmetricKey(all_zeros)); - - SecureVector buf(BLOCK_SIZE); - - const size_t blocks = - (input_len + BLOCK_SIZE - 1) / BLOCK_SIZE; - - byte* final_block = output + input_len; - clear_mem(final_block, BLOCK_SIZE); - - // XOR the hash blocks into the final block - for(size_t i = 0; i != blocks; ++i) - { - const size_t left = std::min(BLOCK_SIZE, - input_len - BLOCK_SIZE * i); - - zeroise(buf); - copy_mem(&buf[0], output + (BLOCK_SIZE * i), left); - - for(size_t j = 0; j != sizeof(i); ++j) - buf[BLOCK_SIZE - 1 - j] ^= get_byte(sizeof(i)-1-j, i); - - cipher->encrypt(buf); - - xor_buf(final_block, buf, BLOCK_SIZE); - } - - // XOR the random package key into the final block - xor_buf(final_block, package_key.begin(), BLOCK_SIZE); - } - -void aont_unpackage(BlockCipher* cipher, - const byte input[], size_t input_len, - byte output[]) - { - const size_t BLOCK_SIZE = cipher->block_size(); - - if(!cipher->valid_keylength(BLOCK_SIZE)) - throw Invalid_Argument("AONT::unpackage: Invalid cipher"); - - if(input_len < BLOCK_SIZE) - throw Invalid_Argument("AONT::unpackage: Input too short"); - - // The all-zero string which is used both as the CTR IV and as K0 - const std::string all_zeros(BLOCK_SIZE*2, '0'); - - cipher->set_key(SymmetricKey(all_zeros)); - - SecureVector package_key(BLOCK_SIZE); - SecureVector buf(BLOCK_SIZE); - - // Copy the package key (masked with the block hashes) - copy_mem(&package_key[0], - input + (input_len - BLOCK_SIZE), - BLOCK_SIZE); - - const size_t blocks = ((input_len - 1) / BLOCK_SIZE); - - // XOR the blocks into the package key bits - for(size_t i = 0; i != blocks; ++i) - { - const size_t left = std::min(BLOCK_SIZE, - input_len - BLOCK_SIZE * (i+1)); - - zeroise(buf); - copy_mem(&buf[0], input + (BLOCK_SIZE * i), left); - - for(size_t j = 0; j != sizeof(i); ++j) - buf[BLOCK_SIZE - 1 - j] ^= get_byte(sizeof(i)-1-j, i); - - cipher->encrypt(buf); - - xor_buf(&package_key[0], buf, BLOCK_SIZE); - } - - Pipe pipe(new StreamCipher_Filter(new CTR_BE(cipher), package_key)); - - pipe.process_msg(input, input_len - BLOCK_SIZE); - - pipe.read(output, pipe.remaining()); - } - -} -/* -* Cryptobox Message Routines -* (C) 2009 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -namespace CryptoBox { - -namespace { - -/* -First 24 bits of SHA-256("Botan Cryptobox"), followed by 8 0 bits -for later use as flags, etc if needed -*/ -const u32bit CRYPTOBOX_VERSION_CODE = 0xEFC22400; - -const size_t VERSION_CODE_LEN = 4; -const size_t CIPHER_KEY_LEN = 32; -const size_t CIPHER_IV_LEN = 16; -const size_t MAC_KEY_LEN = 32; -const size_t MAC_OUTPUT_LEN = 20; -const size_t PBKDF_SALT_LEN = 10; -const size_t PBKDF_ITERATIONS = 8 * 1024; - -const size_t PBKDF_OUTPUT_LEN = CIPHER_KEY_LEN + CIPHER_IV_LEN + MAC_KEY_LEN; - -} - -std::string encrypt(const byte input[], size_t input_len, - const std::string& passphrase, - RandomNumberGenerator& rng) - { - SecureVector pbkdf_salt(PBKDF_SALT_LEN); - rng.randomize(&pbkdf_salt[0], pbkdf_salt.size()); - - PKCS5_PBKDF2 pbkdf(new HMAC(new SHA_512)); - - OctetString master_key = pbkdf.derive_key( - PBKDF_OUTPUT_LEN, - passphrase, - &pbkdf_salt[0], - pbkdf_salt.size(), - PBKDF_ITERATIONS); - - const byte* mk = master_key.begin(); - - SymmetricKey cipher_key(&mk[0], CIPHER_KEY_LEN); - SymmetricKey mac_key(&mk[CIPHER_KEY_LEN], MAC_KEY_LEN); - InitializationVector iv(&mk[CIPHER_KEY_LEN + MAC_KEY_LEN], CIPHER_IV_LEN); - - Pipe pipe(get_cipher("Serpent/CTR-BE", cipher_key, iv, ENCRYPTION), - new Fork( - 0, - new MAC_Filter(new HMAC(new SHA_512), - mac_key, MAC_OUTPUT_LEN))); - - pipe.process_msg(input, input_len); - - /* - Output format is: - version # (4 bytes) - salt (10 bytes) - mac (20 bytes) - ciphertext - */ - const size_t ciphertext_len = pipe.remaining(0); - - SecureVector out_buf(VERSION_CODE_LEN + - PBKDF_SALT_LEN + - MAC_OUTPUT_LEN + - ciphertext_len); - - for(size_t i = 0; i != VERSION_CODE_LEN; ++i) - out_buf[i] = get_byte(i, CRYPTOBOX_VERSION_CODE); - - copy_mem(&out_buf[VERSION_CODE_LEN], &pbkdf_salt[0], PBKDF_SALT_LEN); - - pipe.read(&out_buf[VERSION_CODE_LEN + PBKDF_SALT_LEN], MAC_OUTPUT_LEN, 1); - pipe.read(&out_buf[VERSION_CODE_LEN + PBKDF_SALT_LEN + MAC_OUTPUT_LEN], - ciphertext_len, 0); - - return PEM_Code::encode(out_buf, "BOTAN CRYPTOBOX MESSAGE"); - } - -std::string decrypt(const byte input[], size_t input_len, - const std::string& passphrase) - { - DataSource_Memory input_src(input, input_len); - SecureVector ciphertext = - PEM_Code::decode_check_label(input_src, - "BOTAN CRYPTOBOX MESSAGE"); - - if(ciphertext.size() < (VERSION_CODE_LEN + PBKDF_SALT_LEN + MAC_OUTPUT_LEN)) - throw Decoding_Error("Invalid CryptoBox input"); - - for(size_t i = 0; i != VERSION_CODE_LEN; ++i) - if(ciphertext[i] != get_byte(i, CRYPTOBOX_VERSION_CODE)) - throw Decoding_Error("Bad CryptoBox version"); - - const byte* pbkdf_salt = &ciphertext[VERSION_CODE_LEN]; - - PKCS5_PBKDF2 pbkdf(new HMAC(new SHA_512)); - - OctetString master_key = pbkdf.derive_key( - PBKDF_OUTPUT_LEN, - passphrase, - pbkdf_salt, - PBKDF_SALT_LEN, - PBKDF_ITERATIONS); - - const byte* mk = master_key.begin(); - - SymmetricKey cipher_key(&mk[0], CIPHER_KEY_LEN); - SymmetricKey mac_key(&mk[CIPHER_KEY_LEN], MAC_KEY_LEN); - InitializationVector iv(&mk[CIPHER_KEY_LEN + MAC_KEY_LEN], CIPHER_IV_LEN); - - Pipe pipe(new Fork( - get_cipher("Serpent/CTR-BE", cipher_key, iv, DECRYPTION), - new MAC_Filter(new HMAC(new SHA_512), - mac_key, MAC_OUTPUT_LEN))); - - const size_t ciphertext_offset = - VERSION_CODE_LEN + PBKDF_SALT_LEN + MAC_OUTPUT_LEN; - - pipe.process_msg(&ciphertext[ciphertext_offset], - ciphertext.size() - ciphertext_offset); - - byte computed_mac[MAC_OUTPUT_LEN]; - pipe.read(computed_mac, MAC_OUTPUT_LEN, 1); - - if(!same_mem(computed_mac, - &ciphertext[VERSION_CODE_LEN + PBKDF_SALT_LEN], - MAC_OUTPUT_LEN)) - throw Decoding_Error("CryptoBox integrity failure"); - - return pipe.read_all_as_string(0); - } - -std::string decrypt(const std::string& input, - const std::string& passphrase) - { - return decrypt(reinterpret_cast(&input[0]), - input.size(), - passphrase); - } - -} - -} -/* -* Format Preserving Encryption using the scheme FE1 from the paper -* "Format-Preserving Encryption" by Bellare, Rogaway, et al -* (http://eprint.iacr.org/2009/251) -* -* (C) 2009 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include - -namespace Botan { - -namespace FPE { - -namespace { - -// Normally FPE is for SSNs, CC#s, etc, nothing too big -const size_t MAX_N_BYTES = 128/8; - -/* -* Factor n into a and b which are as close together as possible. -* Assumes n is composed mostly of small factors which is the case for -* typical uses of FPE (typically, n is a power of 10) -* -* Want a >= b since the safe number of rounds is 2+log_a(b); if a >= b -* then this is always 3 -*/ -void factor(BigInt n, BigInt& a, BigInt& b) - { - a = 1; - b = 1; - - size_t n_low_zero = low_zero_bits(n); - - a <<= (n_low_zero / 2); - b <<= n_low_zero - (n_low_zero / 2); - n >>= n_low_zero; - - for(size_t i = 0; i != PRIME_TABLE_SIZE; ++i) - { - while(n % PRIMES[i] == 0) - { - a *= PRIMES[i]; - if(a > b) - std::swap(a, b); - n /= PRIMES[i]; - } - } - - if(a > b) - std::swap(a, b); - a *= n; - if(a < b) - std::swap(a, b); - - if(a <= 1 || b <= 1) - throw std::runtime_error("Could not factor n for use in FPE"); - } - -/* -* According to a paper by Rogaway, Bellare, etc, the min safe number -* of rounds to use for FPE is 2+log_a(b). If a >= b then log_a(b) <= 1 -* so 3 rounds is safe. The FPE factorization routine should always -* return a >= b, so just confirm that and return 3. -*/ -size_t rounds(const BigInt& a, const BigInt& b) - { - if(a < b) - throw std::logic_error("FPE rounds: a < b"); - return 3; - } - -/* -* A simple round function based on HMAC(SHA-256) -*/ -class FPE_Encryptor - { - public: - FPE_Encryptor(const SymmetricKey& key, - const BigInt& n, - const MemoryRegion& tweak); - - ~FPE_Encryptor() { delete mac; } - - BigInt operator()(size_t i, const BigInt& R); - - private: - MessageAuthenticationCode* mac; - SecureVector mac_n_t; - }; - -FPE_Encryptor::FPE_Encryptor(const SymmetricKey& key, - const BigInt& n, - const MemoryRegion& tweak) - { - mac = new HMAC(new SHA_256); - mac->set_key(key); - - SecureVector n_bin = BigInt::encode(n); - - if(n_bin.size() > MAX_N_BYTES) - throw std::runtime_error("N is too large for FPE encryption"); - - mac->update_be(static_cast(n_bin.size())); - mac->update(&n_bin[0], n_bin.size()); - - mac->update_be(static_cast(tweak.size())); - mac->update(&tweak[0], tweak.size()); - - mac_n_t = mac->final(); - } - -BigInt FPE_Encryptor::operator()(size_t round_no, const BigInt& R) - { - SecureVector r_bin = BigInt::encode(R); - - mac->update(mac_n_t); - mac->update_be(static_cast(round_no)); - - mac->update_be(static_cast(r_bin.size())); - mac->update(&r_bin[0], r_bin.size()); - - SecureVector X = mac->final(); - return BigInt(&X[0], X.size()); - } - -} - -/* -* Generic Z_n FPE encryption, FE1 scheme -*/ -BigInt fe1_encrypt(const BigInt& n, const BigInt& X0, - const SymmetricKey& key, - const MemoryRegion& tweak) - { - FPE_Encryptor F(key, n, tweak); - - BigInt a, b; - factor(n, a, b); - - const size_t r = rounds(a, b); - - BigInt X = X0; - - for(size_t i = 0; i != r; ++i) - { - BigInt L = X / b; - BigInt R = X % b; - - BigInt W = (L + F(i, R)) % a; - X = a * R + W; - } - - return X; - } - -/* -* Generic Z_n FPE decryption, FD1 scheme -*/ -BigInt fe1_decrypt(const BigInt& n, const BigInt& X0, - const SymmetricKey& key, - const MemoryRegion& tweak) - { - FPE_Encryptor F(key, n, tweak); - - BigInt a, b; - factor(n, a, b); - - const size_t r = rounds(a, b); - - BigInt X = X0; - - for(size_t i = 0; i != r; ++i) - { - BigInt W = X % a; - BigInt R = X / a; - - BigInt L = (W - F(r-i-1, R)) % a; - X = b * L + R; - } - - return X; - } - -} - -} -/* -* AES Key Wrap (RFC 3394) -* (C) 2011 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include - -namespace Botan { - -namespace { - -BlockCipher* make_aes(size_t keylength, - Algorithm_Factory& af) - { - if(keylength == 16) - return af.make_block_cipher("AES-128"); - else if(keylength == 24) - return af.make_block_cipher("AES-192"); - else if(keylength == 32) - return af.make_block_cipher("AES-256"); - else - throw std::invalid_argument("Bad KEK length for NIST keywrap"); - } - -} - -SecureVector rfc3394_keywrap(const MemoryRegion& key, - const SymmetricKey& kek, - Algorithm_Factory& af) - { - if(key.size() % 8 != 0) - throw std::invalid_argument("Bad input key size for NIST key wrap"); - - std::unique_ptr aes(make_aes(kek.length(), af)); - aes->set_key(kek); - - const size_t n = key.size() / 8; - - SecureVector R((n + 1) * 8); - SecureVector A(16); - - for(size_t i = 0; i != 8; ++i) - A[i] = 0xA6; - - copy_mem(&R[8], key.begin(), key.size()); - - for(size_t j = 0; j <= 5; ++j) - { - for(size_t i = 1; i <= n; ++i) - { - const u32bit t = (n * j) + i; - - copy_mem(&A[8], &R[8*i], 8); - - aes->encrypt(&A[0]); - copy_mem(&R[8*i], &A[8], 8); - - byte t_buf[4] = { 0 }; - store_be(t, t_buf); - xor_buf(&A[4], &t_buf[0], 4); - } - } - - copy_mem(&R[0], &A[0], 8); - - return R; - } - -SecureVector rfc3394_keyunwrap(const MemoryRegion& key, - const SymmetricKey& kek, - Algorithm_Factory& af) - { - if(key.size() < 16 || key.size() % 8 != 0) - throw std::invalid_argument("Bad input key size for NIST key unwrap"); - - std::unique_ptr aes(make_aes(kek.length(), af)); - aes->set_key(kek); - - const size_t n = (key.size() - 8) / 8; - - SecureVector R(n * 8); - SecureVector A(16); - - for(size_t i = 0; i != 8; ++i) - A[i] = key[i]; - - copy_mem(&R[0], key.begin() + 8, key.size() - 8); - - for(size_t j = 0; j <= 5; ++j) - { - for(size_t i = n; i != 0; --i) - { - const u32bit t = (5 - j) * n + i; - - byte t_buf[4] = { 0 }; - store_be(t, t_buf); - - xor_buf(&A[4], &t_buf[0], 4); - - copy_mem(&A[8], &R[8*(i-1)], 8); - - aes->decrypt(&A[0]); - - copy_mem(&R[8*(i-1)], &A[8], 8); - } - } - - if(load_be(&A[0], 0) != 0xA6A6A6A6A6A6A6A6ULL) - throw Integrity_Failure("NIST key unwrap failed"); - - return R; - } - -} -/* -* SRP-6a (RFC 5054 compatatible) -* (C) 2011,2012 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include - -namespace Botan { - -namespace { - -BigInt hash_seq(const std::string& hash_id, - size_t pad_to, - const BigInt& in1, - const BigInt& in2) - { - std::unique_ptr hash_fn( - global_state().algorithm_factory().make_hash_function(hash_id)); - - hash_fn->update(BigInt::encode_1363(in1, pad_to)); - hash_fn->update(BigInt::encode_1363(in2, pad_to)); - - return BigInt::decode(hash_fn->final()); - } - -BigInt compute_x(const std::string& hash_id, - const std::string& identifier, - const std::string& password, - const MemoryRegion& salt) - { - std::unique_ptr hash_fn( - global_state().algorithm_factory().make_hash_function(hash_id)); - - hash_fn->update(identifier); - hash_fn->update(":"); - hash_fn->update(password); - - SecureVector inner_h = hash_fn->final(); - - hash_fn->update(salt); - hash_fn->update(inner_h); - - SecureVector outer_h = hash_fn->final(); - - return BigInt::decode(outer_h); - } - -} - -std::string srp6_group_identifier(const BigInt& N, const BigInt& g) - { - /* - This function assumes that only one 'standard' SRP parameter set has - been defined for a particular bitsize. As of this writing that is the case. - */ - try - { - const std::string group_name = "modp/srp/" + to_string(N.bits()); - - DL_Group group(group_name); - - if(group.get_p() == N && group.get_g() == g) - return group_name; - - throw std::runtime_error("Unknown SRP params"); - } - catch(...) - { - throw Invalid_Argument("Bad SRP group parameters"); - } - } - -std::pair -srp6_client_agree(const std::string& identifier, - const std::string& password, - const std::string& group_id, - const std::string& hash_id, - const MemoryRegion& salt, - const BigInt& B, - RandomNumberGenerator& rng) - { - DL_Group group(group_id); - const BigInt& g = group.get_g(); - const BigInt& p = group.get_p(); - - const size_t p_bytes = group.get_p().bytes(); - - if(B % p == 0) - throw std::runtime_error("Invalid SRP parameter from server"); - - BigInt k = hash_seq(hash_id, p_bytes, p, g); - - BigInt a(rng, 256); - - BigInt A = power_mod(g, a, p); - - BigInt u = hash_seq(hash_id, p_bytes, A, B); - - const BigInt x = compute_x(hash_id, identifier, password, salt); - - BigInt S = power_mod((B - (k * power_mod(g, x, p))) % p, (a + (u * x)), p); - - SymmetricKey Sk(BigInt::encode_1363(S, p_bytes)); - - return std::make_pair(A, Sk); - } - -BigInt generate_srp6_verifier(const std::string& identifier, - const std::string& password, - const MemoryRegion& salt, - const std::string& group_id, - const std::string& hash_id) - { - const BigInt x = compute_x(hash_id, identifier, password, salt); - - DL_Group group(group_id); - return power_mod(group.get_g(), x, group.get_p()); - } - -BigInt SRP6_Server_Session::step1(const BigInt& v, - const std::string& group_id, - const std::string& hash_id, - RandomNumberGenerator& rng) - { - DL_Group group(group_id); - const BigInt& g = group.get_g(); - const BigInt& p = group.get_p(); - - p_bytes = p.bytes(); - - BigInt k = hash_seq(hash_id, p_bytes, p, g); - - BigInt b(rng, 256); - - B = (v*k + power_mod(g, b, p)) % p; - - this->v = v; - this->b = b; - this->p = p; - this->hash_id = hash_id; - - return B; - } - -SymmetricKey SRP6_Server_Session::step2(const BigInt& A) - { - if(A % p == 0) - throw std::runtime_error("Invalid SRP parameter from client"); - - BigInt u = hash_seq(hash_id, p_bytes, A, B); - - BigInt S = power_mod(A * power_mod(v, u, p), b, p); - - return BigInt::encode_1363(S, p_bytes); - } - -} -/* -* RTSS (threshold secret sharing) -* (C) 2009 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include - -namespace Botan { - -namespace { - -/** -Table for GF(2^8) arithmetic (exponentials) -*/ -const byte RTSS_EXP[256] = { -0x01, 0x03, 0x05, 0x0F, 0x11, 0x33, 0x55, 0xFF, 0x1A, 0x2E, 0x72, -0x96, 0xA1, 0xF8, 0x13, 0x35, 0x5F, 0xE1, 0x38, 0x48, 0xD8, 0x73, -0x95, 0xA4, 0xF7, 0x02, 0x06, 0x0A, 0x1E, 0x22, 0x66, 0xAA, 0xE5, -0x34, 0x5C, 0xE4, 0x37, 0x59, 0xEB, 0x26, 0x6A, 0xBE, 0xD9, 0x70, -0x90, 0xAB, 0xE6, 0x31, 0x53, 0xF5, 0x04, 0x0C, 0x14, 0x3C, 0x44, -0xCC, 0x4F, 0xD1, 0x68, 0xB8, 0xD3, 0x6E, 0xB2, 0xCD, 0x4C, 0xD4, -0x67, 0xA9, 0xE0, 0x3B, 0x4D, 0xD7, 0x62, 0xA6, 0xF1, 0x08, 0x18, -0x28, 0x78, 0x88, 0x83, 0x9E, 0xB9, 0xD0, 0x6B, 0xBD, 0xDC, 0x7F, -0x81, 0x98, 0xB3, 0xCE, 0x49, 0xDB, 0x76, 0x9A, 0xB5, 0xC4, 0x57, -0xF9, 0x10, 0x30, 0x50, 0xF0, 0x0B, 0x1D, 0x27, 0x69, 0xBB, 0xD6, -0x61, 0xA3, 0xFE, 0x19, 0x2B, 0x7D, 0x87, 0x92, 0xAD, 0xEC, 0x2F, -0x71, 0x93, 0xAE, 0xE9, 0x20, 0x60, 0xA0, 0xFB, 0x16, 0x3A, 0x4E, -0xD2, 0x6D, 0xB7, 0xC2, 0x5D, 0xE7, 0x32, 0x56, 0xFA, 0x15, 0x3F, -0x41, 0xC3, 0x5E, 0xE2, 0x3D, 0x47, 0xC9, 0x40, 0xC0, 0x5B, 0xED, -0x2C, 0x74, 0x9C, 0xBF, 0xDA, 0x75, 0x9F, 0xBA, 0xD5, 0x64, 0xAC, -0xEF, 0x2A, 0x7E, 0x82, 0x9D, 0xBC, 0xDF, 0x7A, 0x8E, 0x89, 0x80, -0x9B, 0xB6, 0xC1, 0x58, 0xE8, 0x23, 0x65, 0xAF, 0xEA, 0x25, 0x6F, -0xB1, 0xC8, 0x43, 0xC5, 0x54, 0xFC, 0x1F, 0x21, 0x63, 0xA5, 0xF4, -0x07, 0x09, 0x1B, 0x2D, 0x77, 0x99, 0xB0, 0xCB, 0x46, 0xCA, 0x45, -0xCF, 0x4A, 0xDE, 0x79, 0x8B, 0x86, 0x91, 0xA8, 0xE3, 0x3E, 0x42, -0xC6, 0x51, 0xF3, 0x0E, 0x12, 0x36, 0x5A, 0xEE, 0x29, 0x7B, 0x8D, -0x8C, 0x8F, 0x8A, 0x85, 0x94, 0xA7, 0xF2, 0x0D, 0x17, 0x39, 0x4B, -0xDD, 0x7C, 0x84, 0x97, 0xA2, 0xFD, 0x1C, 0x24, 0x6C, 0xB4, 0xC7, -0x52, 0xF6, 0x01 }; - -/** -Table for GF(2^8) arithmetic (logarithms) -*/ -const byte RTSS_LOG[] = { -0x90, 0x00, 0x19, 0x01, 0x32, 0x02, 0x1A, 0xC6, 0x4B, 0xC7, 0x1B, -0x68, 0x33, 0xEE, 0xDF, 0x03, 0x64, 0x04, 0xE0, 0x0E, 0x34, 0x8D, -0x81, 0xEF, 0x4C, 0x71, 0x08, 0xC8, 0xF8, 0x69, 0x1C, 0xC1, 0x7D, -0xC2, 0x1D, 0xB5, 0xF9, 0xB9, 0x27, 0x6A, 0x4D, 0xE4, 0xA6, 0x72, -0x9A, 0xC9, 0x09, 0x78, 0x65, 0x2F, 0x8A, 0x05, 0x21, 0x0F, 0xE1, -0x24, 0x12, 0xF0, 0x82, 0x45, 0x35, 0x93, 0xDA, 0x8E, 0x96, 0x8F, -0xDB, 0xBD, 0x36, 0xD0, 0xCE, 0x94, 0x13, 0x5C, 0xD2, 0xF1, 0x40, -0x46, 0x83, 0x38, 0x66, 0xDD, 0xFD, 0x30, 0xBF, 0x06, 0x8B, 0x62, -0xB3, 0x25, 0xE2, 0x98, 0x22, 0x88, 0x91, 0x10, 0x7E, 0x6E, 0x48, -0xC3, 0xA3, 0xB6, 0x1E, 0x42, 0x3A, 0x6B, 0x28, 0x54, 0xFA, 0x85, -0x3D, 0xBA, 0x2B, 0x79, 0x0A, 0x15, 0x9B, 0x9F, 0x5E, 0xCA, 0x4E, -0xD4, 0xAC, 0xE5, 0xF3, 0x73, 0xA7, 0x57, 0xAF, 0x58, 0xA8, 0x50, -0xF4, 0xEA, 0xD6, 0x74, 0x4F, 0xAE, 0xE9, 0xD5, 0xE7, 0xE6, 0xAD, -0xE8, 0x2C, 0xD7, 0x75, 0x7A, 0xEB, 0x16, 0x0B, 0xF5, 0x59, 0xCB, -0x5F, 0xB0, 0x9C, 0xA9, 0x51, 0xA0, 0x7F, 0x0C, 0xF6, 0x6F, 0x17, -0xC4, 0x49, 0xEC, 0xD8, 0x43, 0x1F, 0x2D, 0xA4, 0x76, 0x7B, 0xB7, -0xCC, 0xBB, 0x3E, 0x5A, 0xFB, 0x60, 0xB1, 0x86, 0x3B, 0x52, 0xA1, -0x6C, 0xAA, 0x55, 0x29, 0x9D, 0x97, 0xB2, 0x87, 0x90, 0x61, 0xBE, -0xDC, 0xFC, 0xBC, 0x95, 0xCF, 0xCD, 0x37, 0x3F, 0x5B, 0xD1, 0x53, -0x39, 0x84, 0x3C, 0x41, 0xA2, 0x6D, 0x47, 0x14, 0x2A, 0x9E, 0x5D, -0x56, 0xF2, 0xD3, 0xAB, 0x44, 0x11, 0x92, 0xD9, 0x23, 0x20, 0x2E, -0x89, 0xB4, 0x7C, 0xB8, 0x26, 0x77, 0x99, 0xE3, 0xA5, 0x67, 0x4A, -0xED, 0xDE, 0xC5, 0x31, 0xFE, 0x18, 0x0D, 0x63, 0x8C, 0x80, 0xC0, -0xF7, 0x70, 0x07 }; - -byte gfp_mul(byte x, byte y) - { - if(x == 0 || y == 0) - return 0; - return RTSS_EXP[(RTSS_LOG[x] + RTSS_LOG[y]) % 255]; - } - -byte rtss_hash_id(const std::string& hash_name) - { - if(hash_name == "SHA-160") - return 1; - else if(hash_name == "SHA-256") - return 2; - else - throw Invalid_Argument("RTSS only supports SHA-1 and SHA-256"); - } - -HashFunction* get_rtss_hash_by_id(byte id) - { - if(id == 1) - return new SHA_160; - else if(id == 2) - return new SHA_256; - else - throw Decoding_Error("Bad RTSS hash identifier"); - } - -} - -RTSS_Share::RTSS_Share(const std::string& hex_input) - { - contents = hex_decode(hex_input); - } - -byte RTSS_Share::share_id() const - { - if(!initialized()) - throw Invalid_State("RTSS_Share::share_id not initialized"); - - return contents[20]; - } - -std::string RTSS_Share::to_string() const - { - return hex_encode(&contents[0], contents.size()); - } - -std::vector -RTSS_Share::split(byte M, byte N, - const byte S[], u16bit S_len, - const byte identifier[16], - RandomNumberGenerator& rng) - { - if(M == 0 || N == 0 || M > N) - throw Encoding_Error("RTSS_Share::split: M == 0 or N == 0 or M > N"); - - SHA_256 hash; // always use SHA-256 when generating shares - - std::vector shares(N); - - // Create RTSS header in each share - for(byte i = 0; i != N; ++i) - { - shares[i].contents += std::make_pair(identifier, 16); - shares[i].contents += rtss_hash_id(hash.name()); - shares[i].contents += M; - shares[i].contents += get_byte(0, S_len); - shares[i].contents += get_byte(1, S_len); - } - - // Choose sequential values for X starting from 1 - for(byte i = 0; i != N; ++i) - shares[i].contents.push_back(i+1); - - // secret = S || H(S) - SecureVector secret(S, S_len); - secret += hash.process(S, S_len); - - for(size_t i = 0; i != secret.size(); ++i) - { - std::vector coefficients(M-1); - rng.randomize(&coefficients[0], coefficients.size()); - - for(byte j = 0; j != N; ++j) - { - const byte X = j + 1; - - byte sum = secret[i]; - byte X_i = X; - - for(size_t k = 0; k != coefficients.size(); ++k) - { - sum ^= gfp_mul(X_i, coefficients[k]); - X_i = gfp_mul(X_i, X); - } - - shares[j].contents.push_back(sum); - } - } - - return shares; - } - -SecureVector -RTSS_Share::reconstruct(const std::vector& shares) - { - const size_t RTSS_HEADER_SIZE = 20; - - for(size_t i = 0; i != shares.size(); ++i) - { - if(shares[i].size() != shares[0].size()) - throw Decoding_Error("Different sized RTSS shares detected"); - if(shares[i].share_id() == 0) - throw Decoding_Error("Invalid (id = 0) RTSS share detected"); - if(shares[i].size() < RTSS_HEADER_SIZE) - throw Decoding_Error("Missing or malformed RTSS header"); - - if(!same_mem(&shares[0].contents[0], - &shares[i].contents[0], RTSS_HEADER_SIZE)) - throw Decoding_Error("Different RTSS headers detected"); - } - - if(shares.size() < shares[0].contents[17]) - throw Decoding_Error("Insufficient shares to do TSS reconstruction"); - - u16bit secret_len = make_u16bit(shares[0].contents[18], - shares[0].contents[19]); - - byte hash_id = shares[0].contents[16]; - - std::unique_ptr hash(get_rtss_hash_by_id(hash_id)); - - if(shares[0].size() != secret_len + hash->output_length() + RTSS_HEADER_SIZE + 1) - throw Decoding_Error("Bad RTSS length field in header"); - - std::vector V(shares.size()); - SecureVector secret; - - for(size_t i = RTSS_HEADER_SIZE + 1; i != shares[0].size(); ++i) - { - for(size_t j = 0; j != V.size(); ++j) - V[j] = shares[j].contents[i]; - - byte r = 0; - for(size_t k = 0; k != shares.size(); ++k) - { - // L_i function: - byte r2 = 1; - for(size_t l = 0; l != shares.size(); ++l) - { - if(k == l) - continue; - - byte share_k = shares[k].share_id(); - byte share_l = shares[l].share_id(); - - if(share_k == share_l) - throw Decoding_Error("Duplicate shares found in RTSS recovery"); - - byte div = RTSS_EXP[(255 + - RTSS_LOG[share_l] - - RTSS_LOG[share_k ^ share_l]) % 255]; - - r2 = gfp_mul(r2, div); - } - - r ^= gfp_mul(V[k], r2); - } - secret.push_back(r); - } - - if(secret.size() != secret_len + hash->output_length()) - throw Decoding_Error("Bad length in RTSS output"); - - hash->update(&secret[0], secret_len); - SecureVector hash_check = hash->final(); - - if(!same_mem(&hash_check[0], - &secret[secret_len], hash->output_length())) - throw Decoding_Error("RTSS hash check failed"); - - return SecureVector(&secret[0], secret_len); - } - -} -/* -* Core Engine -* (C) 1999-2007,2011 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include - -#if defined(BOTAN_HAS_ECB) -#endif - -#if defined(BOTAN_HAS_CBC) -#endif - -#if defined(BOTAN_HAS_CTS) -#endif - -#if defined(BOTAN_HAS_CFB) -#endif - -#if defined(BOTAN_HAS_OFB) -#endif - -#if defined(BOTAN_HAS_CTR_BE) -#endif - -#if defined(BOTAN_HAS_EAX) -#endif - -#if defined(BOTAN_HAS_XTS) -#endif - -namespace Botan { - -namespace { - -/** -* Get a block cipher padding method by name -*/ -BlockCipherModePaddingMethod* get_bc_pad(const std::string& algo_spec, - const std::string& def_if_empty) - { -#if defined(BOTAN_HAS_CIPHER_MODE_PADDING) - if(algo_spec == "NoPadding" || (algo_spec == "" && def_if_empty == "NoPadding")) - return new Null_Padding; - - if(algo_spec == "PKCS7" || (algo_spec == "" && def_if_empty == "PKCS7")) - return new PKCS7_Padding; - - if(algo_spec == "OneAndZeros") - return new OneAndZeros_Padding; - - if(algo_spec == "X9.23") - return new ANSI_X923_Padding; - -#endif - - throw Algorithm_Not_Found(algo_spec); - } - -} - -Keyed_Filter* get_cipher_mode(const BlockCipher* block_cipher, - Cipher_Dir direction, - const std::string& mode, - const std::string& padding) - { -#if defined(BOTAN_HAS_OFB) - if(mode == "OFB") - return new StreamCipher_Filter(new OFB(block_cipher->clone())); -#endif - -#if defined(BOTAN_HAS_CTR_BE) - if(mode == "CTR-BE") - return new StreamCipher_Filter(new CTR_BE(block_cipher->clone())); -#endif - -#if defined(BOTAN_HAS_ECB) - if(mode == "ECB" || mode == "") - { - if(direction == ENCRYPTION) - return new ECB_Encryption(block_cipher->clone(), - get_bc_pad(padding, "NoPadding")); - else - return new ECB_Decryption(block_cipher->clone(), - get_bc_pad(padding, "NoPadding")); - } -#endif - - if(mode == "CBC") - { - if(padding == "CTS") - { -#if defined(BOTAN_HAS_CTS) - if(direction == ENCRYPTION) - return new CTS_Encryption(block_cipher->clone()); - else - return new CTS_Decryption(block_cipher->clone()); -#else - return 0; -#endif - } - -#if defined(BOTAN_HAS_CBC) - if(direction == ENCRYPTION) - return new CBC_Encryption(block_cipher->clone(), - get_bc_pad(padding, "PKCS7")); - else - return new CBC_Decryption(block_cipher->clone(), - get_bc_pad(padding, "PKCS7")); -#else - return 0; -#endif - } - -#if defined(BOTAN_HAS_XTS) - if(mode == "XTS") - { - if(direction == ENCRYPTION) - return new XTS_Encryption(block_cipher->clone()); - else - return new XTS_Decryption(block_cipher->clone()); - } -#endif - - if(mode.find("CFB") != std::string::npos || - mode.find("EAX") != std::string::npos) - { - size_t bits = 0; - - std::vector algo_info = parse_algorithm_name(mode); - std::string mode_name = algo_info[0]; - if(algo_info.size() == 1) - bits = 8 * block_cipher->block_size(); - else if(algo_info.size() == 2) - bits = to_u32bit(algo_info[1]); - else - return 0; - -#if defined(BOTAN_HAS_CFB) - if(mode_name == "CFB") - { - if(direction == ENCRYPTION) - return new CFB_Encryption(block_cipher->clone(), bits); - else - return new CFB_Decryption(block_cipher->clone(), bits); - } -#endif - -#if defined(BOTAN_HAS_EAX) - if(mode_name == "EAX") - { - if(direction == ENCRYPTION) - return new EAX_Encryption(block_cipher->clone(), bits); - else - return new EAX_Decryption(block_cipher->clone(), bits); - } -#endif - } - - return 0; - } - -/* -* Get a cipher object -*/ -Keyed_Filter* Core_Engine::get_cipher(const std::string& algo_spec, - Cipher_Dir direction, - Algorithm_Factory& af) - { - std::vector algo_parts = split_on(algo_spec, '/'); - if(algo_parts.empty()) - throw Invalid_Algorithm_Name(algo_spec); - - const std::string cipher_name = algo_parts[0]; - - // check if it is a stream cipher first (easy case) - const StreamCipher* stream_cipher = af.prototype_stream_cipher(cipher_name); - if(stream_cipher) - return new StreamCipher_Filter(stream_cipher->clone()); - - const BlockCipher* block_cipher = af.prototype_block_cipher(cipher_name); - if(!block_cipher) - return 0; - - if(algo_parts.size() >= 4) - return 0; // 4 part mode, not something we know about - - if(algo_parts.size() < 2) - throw Lookup_Error("Cipher specification '" + algo_spec + - "' is missing mode identifier"); - - std::string mode = algo_parts[1]; - - std::string padding; - if(algo_parts.size() == 3) - padding = algo_parts[2]; - else - padding = (mode == "CBC") ? "PKCS7" : "NoPadding"; - - if(mode == "ECB" && padding == "CTS") - return 0; - else if((mode != "CBC" && mode != "ECB") && padding != "NoPadding") - throw Invalid_Algorithm_Name(algo_spec); - - Keyed_Filter* filt = get_cipher_mode(block_cipher, direction, mode, padding); - if(filt) - return filt; - - throw Algorithm_Not_Found(cipher_name + "/" + mode + "/" + padding); - } - -} -/* -* PK Operations -* (C) 1999-2010 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -#if defined(BOTAN_HAS_RSA) -#endif - -#if defined(BOTAN_HAS_RW) -#endif - -#if defined(BOTAN_HAS_DSA) -#endif - -#if defined(BOTAN_HAS_ECDSA) -#endif - -#if defined(BOTAN_HAS_ELGAMAL) -#endif - -#if defined(BOTAN_HAS_GOST_34_10_2001) -#endif - -#if defined(BOTAN_HAS_NYBERG_RUEPPEL) -#endif - -#if defined(BOTAN_HAS_DIFFIE_HELLMAN) -#endif - -#if defined(BOTAN_HAS_ECDH) -#endif - -namespace Botan { - -PK_Ops::Encryption* -Core_Engine::get_encryption_op(const Public_Key& key) const - { -#if defined(BOTAN_HAS_RSA) - if(const RSA_PublicKey* s = dynamic_cast(&key)) - return new RSA_Public_Operation(*s); -#endif - -#if defined(BOTAN_HAS_ELGAMAL) - if(const ElGamal_PublicKey* s = dynamic_cast(&key)) - return new ElGamal_Encryption_Operation(*s); -#endif - - return 0; - } - -PK_Ops::Decryption* -Core_Engine::get_decryption_op(const Private_Key& key) const - { -#if defined(BOTAN_HAS_RSA) - if(const RSA_PrivateKey* s = dynamic_cast(&key)) - return new RSA_Private_Operation(*s); -#endif - -#if defined(BOTAN_HAS_ELGAMAL) - if(const ElGamal_PrivateKey* s = dynamic_cast(&key)) - return new ElGamal_Decryption_Operation(*s); -#endif - - return 0; - } - -PK_Ops::Key_Agreement* -Core_Engine::get_key_agreement_op(const Private_Key& key) const - { -#if defined(BOTAN_HAS_DIFFIE_HELLMAN) - if(const DH_PrivateKey* dh = dynamic_cast(&key)) - return new DH_KA_Operation(*dh); -#endif - -#if defined(BOTAN_HAS_ECDH) - if(const ECDH_PrivateKey* ecdh = dynamic_cast(&key)) - return new ECDH_KA_Operation(*ecdh); -#endif - - return 0; - } - -PK_Ops::Signature* -Core_Engine::get_signature_op(const Private_Key& key) const - { -#if defined(BOTAN_HAS_RSA) - if(const RSA_PrivateKey* s = dynamic_cast(&key)) - return new RSA_Private_Operation(*s); -#endif - -#if defined(BOTAN_HAS_RW) - if(const RW_PrivateKey* s = dynamic_cast(&key)) - return new RW_Signature_Operation(*s); -#endif - -#if defined(BOTAN_HAS_DSA) - if(const DSA_PrivateKey* s = dynamic_cast(&key)) - return new DSA_Signature_Operation(*s); -#endif - -#if defined(BOTAN_HAS_ECDSA) - if(const ECDSA_PrivateKey* s = dynamic_cast(&key)) - return new ECDSA_Signature_Operation(*s); -#endif - -#if defined(BOTAN_HAS_GOST_34_10_2001) - if(const GOST_3410_PrivateKey* s = - dynamic_cast(&key)) - return new GOST_3410_Signature_Operation(*s); -#endif - -#if defined(BOTAN_HAS_NYBERG_RUEPPEL) - if(const NR_PrivateKey* s = dynamic_cast(&key)) - return new NR_Signature_Operation(*s); -#endif - - return 0; - } - -PK_Ops::Verification* -Core_Engine::get_verify_op(const Public_Key& key) const - { -#if defined(BOTAN_HAS_RSA) - if(const RSA_PublicKey* s = dynamic_cast(&key)) - return new RSA_Public_Operation(*s); -#endif - -#if defined(BOTAN_HAS_RW) - if(const RW_PublicKey* s = dynamic_cast(&key)) - return new RW_Verification_Operation(*s); -#endif - -#if defined(BOTAN_HAS_DSA) - if(const DSA_PublicKey* s = dynamic_cast(&key)) - return new DSA_Verification_Operation(*s); -#endif - -#if defined(BOTAN_HAS_ECDSA) - if(const ECDSA_PublicKey* s = dynamic_cast(&key)) - return new ECDSA_Verification_Operation(*s); -#endif - -#if defined(BOTAN_HAS_GOST_34_10_2001) - if(const GOST_3410_PublicKey* s = - dynamic_cast(&key)) - return new GOST_3410_Verification_Operation(*s); -#endif - -#if defined(BOTAN_HAS_NYBERG_RUEPPEL) - if(const NR_PublicKey* s = dynamic_cast(&key)) - return new NR_Verification_Operation(*s); -#endif - - return 0; - } - -} -/* -* Modular Exponentiation -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -/* -* Choose a modular exponentation algorithm -*/ -Modular_Exponentiator* -Core_Engine::mod_exp(const BigInt& n, Power_Mod::Usage_Hints hints) const - { - if(n.is_odd()) - return new Montgomery_Exponentiator(n, hints); - return new Fixed_Window_Exponentiator(n, hints); - } - -} -/* -* Block Cipher Lookup -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -#if defined(BOTAN_HAS_AES) -#endif - -#if defined(BOTAN_HAS_BLOWFISH) -#endif - -#if defined(BOTAN_HAS_CAMELLIA) -#endif - -#if defined(BOTAN_HAS_CAST) -#endif - -#if defined(BOTAN_HAS_CASCADE) -#endif - -#if defined(BOTAN_HAS_DES) -#endif - -#if defined(BOTAN_HAS_GOST_28147_89) -#endif - -#if defined(BOTAN_HAS_IDEA) -#endif - -#if defined(BOTAN_HAS_KASUMI) -#endif - -#if defined(BOTAN_HAS_LION) -#endif - -#if defined(BOTAN_HAS_LUBY_RACKOFF) -#endif - -#if defined(BOTAN_HAS_MARS) -#endif - -#if defined(BOTAN_HAS_MISTY1) -#endif - -#if defined(BOTAN_HAS_NOEKEON) -#endif - -#if defined(BOTAN_HAS_RC2) -#endif - -#if defined(BOTAN_HAS_RC5) -#endif - -#if defined(BOTAN_HAS_RC6) -#endif - -#if defined(BOTAN_HAS_SAFER) -#endif - -#if defined(BOTAN_HAS_SEED) -#endif - -#if defined(BOTAN_HAS_SERPENT) -#endif - -#if defined(BOTAN_HAS_SKIPJACK) -#endif - -#if defined(BOTAN_HAS_SQUARE) -#endif - -#if defined(BOTAN_HAS_TEA) -#endif - -#if defined(BOTAN_HAS_TWOFISH) -#endif - -#if defined(BOTAN_HAS_XTEA) -#endif - -namespace Botan { - -/* -* Look for an algorithm with this name -*/ -BlockCipher* Core_Engine::find_block_cipher(const SCAN_Name& request, - Algorithm_Factory& af) const - { - -#if defined(BOTAN_HAS_AES) - if(request.algo_name() == "AES-128") - return new AES_128; - if(request.algo_name() == "AES-192") - return new AES_192; - if(request.algo_name() == "AES-256") - return new AES_256; -#endif - -#if defined(BOTAN_HAS_BLOWFISH) - if(request.algo_name() == "Blowfish") - return new Blowfish; -#endif - -#if defined(BOTAN_HAS_CAMELLIA) - if(request.algo_name() == "Camellia-128") - return new Camellia_128; - if(request.algo_name() == "Camellia-192") - return new Camellia_192; - if(request.algo_name() == "Camellia-256") - return new Camellia_256; -#endif - -#if defined(BOTAN_HAS_CAST) - if(request.algo_name() == "CAST-128") - return new CAST_128; - if(request.algo_name() == "CAST-256") - return new CAST_256; -#endif - -#if defined(BOTAN_HAS_DES) - if(request.algo_name() == "DES") - return new DES; - if(request.algo_name() == "DESX") - return new DESX; - if(request.algo_name() == "TripleDES") - return new TripleDES; -#endif - -#if defined(BOTAN_HAS_GOST_28147_89) - if(request.algo_name() == "GOST-28147-89") - return new GOST_28147_89(request.arg(0, "R3411_94_TestParam")); -#endif - -#if defined(BOTAN_HAS_IDEA) - if(request.algo_name() == "IDEA") - return new IDEA; -#endif - -#if defined(BOTAN_HAS_KASUMI) - if(request.algo_name() == "KASUMI") - return new KASUMI; -#endif - -#if defined(BOTAN_HAS_MARS) - if(request.algo_name() == "MARS") - return new MARS; -#endif - -#if defined(BOTAN_HAS_MISTY1) - if(request.algo_name() == "MISTY1") - return new MISTY1(request.arg_as_integer(0, 8)); -#endif - -#if defined(BOTAN_HAS_NOEKEON) - if(request.algo_name() == "Noekeon") - return new Noekeon; -#endif - -#if defined(BOTAN_HAS_RC2) - if(request.algo_name() == "RC2") - return new RC2; -#endif - -#if defined(BOTAN_HAS_RC5) - if(request.algo_name() == "RC5") - return new RC5(request.arg_as_integer(0, 12)); -#endif - -#if defined(BOTAN_HAS_RC6) - if(request.algo_name() == "RC6") - return new RC6; -#endif - -#if defined(BOTAN_HAS_SAFER) - if(request.algo_name() == "SAFER-SK") - return new SAFER_SK(request.arg_as_integer(0, 10)); -#endif - -#if defined(BOTAN_HAS_SEED) - if(request.algo_name() == "SEED") - return new SEED; -#endif - -#if defined(BOTAN_HAS_SERPENT) - if(request.algo_name() == "Serpent") - return new Serpent; -#endif - -#if defined(BOTAN_HAS_SKIPJACK) - if(request.algo_name() == "Skipjack") - return new Skipjack; -#endif - -#if defined(BOTAN_HAS_SQUARE) - if(request.algo_name() == "Square") - return new Square; -#endif - -#if defined(BOTAN_HAS_TEA) - if(request.algo_name() == "TEA") - return new TEA; -#endif - -#if defined(BOTAN_HAS_TWOFISH) - if(request.algo_name() == "Twofish") - return new Twofish; -#endif - -#if defined(BOTAN_HAS_XTEA) - if(request.algo_name() == "XTEA") - return new XTEA; -#endif - -#if defined(BOTAN_HAS_LUBY_RACKOFF) - if(request.algo_name() == "Luby-Rackoff" && request.arg_count() == 1) - { - const HashFunction* hash = af.prototype_hash_function(request.arg(0)); - - if(hash) - return new LubyRackoff(hash->clone()); - } -#endif - -#if defined(BOTAN_HAS_CASCADE) - if(request.algo_name() == "Cascade" && request.arg_count() == 2) - { - const BlockCipher* c1 = af.prototype_block_cipher(request.arg(0)); - const BlockCipher* c2 = af.prototype_block_cipher(request.arg(1)); - - if(c1 && c2) - return new Cascade_Cipher(c1->clone(), c2->clone()); - } -#endif - -#if defined(BOTAN_HAS_LION) - if(request.algo_name() == "Lion" && request.arg_count_between(2, 3)) - { - const size_t block_size = request.arg_as_integer(2, 1024); - - const HashFunction* hash = - af.prototype_hash_function(request.arg(0)); - - const StreamCipher* stream_cipher = - af.prototype_stream_cipher(request.arg(1)); - - if(!hash || !stream_cipher) - return 0; - - return new Lion(hash->clone(), stream_cipher->clone(), block_size); - } -#endif - - return 0; - } - -} -/* -* Hash Algorithms Lookup -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include - -#if defined(BOTAN_HAS_ADLER32) -#endif - -#if defined(BOTAN_HAS_CRC24) -#endif - -#if defined(BOTAN_HAS_CRC32) -#endif - -#if defined(BOTAN_HAS_BMW_512) -#endif - -#if defined(BOTAN_HAS_GOST_34_11) -#endif - -#if defined(BOTAN_HAS_HAS_160) -#endif - -#if defined(BOTAN_HAS_KECCAK) -#endif - -#if defined(BOTAN_HAS_MD2) -#endif - -#if defined(BOTAN_HAS_MD4) -#endif - -#if defined(BOTAN_HAS_MD5) -#endif - -#if defined(BOTAN_HAS_RIPEMD_128) -#endif - -#if defined(BOTAN_HAS_RIPEMD_160) -#endif - -#if defined(BOTAN_HAS_SHA1) -#endif - -#if defined(BOTAN_HAS_SHA2_32) -#endif - -#if defined(BOTAN_HAS_SHA2_64) -#endif - -#if defined(BOTAN_HAS_SKEIN_512) -#endif - -#if defined(BOTAN_HAS_TIGER) -#endif - -#if defined(BOTAN_HAS_WHIRLPOOL) -#endif - -#if defined(BOTAN_HAS_PARALLEL_HASH) -#endif - -#if defined(BOTAN_HAS_COMB4P) -#endif - -namespace Botan { - -/* -* Look for an algorithm with this name -*/ -HashFunction* Core_Engine::find_hash(const SCAN_Name& request, - Algorithm_Factory& af) const - { -#if defined(BOTAN_HAS_ADLER32) - if(request.algo_name() == "Adler32") - return new Adler32; -#endif - -#if defined(BOTAN_HAS_CRC24) - if(request.algo_name() == "CRC24") - return new CRC24; -#endif - -#if defined(BOTAN_HAS_CRC32) - if(request.algo_name() == "CRC32") - return new CRC32; -#endif - -#if defined(BOTAN_HAS_BMW_512) - if(request.algo_name() == "BMW-512") - return new BMW_512; -#endif - -#if defined(BOTAN_HAS_GOST_34_11) - if(request.algo_name() == "GOST-34.11") - return new GOST_34_11; -#endif - -#if defined(BOTAN_HAS_HAS_160) - if(request.algo_name() == "HAS-160") - return new HAS_160; -#endif - -#if defined(BOTAN_HAS_KECCAK) - if(request.algo_name() == "Keccak-1600") - return new Keccak_1600(request.arg_as_integer(0, 512)); -#endif - -#if defined(BOTAN_HAS_MD2) - if(request.algo_name() == "MD2") - return new MD2; -#endif - -#if defined(BOTAN_HAS_MD4) - if(request.algo_name() == "MD4") - return new MD4; -#endif - -#if defined(BOTAN_HAS_MD5) - if(request.algo_name() == "MD5") - return new MD5; -#endif - -#if defined(BOTAN_HAS_RIPEMD_128) - if(request.algo_name() == "RIPEMD-128") - return new RIPEMD_128; -#endif - -#if defined(BOTAN_HAS_RIPEMD_160) - if(request.algo_name() == "RIPEMD-160") - return new RIPEMD_160; -#endif - -#if defined(BOTAN_HAS_SHA1) - if(request.algo_name() == "SHA-160") - return new SHA_160; -#endif - -#if defined(BOTAN_HAS_SHA2_32) - if(request.algo_name() == "SHA-224") - return new SHA_224; - if(request.algo_name() == "SHA-256") - return new SHA_256; -#endif - -#if defined(BOTAN_HAS_SHA2_64) - if(request.algo_name() == "SHA-384") - return new SHA_384; - if(request.algo_name() == "SHA-512") - return new SHA_512; -#endif - -#if defined(BOTAN_HAS_TIGER) - if(request.algo_name() == "Tiger") - return new Tiger(request.arg_as_integer(0, 24), // hash output - request.arg_as_integer(1, 3)); // # passes -#endif - -#if defined(BOTAN_HAS_SKEIN_512) - if(request.algo_name() == "Skein-512") - return new Skein_512(request.arg_as_integer(0, 512), - request.arg(1, "")); -#endif - -#if defined(BOTAN_HAS_WHIRLPOOL) - if(request.algo_name() == "Whirlpool") - return new Whirlpool; -#endif - -#if defined(BOTAN_HAS_COMB4P) - if(request.algo_name() == "Comb4P" && request.arg_count() == 2) - { - const HashFunction* h1 = af.prototype_hash_function(request.arg(0)); - const HashFunction* h2 = af.prototype_hash_function(request.arg(1)); - - if(h1 && h2) - return new Comb4P(h1->clone(), h2->clone()); - } -#endif - -#if defined(BOTAN_HAS_PARALLEL_HASH) - - if(request.algo_name() == "Parallel") - { - std::vector hash_prototypes; - - /* First pass, just get the prototypes (no memory allocation). Then - if all were found, replace each prototype with a newly created clone - */ - for(size_t i = 0; i != request.arg_count(); ++i) - { - const HashFunction* hash = af.prototype_hash_function(request.arg(i)); - if(!hash) - return 0; - - hash_prototypes.push_back(hash); - } - - std::vector hashes; - for(size_t i = 0; i != hash_prototypes.size(); ++i) - hashes.push_back(hash_prototypes[i]->clone()); - - return new Parallel(hashes); - } - -#endif - - return 0; - } - -} -/* -* MAC Lookup -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -#if defined(BOTAN_HAS_CBC_MAC) -#endif - -#if defined(BOTAN_HAS_CMAC) -#endif - -#if defined(BOTAN_HAS_HMAC) -#endif - -#if defined(BOTAN_HAS_SSL3_MAC) -#endif - -#if defined(BOTAN_HAS_ANSI_X919_MAC) -#endif - -namespace Botan { - -/* -* Look for an algorithm with this name -*/ -MessageAuthenticationCode* -Core_Engine::find_mac(const SCAN_Name& request, - Algorithm_Factory& af) const - { - -#if defined(BOTAN_HAS_CBC_MAC) - if(request.algo_name() == "CBC-MAC" && request.arg_count() == 1) - return new CBC_MAC(af.make_block_cipher(request.arg(0))); -#endif - -#if defined(BOTAN_HAS_CMAC) - if(request.algo_name() == "CMAC" && request.arg_count() == 1) - return new CMAC(af.make_block_cipher(request.arg(0))); -#endif - -#if defined(BOTAN_HAS_HMAC) - if(request.algo_name() == "HMAC" && request.arg_count() == 1) - return new HMAC(af.make_hash_function(request.arg(0))); -#endif - -#if defined(BOTAN_HAS_SSL3_MAC) - if(request.algo_name() == "SSL3-MAC" && request.arg_count() == 1) - return new SSL3_MAC(af.make_hash_function(request.arg(0))); -#endif - -#if defined(BOTAN_HAS_ANSI_X919_MAC) - if(request.algo_name() == "X9.19-MAC" && request.arg_count() == 0) - return new ANSI_X919_MAC(af.make_block_cipher("DES")); -#endif - - return 0; - } - -} -/* -* PBKDF Lookup -* (C) 2010 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -#if defined(BOTAN_HAS_PBKDF1) -#endif - -#if defined(BOTAN_HAS_PBKDF2) -#endif - -#if defined(BOTAN_HAS_PGPS2K) -#endif - -namespace Botan { - -PBKDF* Core_Engine::find_pbkdf(const SCAN_Name& algo_spec, - Algorithm_Factory& af) const - { -#if defined(BOTAN_HAS_PBKDF1) - if(algo_spec.algo_name() == "PBKDF1" && algo_spec.arg_count() == 1) - return new PKCS5_PBKDF1(af.make_hash_function(algo_spec.arg(0))); -#endif - -#if defined(BOTAN_HAS_PBKDF2) - if(algo_spec.algo_name() == "PBKDF2" && algo_spec.arg_count() == 1) - { - if(const MessageAuthenticationCode* mac_proto = af.prototype_mac(algo_spec.arg(0))) - return new PKCS5_PBKDF2(mac_proto->clone()); - - return new PKCS5_PBKDF2(af.make_mac("HMAC(" + algo_spec.arg(0) + ")")); - } -#endif - -#if defined(BOTAN_HAS_PGPS2K) - if(algo_spec.algo_name() == "OpenPGP-S2K" && algo_spec.arg_count() == 1) - return new OpenPGP_S2K(af.make_hash_function(algo_spec.arg(0))); -#endif - - return 0; - } - -} -/* -* Stream Cipher Lookup -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -#if defined(BOTAN_HAS_ARC4) -#endif - -#if defined(BOTAN_HAS_SALSA20) -#endif - -#if defined(BOTAN_HAS_TURING) -#endif - -#if defined(BOTAN_HAS_WID_WAKE) -#endif - -namespace Botan { - -/* -* Look for an algorithm with this name -*/ -StreamCipher* -Core_Engine::find_stream_cipher(const SCAN_Name& request, - Algorithm_Factory&) const - { -#if defined(BOTAN_HAS_ARC4) - if(request.algo_name() == "ARC4") - return new ARC4(request.arg_as_integer(0, 0)); - if(request.algo_name() == "RC4_drop") - return new ARC4(768); -#endif - -#if defined(BOTAN_HAS_SALSA20) - if(request.algo_name() == "Salsa20") - return new Salsa20; -#endif - -#if defined(BOTAN_HAS_TURING) - if(request.algo_name() == "Turing") - return new Turing; -#endif - -#if defined(BOTAN_HAS_WID_WAKE) - if(request.algo_name() == "WiderWake4+1-BE") - return new WiderWake_41_BE; -#endif - - return 0; - } - -} -/** -* Dynamically Loaded Engine -* (C) 2010 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -namespace { - -extern "C" { - typedef Engine* (*creator_func)(void); - typedef u32bit (*module_version_func)(void); -} - -} - -Dynamically_Loaded_Engine::Dynamically_Loaded_Engine( - const std::string& library_path) : - engine(0) - { - lib = new Dynamically_Loaded_Library(library_path); - - try - { - module_version_func get_version = - lib->resolve("module_version"); - - const u32bit mod_version = get_version(); - - if(mod_version != 20101003) - throw std::runtime_error("Incompatible version in " + - library_path + " of " + - to_string(mod_version)); - - creator_func creator = - lib->resolve("create_engine"); - - engine = creator(); - - if(!engine) - throw std::runtime_error("Creator function in " + - library_path + " failed"); - } - catch(...) - { - delete lib; - lib = 0; - throw; - } - } - -Dynamically_Loaded_Engine::~Dynamically_Loaded_Engine() - { - delete engine; - delete lib; - } - -} -/* -* Engine -* (C) 2010 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -BlockCipher* -Engine::find_block_cipher(const SCAN_Name&, - Algorithm_Factory&) const - { - return 0; - } - -StreamCipher* -Engine::find_stream_cipher(const SCAN_Name&, - Algorithm_Factory&) const - { - return 0; - } - -HashFunction* -Engine::find_hash(const SCAN_Name&, - Algorithm_Factory&) const - { - return 0; - } - -MessageAuthenticationCode* -Engine::find_mac(const SCAN_Name&, - Algorithm_Factory&) const - { - return 0; - } - -PBKDF* -Engine::find_pbkdf(const SCAN_Name&, - Algorithm_Factory&) const - { - return 0; - } - -Modular_Exponentiator* -Engine::mod_exp(const BigInt&, - Power_Mod::Usage_Hints) const - { - return 0; - } - -Keyed_Filter* Engine::get_cipher(const std::string&, - Cipher_Dir, - Algorithm_Factory&) - { - return 0; - } - -PK_Ops::Key_Agreement* -Engine::get_key_agreement_op(const Private_Key&) const - { - return 0; - } - -PK_Ops::Signature* -Engine::get_signature_op(const Private_Key&) const - { - return 0; - } - -PK_Ops::Verification* -Engine::get_verify_op(const Public_Key&) const - { - return 0; - } - -PK_Ops::Encryption* -Engine::get_encryption_op(const Public_Key&) const - { - return 0; - } - -PK_Ops::Decryption* -Engine::get_decryption_op(const Private_Key&) const - { - return 0; - } - -} -/* -* SIMD Engine -* (C) 1999-2009 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -#if defined(BOTAN_HAS_AES_SSSE3) -#endif - -#if defined(BOTAN_HAS_SERPENT_SIMD) -#endif - -#if defined(BOTAN_HAS_NOEKEON_SIMD) -#endif - -#if defined(BOTAN_HAS_XTEA_SIMD) -#endif - -#if defined(BOTAN_HAS_IDEA_SSE2) -#endif - -#if defined(BOTAN_HAS_SHA1_SSE2) -#endif - -namespace Botan { - -BlockCipher* -SIMD_Engine::find_block_cipher(const SCAN_Name& request, - Algorithm_Factory&) const - { -#if defined(BOTAN_HAS_AES_SSSE3) - if(request.algo_name() == "AES-128" && CPUID::has_ssse3()) - return new AES_128_SSSE3; - if(request.algo_name() == "AES-192" && CPUID::has_ssse3()) - return new AES_192_SSSE3; - if(request.algo_name() == "AES-256" && CPUID::has_ssse3()) - return new AES_256_SSSE3; -#endif - -#if defined(BOTAN_HAS_IDEA_SSE2) - if(request.algo_name() == "IDEA" && CPUID::has_sse2()) - return new IDEA_SSE2; -#endif - -#if defined(BOTAN_HAS_NOEKEON_SIMD) - if(request.algo_name() == "Noekeon" && SIMD_32::enabled()) - return new Noekeon_SIMD; -#endif - -#if defined(BOTAN_HAS_SERPENT_SIMD) - if(request.algo_name() == "Serpent" && SIMD_32::enabled()) - return new Serpent_SIMD; -#endif - -#if defined(BOTAN_HAS_XTEA_SIMD) - if(request.algo_name() == "XTEA" && SIMD_32::enabled()) - return new XTEA_SIMD; -#endif - - return 0; - } - -HashFunction* -SIMD_Engine::find_hash(const SCAN_Name& request, - Algorithm_Factory&) const - { -#if defined(BOTAN_HAS_SHA1_SSE2) - if(request.algo_name() == "SHA-160" && CPUID::has_sse2()) - return new SHA_160_SSE2; -#else - Q_UNUSED(request); -#endif - - return 0; - } - -} - -#ifdef Q_OS_WIN -/* -* Win32 CryptoAPI EntropySource -* (C) 1999-2009 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include -#include - -namespace Botan { - -namespace { - -class CSP_Handle - { - public: - CSP_Handle(u64bit capi_provider) - { - valid = false; - DWORD prov_type = (DWORD)capi_provider; - - if(CryptAcquireContext(&handle, 0, 0, - prov_type, CRYPT_VERIFYCONTEXT)) - valid = true; - } - - ~CSP_Handle() - { - if(is_valid()) - CryptReleaseContext(handle, 0); - } - - size_t gen_random(byte out[], size_t n) const - { - if(is_valid() && CryptGenRandom(handle, static_cast(n), out)) - return n; - return 0; - } - - bool is_valid() const { return valid; } - - HCRYPTPROV get_handle() const { return handle; } - private: - HCRYPTPROV handle; - bool valid; - }; - -} - -/* -* Gather Entropy from Win32 CAPI -*/ -void Win32_CAPI_EntropySource::poll(Entropy_Accumulator& accum) - { - MemoryRegion& io_buffer = accum.get_io_buffer(32); - - for(size_t i = 0; i != prov_types.size(); ++i) - { - CSP_Handle csp(prov_types[i]); - - size_t got = csp.gen_random(&io_buffer[0], io_buffer.size()); - - if(got) - { - accum.add(&io_buffer[0], io_buffer.size(), 6); - break; - } - } - } - -/* -* Win32_Capi_Entropysource Constructor -*/ -Win32_CAPI_EntropySource::Win32_CAPI_EntropySource(const std::string& provs) - { - std::vector capi_provs = split_on(provs, ':'); - - for(size_t i = 0; i != capi_provs.size(); ++i) - { - if(capi_provs[i] == "RSA_FULL") prov_types.push_back(PROV_RSA_FULL); - if(capi_provs[i] == "INTEL_SEC") prov_types.push_back(PROV_INTEL_SEC); - if(capi_provs[i] == "FORTEZZA") prov_types.push_back(PROV_FORTEZZA); - if(capi_provs[i] == "RNG") prov_types.push_back(PROV_RNG); - } - - if(prov_types.size() == 0) - prov_types.push_back(PROV_RSA_FULL); - } - -} -#endif - -#ifdef Q_OS_UNIX -/* -* /dev/random EntropySource -* (C) 1999-2009 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -#include -#include -#include -#include -#include -#include - -namespace Botan { - -/** -Close the device, if open -*/ -void Device_EntropySource::Device_Reader::close() - { - if(fd >= 0) { ::close(fd); fd = -1; } - } - -/** -Read bytes from a device file -*/ -size_t Device_EntropySource::Device_Reader::get(byte out[], size_t length, - size_t ms_wait_time) - { - if(fd < 0) - return 0; - - if(fd >= FD_SETSIZE) - return 0; - - fd_set read_set; - FD_ZERO(&read_set); - FD_SET(fd, &read_set); - - struct ::timeval timeout; - - timeout.tv_sec = (ms_wait_time / 1000); - timeout.tv_usec = (ms_wait_time % 1000) * 1000; - - if(::select(fd + 1, &read_set, 0, 0, &timeout) < 0) - return 0; - - if(!(FD_ISSET(fd, &read_set))) - return 0; - - const ssize_t got = ::read(fd, out, length); - if(got <= 0) - return 0; - - return static_cast(got); - } - -/** -Attempt to open a device -*/ -Device_EntropySource::Device_Reader::fd_type -Device_EntropySource::Device_Reader::open(const std::string& pathname) - { -#ifndef O_NONBLOCK - #define O_NONBLOCK 0 -#endif - -#ifndef O_NOCTTY - #define O_NOCTTY 0 -#endif - - const int flags = O_RDONLY | O_NONBLOCK | O_NOCTTY; - return ::open(pathname.c_str(), flags); - } - -/** -Device_EntropySource constructor -Open a file descriptor to each (available) device in fsnames -*/ -Device_EntropySource::Device_EntropySource( - const std::vector& fsnames) - { - for(size_t i = 0; i != fsnames.size(); ++i) - { - Device_Reader::fd_type fd = Device_Reader::open(fsnames[i]); - if(fd >= 0) - devices.push_back(Device_Reader(fd)); - } - } - -/** -Device_EntropySource destructor: close all open devices -*/ -Device_EntropySource::~Device_EntropySource() - { - for(size_t i = 0; i != devices.size(); ++i) - devices[i].close(); - } - -/** -* Gather entropy from a RNG device -*/ -void Device_EntropySource::poll(Entropy_Accumulator& accum) - { - const size_t ENTROPY_BITS_PER_BYTE = 7; - - const size_t go_get = std::min( - accum.desired_remaining_bits() / ENTROPY_BITS_PER_BYTE, 32); - - const size_t read_wait_ms = std::max(go_get, 100); - MemoryRegion& io_buffer = accum.get_io_buffer(go_get); - - for(size_t i = 0; i != devices.size(); ++i) - { - size_t got = devices[i].get(&io_buffer[0], io_buffer.size(), - read_wait_ms); - - if(got) - { - accum.add(&io_buffer[0], got, ENTROPY_BITS_PER_BYTE); - break; - } - } - } - -} - -/* -* EGD EntropySource -* (C) 1999-2009 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include -#include - -#include -#include -#include -#include - -#include -#include - -#ifndef PF_LOCAL - #define PF_LOCAL PF_UNIX -#endif - -namespace Botan { - -EGD_EntropySource::EGD_Socket::EGD_Socket(const std::string& path) : - socket_path(path), m_fd(-1) - { - } - -/** -* Attempt a connection to an EGD/PRNGD socket -*/ -int EGD_EntropySource::EGD_Socket::open_socket(const std::string& path) - { - int fd = ::socket(PF_LOCAL, SOCK_STREAM, 0); - - if(fd >= 0) - { - sockaddr_un addr; - std::memset(&addr, 0, sizeof(addr)); - addr.sun_family = PF_LOCAL; - - if(path.length() >= sizeof(addr.sun_path)) - throw std::invalid_argument("EGD socket path is too long"); - - std::strncpy(addr.sun_path, path.c_str(), sizeof(addr.sun_path)); - - int len = sizeof(addr.sun_family) + std::strlen(addr.sun_path) + 1; - - if(::connect(fd, reinterpret_cast(&addr), len) < 0) - { - ::close(fd); - fd = -1; - } - } - - return fd; - } - -/** -* Attempt to read entropy from EGD -*/ -size_t EGD_EntropySource::EGD_Socket::read(byte outbuf[], size_t length) - { - if(length == 0) - return 0; - - if(m_fd < 0) - { - m_fd = open_socket(socket_path); - if(m_fd < 0) - return 0; - } - - try - { - // 1 == EGD command for non-blocking read - byte egd_read_command[2] = { - 1, static_cast(std::min(length, 255)) }; - - if(::write(m_fd, egd_read_command, 2) != 2) - throw std::runtime_error("Writing entropy read command to EGD failed"); - - byte out_len = 0; - if(::read(m_fd, &out_len, 1) != 1) - throw std::runtime_error("Reading response length from EGD failed"); - - if(out_len > egd_read_command[1]) - throw std::runtime_error("Bogus length field received from EGD"); - - ssize_t count = ::read(m_fd, outbuf, out_len); - - if(count != out_len) - throw std::runtime_error("Reading entropy result from EGD failed"); - - return static_cast(count); - } - catch(std::exception) - { - this->close(); - // Will attempt to reopen next poll - } - - return 0; - } - -void EGD_EntropySource::EGD_Socket::close() - { - if(m_fd > 0) - { - ::close(m_fd); - m_fd = -1; - } - } - -/** -* EGD_EntropySource constructor -*/ -EGD_EntropySource::EGD_EntropySource(const std::vector& paths) - { - for(size_t i = 0; i != paths.size(); ++i) - sockets.push_back(EGD_Socket(paths[i])); - } - -EGD_EntropySource::~EGD_EntropySource() - { - for(size_t i = 0; i != sockets.size(); ++i) - sockets[i].close(); - sockets.clear(); - } - -/** -* Gather Entropy from EGD -*/ -void EGD_EntropySource::poll(Entropy_Accumulator& accum) - { - size_t go_get = std::min(accum.desired_remaining_bits() / 8, 32); - - MemoryRegion& io_buffer = accum.get_io_buffer(go_get); - - for(size_t i = 0; i != sockets.size(); ++i) - { - size_t got = sockets[i].read(&io_buffer[0], io_buffer.size()); - - if(got) - { - accum.add(&io_buffer[0], got, 6); - break; - } - } - } - -} -#endif - -/* -* High Resolution Timestamp Entropy Source -* (C) 1999-2009,2011 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -#if defined(BOTAN_TARGET_OS_IS_WINDOWS) - #include -#endif - -namespace Botan { - -/* -* Get the timestamp -*/ -void High_Resolution_Timestamp::poll(Entropy_Accumulator& accum) - { - // If Windows, grab the Performance Counter (usually TSC or PIT) -#if defined(BOTAN_TARGET_OS_IS_WINDOWS) - { - LARGE_INTEGER tv; - ::QueryPerformanceCounter(&tv); - accum.add(tv.QuadPart, 0); - } -#endif - -#if defined(BOTAN_TARGET_OS_HAS_CLOCK_GETTIME) - -#define CLOCK_POLL(src) \ - do { \ - struct timespec ts; \ - clock_gettime(src, &ts); \ - accum.add(&ts, sizeof(ts), 0); \ - } while(0) - -#if defined(CLOCK_REALTIME) - CLOCK_POLL(CLOCK_REALTIME); -#endif - -#if defined(CLOCK_MONOTONIC) - CLOCK_POLL(CLOCK_MONOTONIC); -#endif - -#if defined(CLOCK_MONOTONIC_RAW) - CLOCK_POLL(CLOCK_MONOTONIC_RAW); -#endif - -#if defined(CLOCK_PROCESS_CPUTIME_ID) - CLOCK_POLL(CLOCK_PROCESS_CPUTIME_ID); -#endif - -#if defined(CLOCK_THREAD_CPUTIME_ID) - CLOCK_POLL(CLOCK_THREAD_CPUTIME_ID); -#endif - -#undef CLOCK_POLL - -#endif - -#if BOTAN_USE_GCC_INLINE_ASM - - u64bit rtc = 0; - -#if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY) - if(CPUID::has_rdtsc()) // not availble on all x86 CPUs - { - u32bit rtc_low = 0, rtc_high = 0; - asm volatile("rdtsc" : "=d" (rtc_high), "=a" (rtc_low)); - rtc = (static_cast(rtc_high) << 32) | rtc_low; - } - -#elif defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY) - u32bit rtc_low = 0, rtc_high = 0; - asm volatile("mftbu %0; mftb %1" : "=r" (rtc_high), "=r" (rtc_low)); - rtc = (static_cast(rtc_high) << 32) | rtc_low; - -#elif defined(BOTAN_TARGET_ARCH_IS_ALPHA) - asm volatile("rpcc %0" : "=r" (rtc)); - -#elif defined(BOTAN_TARGET_ARCH_IS_SPARC64) && !defined(BOTAN_TARGET_OS_IS_OPENBSD) - asm volatile("rd %%tick, %0" : "=r" (rtc)); - -#elif defined(BOTAN_TARGET_ARCH_IS_IA64) - asm volatile("mov %0=ar.itc" : "=r" (rtc)); - -#elif defined(BOTAN_TARGET_ARCH_IS_S390X) - asm volatile("stck 0(%0)" : : "a" (&rtc) : "memory", "cc"); - -#elif defined(BOTAN_TARGET_ARCH_IS_HPPA) - asm volatile("mfctl 16,%0" : "=r" (rtc)); // 64-bit only? - -#endif - - // Don't count the timestamp as contributing entropy - accum.add(rtc, 0); - -#endif - } - -} - -#ifdef Q_OS_UNIX -/* -* FTW EntropySource -* (C) 1999-2008,2012 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include -#include - -#ifndef _POSIX_C_SOURCE - #define _POSIX_C_SOURCE 199309 -#endif - -#include -#include -#include -#include -#include - -namespace Botan { - -/** -* Returns file descriptors. Until it doesn't -*/ -class File_Descriptor_Source - { - public: - /** - * @return next file descriptor, or -1 if done - */ - virtual int next_fd() = 0; - - virtual ~File_Descriptor_Source() {} - }; - -namespace { - -class Directory_Walker : public File_Descriptor_Source - { - public: - Directory_Walker(const std::string& root) : - m_cur_dir(std::make_pair(0, "")) - { - if(DIR* root_dir = ::opendir(root.c_str())) - m_cur_dir = std::make_pair(root_dir, root); - } - - ~Directory_Walker() - { - if(m_cur_dir.first) - ::closedir(m_cur_dir.first); - } - - int next_fd(); - private: - void add_directory(const std::string& dirname) - { - m_dirlist.push_back(dirname); - } - - std::pair get_next_dirent(); - - std::pair m_cur_dir; - std::deque m_dirlist; - }; - -std::pair Directory_Walker::get_next_dirent() - { - while(m_cur_dir.first) - { - struct dirent* dir = ::readdir(m_cur_dir.first); - - if(dir) - return std::make_pair(dir, m_cur_dir.second); - - ::closedir(m_cur_dir.first); - m_cur_dir = std::make_pair(0, ""); - - while(!m_dirlist.empty() && m_cur_dir.first == 0) - { - const std::string next_dir_name = m_dirlist[0]; - m_dirlist.pop_front(); - - if(DIR* next_dir = ::opendir(next_dir_name.c_str())) - m_cur_dir = std::make_pair(next_dir, next_dir_name); - } - } - - return std::make_pair(0, ""); // nothing left - } - -int Directory_Walker::next_fd() - { - while(true) - { - std::pair entry = get_next_dirent(); - - if(!entry.first) - break; // no more dirs - - const std::string filename = entry.first->d_name; - - if(filename == "." || filename == "..") - continue; - - const std::string full_path = entry.second + '/' + filename; - - struct stat stat_buf; - if(::lstat(full_path.c_str(), &stat_buf) == -1) - continue; - - if(S_ISDIR(stat_buf.st_mode)) - { - add_directory(full_path); - } - else if(S_ISREG(stat_buf.st_mode) && (stat_buf.st_mode & S_IROTH)) - { - int fd = ::open(full_path.c_str(), O_RDONLY | O_NOCTTY); - - if(fd >= 0) - return fd; - } - } - - return -1; - } - -} - -/** -* FTW_EntropySource Constructor -*/ -FTW_EntropySource::FTW_EntropySource(const std::string& p) : path(p) - { - dir = 0; - } - -/** -* FTW_EntropySource Destructor -*/ -FTW_EntropySource::~FTW_EntropySource() - { - delete dir; - } - -void FTW_EntropySource::poll(Entropy_Accumulator& accum) - { - const size_t MAX_FILES_READ_PER_POLL = 2048; - - if(!dir) - dir = new Directory_Walker(path); - - MemoryRegion& io_buffer = accum.get_io_buffer(4096); - - for(size_t i = 0; i != MAX_FILES_READ_PER_POLL; ++i) - { - int fd = dir->next_fd(); - - // If we've exhaused this walk of the directory, halt the poll - if(fd == -1) - { - delete dir; - dir = 0; - break; - } - - ssize_t got = ::read(fd, &io_buffer[0], io_buffer.size()); - ::close(fd); - - if(got > 0) - accum.add(&io_buffer[0], got, .001); - - if(accum.polling_goal_achieved()) - break; - } - } - -} - -/* -* Unix EntropySource -* (C) 1999-2009 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include - -#include -#include -#include -#include - -namespace Botan { - -namespace { - -/** -* Sort ordering by priority -*/ -bool Unix_Program_Cmp(const Unix_Program& a, const Unix_Program& b) - { - if(a.priority == b.priority) - return (a.name_and_args < b.name_and_args); - - return (a.priority < b.priority); - } - -} - -/** -* Unix_EntropySource Constructor -*/ -Unix_EntropySource::Unix_EntropySource(const std::vector& path) : - PATH(path) - { - std::vector default_sources = get_default_sources(); - add_sources(&default_sources[0], default_sources.size()); - } - -/** -* Add sources to the list -*/ -void Unix_EntropySource::add_sources(const Unix_Program srcs[], size_t count) - { - sources.insert(sources.end(), srcs, srcs + count); - std::sort(sources.begin(), sources.end(), Unix_Program_Cmp); - } - -/** -* Poll for entropy on a generic Unix system, first by grabbing various -* statistics (stat on common files, getrusage, etc), and then, if more -* is required, by exec'ing various programs like uname and rpcinfo and -* reading the output. -*/ -void Unix_EntropySource::poll(Entropy_Accumulator& accum) - { - const char* stat_targets[] = { - "/", - "/tmp", - "/var/tmp", - "/usr", - "/home", - "/etc/passwd", - ".", - "..", - 0 }; - - for(size_t i = 0; stat_targets[i]; i++) - { - struct stat statbuf; - clear_mem(&statbuf, 1); - if(::stat(stat_targets[i], &statbuf) == 0) - accum.add(&statbuf, sizeof(statbuf), .005); - } - - accum.add(::getpid(), 0); - accum.add(::getppid(), 0); - accum.add(::getuid(), 0); - accum.add(::getgid(), 0); - accum.add(::getpgrp(), 0); - - struct ::rusage usage; - ::getrusage(RUSAGE_SELF, &usage); - accum.add(usage, .005); - - ::getrusage(RUSAGE_CHILDREN, &usage); - accum.add(usage, .005); - - const size_t MINIMAL_WORKING = 16; - - MemoryRegion& io_buffer = accum.get_io_buffer(DEFAULT_BUFFERSIZE); - - for(size_t i = 0; i != sources.size(); i++) - { - DataSource_Command pipe(sources[i].name_and_args, PATH); - - size_t got_from_src = 0; - - while(!pipe.end_of_data()) - { - size_t got_this_loop = pipe.read(&io_buffer[0], io_buffer.size()); - got_from_src += got_this_loop; - - accum.add(&io_buffer[0], got_this_loop, .005); - } - - sources[i].working = (got_from_src >= MINIMAL_WORKING) ? true : false; - - if(accum.polling_goal_achieved()) - break; - } - } - -} -/* -* Unix Command Execution -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -#include -#include -#include -#include -#include -#include -#include - -namespace Botan { - -namespace { - -/** -* Attempt to execute the command -*/ -void do_exec(const std::vector& arg_list, - const std::vector& paths) - { - const size_t args = arg_list.size() - 1; - - const char* arg1 = (args >= 1) ? arg_list[1].c_str() : 0; - const char* arg2 = (args >= 2) ? arg_list[2].c_str() : 0; - const char* arg3 = (args >= 3) ? arg_list[3].c_str() : 0; - const char* arg4 = (args >= 4) ? arg_list[4].c_str() : 0; - - for(size_t j = 0; j != paths.size(); j++) - { - const std::string full_path = paths[j] + "/" + arg_list[0]; - const char* fsname = full_path.c_str(); - - ::execl(fsname, fsname, arg1, arg2, arg3, arg4, NULL); - } - } - -} - -/** -* Local information about the pipe -*/ -struct pipe_wrapper - { - int fd; - pid_t pid; - - pipe_wrapper(int f, pid_t p) : fd(f), pid(p) {} - ~pipe_wrapper() { ::close(fd); } - }; - -/** -* Read from the pipe -*/ -size_t DataSource_Command::read(byte buf[], size_t length) - { - if(end_of_data()) - return 0; - - fd_set set; - FD_ZERO(&set); - FD_SET(pipe->fd, &set); - - struct ::timeval tv; - tv.tv_sec = 0; - tv.tv_usec = MAX_BLOCK_USECS; - - ssize_t got = 0; - if(::select(pipe->fd + 1, &set, 0, 0, &tv) == 1) - { - if(FD_ISSET(pipe->fd, &set)) - got = ::read(pipe->fd, buf, length); - } - - if(got <= 0) - { - shutdown_pipe(); - return 0; - } - - return static_cast(got); - } - -/** -* Peek at the pipe contents -*/ -size_t DataSource_Command::peek(byte[], size_t, size_t) const - { - if(end_of_data()) - throw Invalid_State("DataSource_Command: Cannot peek when out of data"); - throw Stream_IO_Error("Cannot peek/seek on a command pipe"); - } - -/** -* Check if we reached EOF -*/ -bool DataSource_Command::end_of_data() const - { - return (pipe) ? false : true; - } - -/** -* Return the Unix file descriptor of the pipe -*/ -int DataSource_Command::fd() const - { - if(!pipe) - return -1; - return pipe->fd; - } - -/** -* Return a human-readable ID for this stream -*/ -std::string DataSource_Command::id() const - { - return "Unix command: " + arg_list[0]; - } - -/** -* Create the pipe -*/ -void DataSource_Command::create_pipe(const std::vector& paths) - { - bool found_something = false; - - for(size_t j = 0; j != paths.size(); j++) - { - const std::string full_path = paths[j] + "/" + arg_list[0]; - if(::access(full_path.c_str(), X_OK) == 0) - { - found_something = true; - break; - } - } - - if(!found_something) - return; - - int pipe_fd[2]; - if(::pipe(pipe_fd) != 0) - return; - - pid_t pid = ::fork(); - - if(pid == -1) - { - ::close(pipe_fd[0]); - ::close(pipe_fd[1]); - } - else if(pid > 0) - { - pipe = new pipe_wrapper(pipe_fd[0], pid); - ::close(pipe_fd[1]); - } - else - { - if(dup2(pipe_fd[1], STDOUT_FILENO) == -1) - ::exit(127); - if(close(pipe_fd[0]) != 0 || close(pipe_fd[1]) != 0) - ::exit(127); - if(close(STDERR_FILENO) != 0) - ::exit(127); - - do_exec(arg_list, paths); - ::exit(127); - } - } - -/** -* Shutdown the pipe -*/ -void DataSource_Command::shutdown_pipe() - { - if(pipe) - { - pid_t reaped = waitpid(pipe->pid, 0, WNOHANG); - - if(reaped == 0) - { - kill(pipe->pid, SIGTERM); - - struct ::timeval tv; - tv.tv_sec = 0; - tv.tv_usec = KILL_WAIT; - select(0, 0, 0, 0, &tv); - - reaped = ::waitpid(pipe->pid, 0, WNOHANG); - - if(reaped == 0) - { - ::kill(pipe->pid, SIGKILL); - do - reaped = ::waitpid(pipe->pid, 0, 0); - while(reaped == -1); - } - } - - delete pipe; - pipe = 0; - } - } - -/** -* DataSource_Command Constructor -*/ -DataSource_Command::DataSource_Command(const std::string& prog_and_args, - const std::vector& paths) : - MAX_BLOCK_USECS(100000), KILL_WAIT(10000) - { - arg_list = split_on(prog_and_args, ' '); - - if(arg_list.size() == 0) - throw Invalid_Argument("DataSource_Command: No command given"); - if(arg_list.size() > 5) - throw Invalid_Argument("DataSource_Command: Too many args"); - - pipe = 0; - create_pipe(paths); - } - -/** -* DataSource_Command Destructor -*/ -DataSource_Command::~DataSource_Command() - { - if(!end_of_data()) - shutdown_pipe(); - } - -} -/* -* Program List for Unix_EntropySource -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -/** -* Default Commands for Entropy Gathering -*/ -std::vector Unix_EntropySource::get_default_sources() - { - std::vector srcs; - - srcs.push_back(Unix_Program("netstat -in", 1)); - srcs.push_back(Unix_Program("pfstat", 1)); - srcs.push_back(Unix_Program("vmstat -s", 1)); - srcs.push_back(Unix_Program("vmstat", 1)); - - srcs.push_back(Unix_Program("arp -a -n", 2)); - srcs.push_back(Unix_Program("ifconfig -a", 2)); - srcs.push_back(Unix_Program("iostat", 2)); - srcs.push_back(Unix_Program("ipcs -a", 2)); - srcs.push_back(Unix_Program("mpstat", 2)); - srcs.push_back(Unix_Program("netstat -an", 2)); - srcs.push_back(Unix_Program("netstat -s", 2)); - srcs.push_back(Unix_Program("nfsstat", 2)); - srcs.push_back(Unix_Program("portstat", 2)); - srcs.push_back(Unix_Program("procinfo -a", 2)); - srcs.push_back(Unix_Program("pstat -T", 2)); - srcs.push_back(Unix_Program("pstat -s", 2)); - srcs.push_back(Unix_Program("uname -a", 2)); - srcs.push_back(Unix_Program("uptime", 2)); - - srcs.push_back(Unix_Program("listarea", 3)); - srcs.push_back(Unix_Program("listdev", 3)); - srcs.push_back(Unix_Program("ps -A", 3)); - srcs.push_back(Unix_Program("sysinfo", 3)); - - srcs.push_back(Unix_Program("finger", 4)); - srcs.push_back(Unix_Program("mailstats", 4)); - srcs.push_back(Unix_Program("rpcinfo -p localhost", 4)); - srcs.push_back(Unix_Program("who", 4)); - - srcs.push_back(Unix_Program("df -l", 4)); - srcs.push_back(Unix_Program("dmesg", 4)); - srcs.push_back(Unix_Program("last -5", 4)); - srcs.push_back(Unix_Program("ls -alni /proc", 4)); - srcs.push_back(Unix_Program("ls -alni /tmp", 4)); - srcs.push_back(Unix_Program("pstat -f", 4)); - - srcs.push_back(Unix_Program("ps -elf", 5)); - srcs.push_back(Unix_Program("ps aux", 5)); - - srcs.push_back(Unix_Program("lsof -n", 6)); - srcs.push_back(Unix_Program("sar -A", 6)); - - return srcs; - } - -} -#endif - -#ifdef Q_OS_WIN -/* -* Win32 EntropySource -* (C) 1999-2009 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include -#include - -namespace Botan { - -/** -* Win32 poll using stats functions including Tooltip32 -*/ -void Win32_EntropySource::poll(Entropy_Accumulator& accum) - { - /* - First query a bunch of basic statistical stuff, though - don't count it for much in terms of contributed entropy. - */ - accum.add(GetTickCount(), 0); - accum.add(GetMessagePos(), 0); - accum.add(GetMessageTime(), 0); - accum.add(GetInputState(), 0); - accum.add(GetCurrentProcessId(), 0); - accum.add(GetCurrentThreadId(), 0); - - SYSTEM_INFO sys_info; - GetSystemInfo(&sys_info); - accum.add(sys_info, 1); - - MEMORYSTATUS mem_info; - GlobalMemoryStatus(&mem_info); - accum.add(mem_info, 1); - - POINT point; - GetCursorPos(&point); - accum.add(point, 1); - - GetCaretPos(&point); - accum.add(point, 1); - - LARGE_INTEGER perf_counter; - QueryPerformanceCounter(&perf_counter); - accum.add(perf_counter, 0); - - /* - Now use the Tooltip library to iterate throug various objects on - the system, including processes, threads, and heap objects. - */ - - HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0); - -#define TOOLHELP32_ITER(DATA_TYPE, FUNC_FIRST, FUNC_NEXT) \ - if(!accum.polling_goal_achieved()) \ - { \ - DATA_TYPE info; \ - info.dwSize = sizeof(DATA_TYPE); \ - if(FUNC_FIRST(snapshot, &info)) \ - { \ - do \ - { \ - accum.add(info, 1); \ - } while(FUNC_NEXT(snapshot, &info)); \ - } \ - } - - TOOLHELP32_ITER(MODULEENTRY32, Module32First, Module32Next); - TOOLHELP32_ITER(PROCESSENTRY32, Process32First, Process32Next); - TOOLHELP32_ITER(THREADENTRY32, Thread32First, Thread32Next); - -#undef TOOLHELP32_ITER - - if(!accum.polling_goal_achieved()) - { - size_t heap_lists_found = 0; - HEAPLIST32 heap_list; - heap_list.dwSize = sizeof(HEAPLIST32); - - const size_t HEAP_LISTS_MAX = 32; - const size_t HEAP_OBJS_PER_LIST = 128; - - if(Heap32ListFirst(snapshot, &heap_list)) - { - do - { - accum.add(heap_list, 1); - - if(++heap_lists_found > HEAP_LISTS_MAX) - break; - - size_t heap_objs_found = 0; - HEAPENTRY32 heap_entry; - heap_entry.dwSize = sizeof(HEAPENTRY32); - if(Heap32First(&heap_entry, heap_list.th32ProcessID, - heap_list.th32HeapID)) - { - do - { - if(heap_objs_found++ > HEAP_OBJS_PER_LIST) - break; - accum.add(heap_entry, 1); - } while(Heap32Next(&heap_entry)); - } - - if(accum.polling_goal_achieved()) - break; - - } while(Heap32ListNext(snapshot, &heap_list)); - } - } - - CloseHandle(snapshot); - } - -} -#endif - -/* -* Filters -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include - -namespace Botan { - -/* -* StreamCipher_Filter Constructor -*/ -StreamCipher_Filter::StreamCipher_Filter(StreamCipher* stream_cipher) : - buffer(DEFAULT_BUFFERSIZE) - { - cipher = stream_cipher; - } - -/* -* StreamCipher_Filter Constructor -*/ -StreamCipher_Filter::StreamCipher_Filter(StreamCipher* stream_cipher, - const SymmetricKey& key) : - buffer(DEFAULT_BUFFERSIZE) - { - cipher = stream_cipher; - cipher->set_key(key); - } - -/* -* StreamCipher_Filter Constructor -*/ -StreamCipher_Filter::StreamCipher_Filter(const std::string& sc_name) : - buffer(DEFAULT_BUFFERSIZE) - { - Algorithm_Factory& af = global_state().algorithm_factory(); - cipher = af.make_stream_cipher(sc_name); - } - -/* -* StreamCipher_Filter Constructor -*/ -StreamCipher_Filter::StreamCipher_Filter(const std::string& sc_name, - const SymmetricKey& key) : - buffer(DEFAULT_BUFFERSIZE) - { - Algorithm_Factory& af = global_state().algorithm_factory(); - cipher = af.make_stream_cipher(sc_name); - cipher->set_key(key); - } - -/* -* Set the IV of a stream cipher -*/ -void StreamCipher_Filter::set_iv(const InitializationVector& iv) - { - cipher->set_iv(iv.begin(), iv.length()); - } - -/* -* Write data into a StreamCipher_Filter -*/ -void StreamCipher_Filter::write(const byte input[], size_t length) - { - while(length) - { - size_t copied = std::min(length, buffer.size()); - cipher->cipher(input, &buffer[0], copied); - send(buffer, copied); - input += copied; - length -= copied; - } - } - -/* -* Hash_Filter Constructor -*/ -Hash_Filter::Hash_Filter(const std::string& algo_spec, - size_t len) : - OUTPUT_LENGTH(len) - { - Algorithm_Factory& af = global_state().algorithm_factory(); - hash = af.make_hash_function(algo_spec); - } - -/* -* Complete a calculation by a Hash_Filter -*/ -void Hash_Filter::end_msg() - { - SecureVector output = hash->final(); - if(OUTPUT_LENGTH) - send(output, std::min(OUTPUT_LENGTH, output.size())); - else - send(output); - } - -/* -* MAC_Filter Constructor -*/ -MAC_Filter::MAC_Filter(const std::string& mac_name, size_t len) : - OUTPUT_LENGTH(len) - { - Algorithm_Factory& af = global_state().algorithm_factory(); - mac = af.make_mac(mac_name); - } - -/* -* MAC_Filter Constructor -*/ -MAC_Filter::MAC_Filter(const std::string& mac_name, const SymmetricKey& key, - size_t len) : OUTPUT_LENGTH(len) - { - Algorithm_Factory& af = global_state().algorithm_factory(); - mac = af.make_mac(mac_name); - mac->set_key(key); - } - -/* -* Complete a calculation by a MAC_Filter -*/ -void MAC_Filter::end_msg() - { - SecureVector output = mac->final(); - if(OUTPUT_LENGTH) - send(output, std::min(OUTPUT_LENGTH, output.size())); - else - send(output); - } - -} -/* -* Basic Filters -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -void Keyed_Filter::set_iv(const InitializationVector& iv) - { - if(iv.length() != 0) - throw Invalid_IV_Length(name(), iv.length()); - } - -/* -* Chain Constructor -*/ -Chain::Chain(Filter* f1, Filter* f2, Filter* f3, Filter* f4) - { - if(f1) { attach(f1); incr_owns(); } - if(f2) { attach(f2); incr_owns(); } - if(f3) { attach(f3); incr_owns(); } - if(f4) { attach(f4); incr_owns(); } - } - -/* -* Chain Constructor -*/ -Chain::Chain(Filter* filters[], size_t count) - { - for(size_t j = 0; j != count; ++j) - if(filters[j]) - { - attach(filters[j]); - incr_owns(); - } - } - -std::string Chain::name() const - { - return "Chain"; - } - -/* -* Fork Constructor -*/ -Fork::Fork(Filter* f1, Filter* f2, Filter* f3, Filter* f4) - { - Filter* filters[4] = { f1, f2, f3, f4 }; - set_next(filters, 4); - } - -/* -* Fork Constructor -*/ -Fork::Fork(Filter* filters[], size_t count) - { - set_next(filters, count); - } - -std::string Fork::name() const - { - return "Fork"; - } - -} -/* -* Buffered Filter -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include - -namespace Botan { - -/* -* Buffered_Filter Constructor -*/ -Buffered_Filter::Buffered_Filter(size_t b, size_t f) : - main_block_mod(b), final_minimum(f) - { - if(main_block_mod == 0) - throw std::invalid_argument("main_block_mod == 0"); - - if(final_minimum > main_block_mod) - throw std::invalid_argument("final_minimum > main_block_mod"); - - buffer.resize(2 * main_block_mod); - buffer_pos = 0; - } - -/* -* Buffer input into blocks, trying to minimize copying -*/ -void Buffered_Filter::write(const byte input[], size_t input_size) - { - if(!input_size) - return; - - if(buffer_pos + input_size >= main_block_mod + final_minimum) - { - size_t to_copy = std::min(buffer.size() - buffer_pos, input_size); - - copy_mem(&buffer[buffer_pos], input, to_copy); - buffer_pos += to_copy; - - input += to_copy; - input_size -= to_copy; - - size_t total_to_consume = - round_down(std::min(buffer_pos, - buffer_pos + input_size - final_minimum), - main_block_mod); - - buffered_block(&buffer[0], total_to_consume); - - buffer_pos -= total_to_consume; - - copy_mem(&buffer[0], &buffer[total_to_consume], buffer_pos); - } - - if(input_size >= final_minimum) - { - size_t full_blocks = (input_size - final_minimum) / main_block_mod; - size_t to_copy = full_blocks * main_block_mod; - - if(to_copy) - { - buffered_block(input, to_copy); - - input += to_copy; - input_size -= to_copy; - } - } - - copy_mem(&buffer[buffer_pos], input, input_size); - buffer_pos += input_size; - } - -/* -* Finish/flush operation -*/ -void Buffered_Filter::end_msg() - { - if(buffer_pos < final_minimum) - throw std::runtime_error("Buffered filter end_msg without enough input"); - - size_t spare_blocks = (buffer_pos - final_minimum) / main_block_mod; - - if(spare_blocks) - { - size_t spare_bytes = main_block_mod * spare_blocks; - buffered_block(&buffer[0], spare_bytes); - buffered_final(&buffer[spare_bytes], buffer_pos - spare_bytes); - } - else - { - buffered_final(&buffer[0], buffer_pos); - } - - buffer_pos = 0; - } - -} -/* -* Base64 Encoder/Decoder -* (C) 1999-2010 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include - -namespace Botan { - -/* -* Base64_Encoder Constructor -*/ -Base64_Encoder::Base64_Encoder(bool breaks, size_t length, bool t_n) : - line_length(breaks ? length : 0), - trailing_newline(t_n && breaks), - in(48), - out(64), - position(0), - out_position(0) - { - } - -/* -* Encode and send a block -*/ -void Base64_Encoder::encode_and_send(const byte input[], size_t length, - bool final_inputs) - { - while(length) - { - const size_t proc = std::min(length, in.size()); - - size_t consumed = 0; - size_t produced = base64_encode(reinterpret_cast(&out[0]), input, - proc, consumed, final_inputs); - - do_output(&out[0], produced); - - // FIXME: s/proc/consumed/? - input += proc; - length -= proc; - } - } - -/* -* Handle the output -*/ -void Base64_Encoder::do_output(const byte input[], size_t length) - { - if(line_length == 0) - send(input, length); - else - { - size_t remaining = length, offset = 0; - while(remaining) - { - size_t sent = std::min(line_length - out_position, remaining); - send(input + offset, sent); - out_position += sent; - remaining -= sent; - offset += sent; - if(out_position == line_length) - { - send('\n'); - out_position = 0; - } - } - } - } - -/* -* Convert some data into Base64 -*/ -void Base64_Encoder::write(const byte input[], size_t length) - { - in.copy(position, input, length); - if(position + length >= in.size()) - { - encode_and_send(&in[0], in.size()); - input += (in.size() - position); - length -= (in.size() - position); - while(length >= in.size()) - { - encode_and_send(input, in.size()); - input += in.size(); - length -= in.size(); - } - in.copy(input, length); - position = 0; - } - position += length; - } - -/* -* Flush buffers -*/ -void Base64_Encoder::end_msg() - { - encode_and_send(&in[0], position, true); - - if(trailing_newline || (out_position && line_length)) - send('\n'); - - out_position = position = 0; - } - -/* -* Base64_Decoder Constructor -*/ -Base64_Decoder::Base64_Decoder(Decoder_Checking c) : - checking(c), in(64), out(48), position(0) - { - } - -/* -* Convert some data from Base64 -*/ -void Base64_Decoder::write(const byte input[], size_t length) - { - while(length) - { - size_t to_copy = std::min(length, in.size() - position); - copy_mem(&in[position], input, to_copy); - position += to_copy; - - size_t consumed = 0; - size_t written = base64_decode(&out[0], - reinterpret_cast(&in[0]), - position, - consumed, - false, - checking != FULL_CHECK); - - send(out, written); - - if(consumed != position) - { - copy_mem(&in[0], &in[consumed], position - consumed); - position = position - consumed; - } - else - position = 0; - - length -= to_copy; - input += to_copy; - } - } - -/* -* Flush buffers -*/ -void Base64_Decoder::end_msg() - { - size_t consumed = 0; - size_t written = base64_decode(&out[0], - reinterpret_cast(&in[0]), - position, - consumed, - true, - checking != FULL_CHECK); - - send(out, written); - - const bool not_full_bytes = consumed != position; - - position = 0; - - if(not_full_bytes) - throw std::invalid_argument("Base64_Decoder: Input not full bytes"); - } - -} -/* -* Hex Encoder/Decoder -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include - -namespace Botan { - -/** -* Size used for internal buffer in hex encoder/decoder -*/ -const size_t HEX_CODEC_BUFFER_SIZE = 256; - -/* -* Hex_Encoder Constructor -*/ -Hex_Encoder::Hex_Encoder(bool breaks, size_t length, Case c) : - casing(c), line_length(breaks ? length : 0) - { - in.resize(HEX_CODEC_BUFFER_SIZE); - out.resize(2*in.size()); - counter = position = 0; - } - -/* -* Hex_Encoder Constructor -*/ -Hex_Encoder::Hex_Encoder(Case c) : casing(c), line_length(0) - { - in.resize(HEX_CODEC_BUFFER_SIZE); - out.resize(2*in.size()); - counter = position = 0; - } - -/* -* Encode and send a block -*/ -void Hex_Encoder::encode_and_send(const byte block[], size_t length) - { - hex_encode(reinterpret_cast(&out[0]), - block, length, - casing == Uppercase); - - if(line_length == 0) - send(out, 2*length); - else - { - size_t remaining = 2*length, offset = 0; - while(remaining) - { - size_t sent = std::min(line_length - counter, remaining); - send(&out[offset], sent); - counter += sent; - remaining -= sent; - offset += sent; - if(counter == line_length) - { - send('\n'); - counter = 0; - } - } - } - } - -/* -* Convert some data into hex format -*/ -void Hex_Encoder::write(const byte input[], size_t length) - { - in.copy(position, input, length); - if(position + length >= in.size()) - { - encode_and_send(&in[0], in.size()); - input += (in.size() - position); - length -= (in.size() - position); - while(length >= in.size()) - { - encode_and_send(input, in.size()); - input += in.size(); - length -= in.size(); - } - in.copy(input, length); - position = 0; - } - position += length; - } - -/* -* Flush buffers -*/ -void Hex_Encoder::end_msg() - { - encode_and_send(&in[0], position); - if(counter && line_length) - send('\n'); - counter = position = 0; - } - -/* -* Hex_Decoder Constructor -*/ -Hex_Decoder::Hex_Decoder(Decoder_Checking c) : checking(c) - { - in.resize(HEX_CODEC_BUFFER_SIZE); - out.resize(in.size() / 2); - position = 0; - } - -/* -* Convert some data from hex format -*/ -void Hex_Decoder::write(const byte input[], size_t length) - { - while(length) - { - size_t to_copy = std::min(length, in.size() - position); - copy_mem(&in[position], input, to_copy); - position += to_copy; - - size_t consumed = 0; - size_t written = hex_decode(&out[0], - reinterpret_cast(&in[0]), - position, - consumed, - checking != FULL_CHECK); - - send(out, written); - - if(consumed != position) - { - copy_mem(&in[0], &in[consumed], position - consumed); - position = position - consumed; - } - else - position = 0; - - length -= to_copy; - input += to_copy; - } - } - -/* -* Flush buffers -*/ -void Hex_Decoder::end_msg() - { - size_t consumed = 0; - size_t written = hex_decode(&out[0], - reinterpret_cast(&in[0]), - position, - consumed, - checking != FULL_CHECK); - - send(out, written); - - const bool not_full_bytes = consumed != position; - - position = 0; - - if(not_full_bytes) - throw std::invalid_argument("Hex_Decoder: Input not full bytes"); - } - -} -/* -* DataSink -* (C) 1999-2007 Jack Lloyd -* 2005 Matthew Gregan -* -* Distributed under the terms of the Botan license -*/ - -#include - -namespace Botan { - -/* -* Write to a stream -*/ -void DataSink_Stream::write(const byte out[], size_t length) - { - sink.write(reinterpret_cast(out), length); - if(!sink.good()) - throw Stream_IO_Error("DataSink_Stream: Failure writing to " + - identifier); - } - -/* -* DataSink_Stream Constructor -*/ -DataSink_Stream::DataSink_Stream(std::ostream& out, - const std::string& name) : - identifier(name), - sink_p(0), - sink(out) - { - } - -/* -* DataSink_Stream Constructor -*/ -DataSink_Stream::DataSink_Stream(const std::string& path, - bool use_binary) : - identifier(path), - sink_p(new std::ofstream( - path.c_str(), - use_binary ? std::ios::binary : std::ios::out)), - sink(*sink_p) - { - if(!sink.good()) - { - delete sink_p; - throw Stream_IO_Error("DataSink_Stream: Failure opening " + path); - } - } - -/* -* DataSink_Stream Destructor -*/ -DataSink_Stream::~DataSink_Stream() - { - delete sink_p; - } - -} -/* -* DataSource -* (C) 1999-2007 Jack Lloyd -* 2005 Matthew Gregan -* -* Distributed under the terms of the Botan license -*/ - -#include -#include - -namespace Botan { - -/* -* Read a single byte from the DataSource -*/ -size_t DataSource::read_byte(byte& out) - { - return read(&out, 1); - } - -/* -* Peek a single byte from the DataSource -*/ -size_t DataSource::peek_byte(byte& out) const - { - return peek(&out, 1, 0); - } - -/* -* Discard the next N bytes of the data -*/ -size_t DataSource::discard_next(size_t n) - { - size_t discarded = 0; - byte dummy; - for(size_t j = 0; j != n; ++j) - discarded += read_byte(dummy); - return discarded; - } - -/* -* Read from a memory buffer -*/ -size_t DataSource_Memory::read(byte out[], size_t length) - { - size_t got = std::min(source.size() - offset, length); - copy_mem(out, &source[offset], got); - offset += got; - return got; - } - -/* -* Peek into a memory buffer -*/ -size_t DataSource_Memory::peek(byte out[], size_t length, - size_t peek_offset) const - { - const size_t bytes_left = source.size() - offset; - if(peek_offset >= bytes_left) return 0; - - size_t got = std::min(bytes_left - peek_offset, length); - copy_mem(out, &source[offset + peek_offset], got); - return got; - } - -/* -* Check if the memory buffer is empty -*/ -bool DataSource_Memory::end_of_data() const - { - return (offset == source.size()); - } - -/* -* DataSource_Memory Constructor -*/ -DataSource_Memory::DataSource_Memory(const byte in[], size_t length) : - source(in, length) - { - offset = 0; - } - -/* -* DataSource_Memory Constructor -*/ -DataSource_Memory::DataSource_Memory(const MemoryRegion& in) : - source(in) - { - offset = 0; - } - -/* -* DataSource_Memory Constructor -*/ -DataSource_Memory::DataSource_Memory(const std::string& in) : - source(reinterpret_cast(in.data()), in.length()) - { - offset = 0; - } - -/* -* Read from a stream -*/ -size_t DataSource_Stream::read(byte out[], size_t length) - { - source.read(reinterpret_cast(out), length); - if(source.bad()) - throw Stream_IO_Error("DataSource_Stream::read: Source failure"); - - size_t got = source.gcount(); - total_read += got; - return got; - } - -/* -* Peek into a stream -*/ -size_t DataSource_Stream::peek(byte out[], size_t length, size_t offset) const - { - if(end_of_data()) - throw Invalid_State("DataSource_Stream: Cannot peek when out of data"); - - size_t got = 0; - - if(offset) - { - SecureVector buf(offset); - source.read(reinterpret_cast(&buf[0]), buf.size()); - if(source.bad()) - throw Stream_IO_Error("DataSource_Stream::peek: Source failure"); - got = source.gcount(); - } - - if(got == offset) - { - source.read(reinterpret_cast(out), length); - if(source.bad()) - throw Stream_IO_Error("DataSource_Stream::peek: Source failure"); - got = source.gcount(); - } - - if(source.eof()) - source.clear(); - source.seekg(total_read, std::ios::beg); - - return got; - } - -/* -* Check if the stream is empty or in error -*/ -bool DataSource_Stream::end_of_data() const - { - return (!source.good()); - } - -/* -* Return a human-readable ID for this stream -*/ -std::string DataSource_Stream::id() const - { - return identifier; - } - -/* -* DataSource_Stream Constructor -*/ -DataSource_Stream::DataSource_Stream(const std::string& path, - bool use_binary) : - identifier(path), - source_p(new std::ifstream( - path.c_str(), - use_binary ? std::ios::binary : std::ios::in)), - source(*source_p), - total_read(0) - { - if(!source.good()) - { - delete source_p; - throw Stream_IO_Error("DataSource: Failure opening file " + path); - } - } - -/* -* DataSource_Stream Constructor -*/ -DataSource_Stream::DataSource_Stream(std::istream& in, - const std::string& name) : - identifier(name), - source_p(0), - source(in), - total_read(0) - { - } - -/* -* DataSource_Stream Destructor -*/ -DataSource_Stream::~DataSource_Stream() - { - delete source_p; - } - -} - -#ifdef Q_OS_UNIX -/* -* Pipe I/O for Unix -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include - -namespace Botan { - -/* -* Write data from a pipe into a Unix fd -*/ -int operator<<(int fd, Pipe& pipe) - { - SecureVector buffer(DEFAULT_BUFFERSIZE); - while(pipe.remaining()) - { - size_t got = pipe.read(&buffer[0], buffer.size()); - size_t position = 0; - while(got) - { - ssize_t ret = write(fd, &buffer[position], got); - if(ret == -1) - throw Stream_IO_Error("Pipe output operator (unixfd) has failed"); - position += ret; - got -= ret; - } - } - return fd; - } - -/* -* Read data from a Unix fd into a pipe -*/ -int operator>>(int fd, Pipe& pipe) - { - SecureVector buffer(DEFAULT_BUFFERSIZE); - while(true) - { - ssize_t ret = read(fd, &buffer[0], buffer.size()); - if(ret == 0) break; - if(ret == -1) - throw Stream_IO_Error("Pipe input operator (unixfd) has failed"); - pipe.write(&buffer[0], ret); - } - return fd; - } - -} -#endif - -/* -* Filter -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -/* -* Filter Constructor -*/ -Filter::Filter() - { - next.resize(1); - port_num = 0; - filter_owns = 0; - owned = false; - } - -/* -* Send data to all ports -*/ -void Filter::send(const byte input[], size_t length) - { - bool nothing_attached = true; - for(size_t j = 0; j != total_ports(); ++j) - if(next[j]) - { - if(write_queue.size()) - next[j]->write(&write_queue[0], write_queue.size()); - next[j]->write(input, length); - nothing_attached = false; - } - - if(nothing_attached) - write_queue += std::make_pair(input, length); - else - write_queue.clear(); - } - -/* -* Start a new message -*/ -void Filter::new_msg() - { - start_msg(); - for(size_t j = 0; j != total_ports(); ++j) - if(next[j]) - next[j]->new_msg(); - } - -/* -* End the current message -*/ -void Filter::finish_msg() - { - end_msg(); - for(size_t j = 0; j != total_ports(); ++j) - if(next[j]) - next[j]->finish_msg(); - } - -/* -* Attach a filter to the current port -*/ -void Filter::attach(Filter* new_filter) - { - if(new_filter) - { - Filter* last = this; - while(last->get_next()) - last = last->get_next(); - last->next[last->current_port()] = new_filter; - } - } - -/* -* Set the active port on a filter -*/ -void Filter::set_port(size_t new_port) - { - if(new_port >= total_ports()) - throw Invalid_Argument("Filter: Invalid port number"); - port_num = new_port; - } - -/* -* Return the next Filter in the logical chain -*/ -Filter* Filter::get_next() const - { - if(port_num < next.size()) - return next[port_num]; - return 0; - } - -/* -* Set the next Filters -*/ -void Filter::set_next(Filter* filters[], size_t size) - { - while(size && filters && filters[size-1] == 0) - --size; - - next.clear(); - next.resize(size); - - port_num = 0; - filter_owns = 0; - - for(size_t j = 0; j != size; ++j) - next[j] = filters[j]; - } - -/* -* Return the total number of ports -*/ -size_t Filter::total_ports() const - { - return next.size(); - } - -} -/* -* CBC Mode -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include - -namespace Botan { - -/* -* CBC Encryption Constructor -*/ -CBC_Encryption::CBC_Encryption(BlockCipher* ciph, - BlockCipherModePaddingMethod* pad) : - Buffered_Filter(ciph->block_size(), 0), - cipher(ciph), padder(pad) - { - if(!padder->valid_blocksize(cipher->block_size())) - throw Invalid_Block_Size(name(), padder->name()); - - state.resize(cipher->block_size()); - } - -/* -* CBC Encryption Constructor -*/ -CBC_Encryption::CBC_Encryption(BlockCipher* ciph, - BlockCipherModePaddingMethod* pad, - const SymmetricKey& key, - const InitializationVector& iv) : - Buffered_Filter(ciph->block_size(), 0), - cipher(ciph), padder(pad) - { - if(!padder->valid_blocksize(cipher->block_size())) - throw Invalid_Block_Size(name(), padder->name()); - - state.resize(cipher->block_size()); - - set_key(key); - set_iv(iv); - } - -/* -* Set the IV -*/ -void CBC_Encryption::set_iv(const InitializationVector& iv) - { - if(!valid_iv_length(iv.length())) - throw Invalid_IV_Length(name(), iv.length()); - - state = iv.bits_of(); - buffer_reset(); - } - -/* -* Encrypt in CBC mode -*/ -void CBC_Encryption::buffered_block(const byte input[], size_t length) - { - size_t blocks = length / state.size(); - - for(size_t i = 0; i != blocks; ++i) - { - xor_buf(state, input + i * cipher->block_size(), state.size()); - cipher->encrypt(state); - send(state, state.size()); - } - } - -/* -* Finish encrypting in CBC mode -*/ -void CBC_Encryption::buffered_final(const byte input[], size_t length) - { - if(length % cipher->block_size() == 0) - buffered_block(input, length); - else if(length != 0) - throw Encoding_Error(name() + ": Did not pad to full blocksize"); - } - -void CBC_Encryption::write(const byte input[], size_t input_length) - { - Buffered_Filter::write(input, input_length); - } - -void CBC_Encryption::end_msg() - { - size_t last_block = current_position() % cipher->block_size(); - - SecureVector padding(cipher->block_size()); - padder->pad(padding, padding.size(), last_block); - - size_t pad_bytes = padder->pad_bytes(cipher->block_size(), last_block); - - if(pad_bytes) - Buffered_Filter::write(padding, pad_bytes); - Buffered_Filter::end_msg(); - } - -/* -* Return a CBC mode name -*/ -std::string CBC_Encryption::name() const - { - return (cipher->name() + "/CBC/" + padder->name()); - } - -/* -* CBC Decryption Constructor -*/ -CBC_Decryption::CBC_Decryption(BlockCipher* ciph, - BlockCipherModePaddingMethod* pad) : - Buffered_Filter(ciph->parallel_bytes(), ciph->block_size()), - cipher(ciph), padder(pad) - { - if(!padder->valid_blocksize(cipher->block_size())) - throw Invalid_Block_Size(name(), padder->name()); - - state.resize(cipher->block_size()); - temp.resize(buffered_block_size()); - } - -/* -* CBC Decryption Constructor -*/ -CBC_Decryption::CBC_Decryption(BlockCipher* ciph, - BlockCipherModePaddingMethod* pad, - const SymmetricKey& key, - const InitializationVector& iv) : - Buffered_Filter(ciph->parallel_bytes(), ciph->block_size()), - cipher(ciph), padder(pad) - { - if(!padder->valid_blocksize(cipher->block_size())) - throw Invalid_Block_Size(name(), padder->name()); - - state.resize(cipher->block_size()); - temp.resize(buffered_block_size()); - - set_key(key); - set_iv(iv); - } - -/* -* Set the IV -*/ -void CBC_Decryption::set_iv(const InitializationVector& iv) - { - if(!valid_iv_length(iv.length())) - throw Invalid_IV_Length(name(), iv.length()); - - state = iv.bits_of(); - buffer_reset(); - } - -/* -* Decrypt in CBC mode -*/ -void CBC_Decryption::buffered_block(const byte input[], size_t length) - { - const size_t blocks_in_temp = temp.size() / cipher->block_size(); - size_t blocks = length / cipher->block_size(); - - while(blocks) - { - size_t to_proc = std::min(blocks, blocks_in_temp); - - cipher->decrypt_n(input, &temp[0], to_proc); - - xor_buf(temp, state, cipher->block_size()); - - for(size_t i = 1; i < to_proc; ++i) - xor_buf(&temp[i * cipher->block_size()], - input + (i-1) * cipher->block_size(), - cipher->block_size()); - - copy_mem(&state[0], - input + (to_proc - 1) * cipher->block_size(), - cipher->block_size()); - - send(temp, to_proc * cipher->block_size()); - - input += to_proc * cipher->block_size(); - blocks -= to_proc; - } - } - -/* -* Finish encrypting in CBC mode -*/ -void CBC_Decryption::buffered_final(const byte input[], size_t length) - { - if(length == 0 || length % cipher->block_size() != 0) - throw Decoding_Error(name() + ": Ciphertext not multiple of block size"); - - size_t extra_blocks = (length - 1) / cipher->block_size(); - - buffered_block(input, extra_blocks * cipher->block_size()); - - input += extra_blocks * cipher->block_size(); - - cipher->decrypt(input, temp); - xor_buf(temp, state, cipher->block_size()); - send(temp, padder->unpad(temp, cipher->block_size())); - - copy_mem(&state[0], input, state.size()); // save for IV chaining - } - -/* -* Decrypt in CBC mode -*/ -void CBC_Decryption::write(const byte input[], size_t length) - { - Buffered_Filter::write(input, length); - } - -/* -* Finish decrypting in CBC mode -*/ -void CBC_Decryption::end_msg() - { - Buffered_Filter::end_msg(); - } - -/* -* Return a CBC mode name -*/ -std::string CBC_Decryption::name() const - { - return (cipher->name() + "/CBC/" + padder->name()); - } - -} -/* -* CFB Mode -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include - -namespace Botan { - -/* -* CFB Encryption Constructor -*/ -CFB_Encryption::CFB_Encryption(BlockCipher* ciph, size_t fback_bits) - { - cipher = ciph; - feedback = fback_bits ? fback_bits / 8: cipher->block_size(); - - buffer.resize(cipher->block_size()); - state.resize(cipher->block_size()); - position = 0; - - if(feedback == 0 || fback_bits % 8 != 0 || feedback > cipher->block_size()) - throw Invalid_Argument("CFB_Encryption: Invalid feedback size " + - to_string(fback_bits)); - } - -/* -* CFB Encryption Constructor -*/ -CFB_Encryption::CFB_Encryption(BlockCipher* ciph, - const SymmetricKey& key, - const InitializationVector& iv, - size_t fback_bits) - { - cipher = ciph; - feedback = fback_bits ? fback_bits / 8: cipher->block_size(); - - buffer.resize(cipher->block_size()); - state.resize(cipher->block_size()); - position = 0; - - if(feedback == 0 || fback_bits % 8 != 0 || feedback > cipher->block_size()) - throw Invalid_Argument("CFB_Encryption: Invalid feedback size " + - to_string(fback_bits)); - - set_key(key); - set_iv(iv); - } - -void CFB_Encryption::set_iv(const InitializationVector& iv) - { - if(!valid_iv_length(iv.length())) - throw Invalid_IV_Length(name(), iv.length()); - - state = iv.bits_of(); - zeroise(buffer); - position = 0; - - cipher->encrypt(state, buffer); - } - -/* -* Encrypt data in CFB mode -*/ -void CFB_Encryption::write(const byte input[], size_t length) - { - while(length) - { - size_t xored = std::min(feedback - position, length); - xor_buf(&buffer[position], input, xored); - send(&buffer[position], xored); - input += xored; - length -= xored; - position += xored; - - if(position == feedback) - { - for(size_t j = 0; j != cipher->block_size() - feedback; ++j) - state[j] = state[j + feedback]; - state.copy(cipher->block_size() - feedback, buffer, feedback); - cipher->encrypt(state, buffer); - position = 0; - } - } - } - -/* -* CFB Decryption Constructor -*/ -CFB_Decryption::CFB_Decryption(BlockCipher* ciph, size_t fback_bits) - { - cipher = ciph; - feedback = fback_bits ? fback_bits / 8: cipher->block_size(); - - buffer.resize(cipher->block_size()); - state.resize(cipher->block_size()); - position = 0; - - if(feedback == 0 || fback_bits % 8 != 0 || feedback > cipher->block_size()) - throw Invalid_Argument("CFB_Decryption: Invalid feedback size " + - to_string(fback_bits)); - } - -/* -* CFB Decryption Constructor -*/ -CFB_Decryption::CFB_Decryption(BlockCipher* ciph, - const SymmetricKey& key, - const InitializationVector& iv, - size_t fback_bits) - { - cipher = ciph; - feedback = fback_bits ? fback_bits / 8: cipher->block_size(); - - buffer.resize(cipher->block_size()); - state.resize(cipher->block_size()); - position = 0; - - if(feedback == 0 || fback_bits % 8 != 0 || feedback > cipher->block_size()) - throw Invalid_Argument("CFB_Decryption: Invalid feedback size " + - to_string(fback_bits)); - - set_key(key); - set_iv(iv); - } - -void CFB_Decryption::set_iv(const InitializationVector& iv) - { - if(!valid_iv_length(iv.length())) - throw Invalid_IV_Length(name(), iv.length()); - - state = iv.bits_of(); - zeroise(buffer); - position = 0; - - cipher->encrypt(state, buffer); - } - -/* -* Decrypt data in CFB mode -*/ -void CFB_Decryption::write(const byte input[], size_t length) - { - while(length) - { - size_t xored = std::min(feedback - position, length); - xor_buf(&buffer[position], input, xored); - send(&buffer[position], xored); - buffer.copy(position, input, xored); - input += xored; - length -= xored; - position += xored; - if(position == feedback) - { - for(size_t j = 0; j != cipher->block_size() - feedback; ++j) - state[j] = state[j + feedback]; - state.copy(cipher->block_size() - feedback, buffer, feedback); - cipher->encrypt(state, buffer); - position = 0; - } - } - } - -} -/* -* CTS Mode -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include - -namespace Botan { - -/* -* CTS Encryption Constructor -*/ -CTS_Encryption::CTS_Encryption(BlockCipher* ciph) : - cipher(ciph) - { - buffer.resize(2 * cipher->block_size()); - state.resize(cipher->block_size()); - position = 0; - } - -/* -* CTS Encryption Constructor -*/ -CTS_Encryption::CTS_Encryption(BlockCipher* ciph, - const SymmetricKey& key, - const InitializationVector& iv) : - cipher(ciph) - { - buffer.resize(2 * cipher->block_size()); - state.resize(cipher->block_size()); - position = 0; - - set_key(key); - set_iv(iv); - } - -/* -* Set the IV -*/ -void CTS_Encryption::set_iv(const InitializationVector& iv) - { - if(!valid_iv_length(iv.length())) - throw Invalid_IV_Length(name(), iv.length()); - - state = iv.bits_of(); - zeroise(buffer); - position = 0; - } - -/* -* Encrypt a block -*/ -void CTS_Encryption::encrypt(const byte block[]) - { - xor_buf(state, block, cipher->block_size()); - cipher->encrypt(state); - send(state, cipher->block_size()); - } - -/* -* Encrypt in CTS mode -*/ -void CTS_Encryption::write(const byte input[], size_t length) - { - size_t copied = std::min(buffer.size() - position, length); - buffer.copy(position, input, copied); - length -= copied; - input += copied; - position += copied; - - if(length == 0) return; - - encrypt(&buffer[0]); - if(length > cipher->block_size()) - { - encrypt(&buffer[cipher->block_size()]); - while(length > 2*cipher->block_size()) - { - encrypt(input); - length -= cipher->block_size(); - input += cipher->block_size(); - } - position = 0; - } - else - { - copy_mem(&buffer[0], &buffer[cipher->block_size()], cipher->block_size()); - position = cipher->block_size(); - } - buffer.copy(position, input, length); - position += length; - } - -/* -* Finish encrypting in CTS mode -*/ -void CTS_Encryption::end_msg() - { - if(position < cipher->block_size() + 1) - throw Encoding_Error(name() + ": insufficient data to encrypt"); - - xor_buf(state, buffer, cipher->block_size()); - cipher->encrypt(state); - SecureVector cn = state; - clear_mem(&buffer[position], buffer.size() - position); - encrypt(&buffer[cipher->block_size()]); - send(cn, position - cipher->block_size()); - } - -/* -* CTS Decryption Constructor -*/ -CTS_Decryption::CTS_Decryption(BlockCipher* ciph) : - cipher(ciph) - { - buffer.resize(2 * cipher->block_size()); - state.resize(cipher->block_size()); - temp.resize(cipher->block_size()); - position = 0; - } - -/* -* CTS Decryption Constructor -*/ -CTS_Decryption::CTS_Decryption(BlockCipher* ciph, - const SymmetricKey& key, - const InitializationVector& iv) : - cipher(ciph) - { - buffer.resize(2 * cipher->block_size()); - state.resize(cipher->block_size()); - temp.resize(cipher->block_size()); - position = 0; - - set_key(key); - set_iv(iv); - } - -/* -* Set the IV -*/ -void CTS_Decryption::set_iv(const InitializationVector& iv) - { - if(!valid_iv_length(iv.length())) - throw Invalid_IV_Length(name(), iv.length()); - - state = iv.bits_of(); - zeroise(buffer); - position = 0; - } - -/* -* Decrypt a block -*/ -void CTS_Decryption::decrypt(const byte block[]) - { - cipher->decrypt(block, &temp[0]); - xor_buf(temp, state, cipher->block_size()); - send(temp, cipher->block_size()); - state.copy(block, cipher->block_size()); - } - -/* -* Decrypt in CTS mode -*/ -void CTS_Decryption::write(const byte input[], size_t length) - { - size_t copied = std::min(buffer.size() - position, length); - buffer.copy(position, input, copied); - length -= copied; - input += copied; - position += copied; - - if(length == 0) return; - - decrypt(buffer); - if(length > cipher->block_size()) - { - decrypt(&buffer[cipher->block_size()]); - while(length > 2*cipher->block_size()) - { - decrypt(input); - length -= cipher->block_size(); - input += cipher->block_size(); - } - position = 0; - } - else - { - copy_mem(&buffer[0], &buffer[cipher->block_size()], cipher->block_size()); - position = cipher->block_size(); - } - buffer.copy(position, input, length); - position += length; - } - -/* -* Finish decrypting in CTS mode -*/ -void CTS_Decryption::end_msg() - { - cipher->decrypt(buffer, temp); - xor_buf(temp, &buffer[cipher->block_size()], position - cipher->block_size()); - - SecureVector xn = temp; - - copy_mem(&buffer[position], - &xn[position - cipher->block_size()], - buffer.size() - position); - - cipher->decrypt(&buffer[cipher->block_size()], temp); - xor_buf(temp, state, cipher->block_size()); - send(temp, cipher->block_size()); - send(xn, position - cipher->block_size()); - } - -} -/* -* EAX Mode Encryption -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include - -namespace Botan { - -namespace { - -/* -* EAX MAC-based PRF -*/ -SecureVector eax_prf(byte tag, size_t BLOCK_SIZE, - MessageAuthenticationCode* mac, - const byte in[], size_t length) - { - for(size_t i = 0; i != BLOCK_SIZE - 1; ++i) - mac->update(0); - mac->update(tag); - mac->update(in, length); - return mac->final(); - } - -} - -/* -* EAX_Base Constructor -*/ -EAX_Base::EAX_Base(BlockCipher* cipher, size_t tag_size) : - BLOCK_SIZE(cipher->block_size()), - TAG_SIZE(tag_size ? tag_size / 8 : BLOCK_SIZE), - cipher_name(cipher->name()), - ctr_buf(DEFAULT_BUFFERSIZE) - { - cmac = new CMAC(cipher->clone()); - ctr = new CTR_BE(cipher); // takes ownership - - if(tag_size % 8 != 0 || TAG_SIZE == 0 || TAG_SIZE > cmac->output_length()) - throw Invalid_Argument(name() + ": Bad tag size " + to_string(tag_size)); - } - -/* -* Check if a keylength is valid for EAX -*/ -bool EAX_Base::valid_keylength(size_t n) const - { - if(!ctr->valid_keylength(n)) - return false; - return true; - } - -/* -* Set the EAX key -*/ -void EAX_Base::set_key(const SymmetricKey& key) - { - /* - * These could share the key schedule, which is one nice part of EAX, - * but it's much easier to ignore that here... - */ - ctr->set_key(key); - cmac->set_key(key); - - header_mac = eax_prf(1, BLOCK_SIZE, cmac, 0, 0); - } - -/* -* Do setup at the start of each message -*/ -void EAX_Base::start_msg() - { - for(size_t i = 0; i != BLOCK_SIZE - 1; ++i) - cmac->update(0); - cmac->update(2); - } - -/* -* Set the EAX nonce -*/ -void EAX_Base::set_iv(const InitializationVector& iv) - { - nonce_mac = eax_prf(0, BLOCK_SIZE, cmac, iv.begin(), iv.length()); - ctr->set_iv(&nonce_mac[0], nonce_mac.size()); - } - -/* -* Set the EAX header -*/ -void EAX_Base::set_header(const byte header[], size_t length) - { - header_mac = eax_prf(1, BLOCK_SIZE, cmac, header, length); - } - -/* -* Return the name of this cipher mode -*/ -std::string EAX_Base::name() const - { - return (cipher_name + "/EAX"); - } - -/* -* Encrypt in EAX mode -*/ -void EAX_Encryption::write(const byte input[], size_t length) - { - while(length) - { - size_t copied = std::min(length, ctr_buf.size()); - - ctr->cipher(input, &ctr_buf[0], copied); - cmac->update(&ctr_buf[0], copied); - - send(ctr_buf, copied); - input += copied; - length -= copied; - } - } - -/* -* Finish encrypting in EAX mode -*/ -void EAX_Encryption::end_msg() - { - SecureVector data_mac = cmac->final(); - xor_buf(data_mac, nonce_mac, data_mac.size()); - xor_buf(data_mac, header_mac, data_mac.size()); - - send(data_mac, TAG_SIZE); - } - -} -/* -* EAX Mode Encryption -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include - -namespace Botan { - -/* -* EAX_Decryption Constructor -*/ -EAX_Decryption::EAX_Decryption(BlockCipher* ciph, - size_t tag_size) : - EAX_Base(ciph, tag_size) - { - queue.resize(2*TAG_SIZE + DEFAULT_BUFFERSIZE); - queue_start = queue_end = 0; - } - -/* -* EAX_Decryption Constructor -*/ -EAX_Decryption::EAX_Decryption(BlockCipher* ciph, - const SymmetricKey& key, - const InitializationVector& iv, - size_t tag_size) : - EAX_Base(ciph, tag_size) - { - set_key(key); - set_iv(iv); - queue.resize(2*TAG_SIZE + DEFAULT_BUFFERSIZE); - queue_start = queue_end = 0; - } - -/* -* Decrypt in EAX mode -*/ -void EAX_Decryption::write(const byte input[], size_t length) - { - while(length) - { - const size_t copied = std::min(length, queue.size() - queue_end); - - queue.copy(queue_end, input, copied); - input += copied; - length -= copied; - queue_end += copied; - - while((queue_end - queue_start) > TAG_SIZE) - { - size_t removed = (queue_end - queue_start) - TAG_SIZE; - do_write(&queue[queue_start], removed); - queue_start += removed; - } - - if(queue_start + TAG_SIZE == queue_end && - queue_start >= queue.size() / 2) - { - SecureVector queue_data(TAG_SIZE); - queue_data.copy(&queue[queue_start], TAG_SIZE); - queue.copy(&queue_data[0], TAG_SIZE); - queue_start = 0; - queue_end = TAG_SIZE; - } - } - } - -/* -* Decrypt in EAX mode -*/ -void EAX_Decryption::do_write(const byte input[], size_t length) - { - while(length) - { - size_t copied = std::min(length, ctr_buf.size()); - - /* - Process same block with cmac and ctr at the same time to - help cache locality. - */ - cmac->update(input, copied); - ctr->cipher(input, &ctr_buf[0], copied); - send(ctr_buf, copied); - input += copied; - length -= copied; - } - } - -/* -* Finish decrypting in EAX mode -*/ -void EAX_Decryption::end_msg() - { - if((queue_end - queue_start) != TAG_SIZE) - throw Decoding_Error(name() + ": Message authentication failure"); - - SecureVector data_mac = cmac->final(); - - for(size_t j = 0; j != TAG_SIZE; ++j) - if(queue[queue_start+j] != (data_mac[j] ^ nonce_mac[j] ^ header_mac[j])) - throw Decoding_Error(name() + ": Message authentication failure"); - - queue_start = queue_end = 0; - } - -} -/* -* ECB Mode -* (C) 1999-2009 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -/* -* ECB_Encryption Constructor -*/ -ECB_Encryption::ECB_Encryption(BlockCipher* ciph, - BlockCipherModePaddingMethod* pad) : - Buffered_Filter(ciph->parallel_bytes(), 0) - { - cipher = ciph; - padder = pad; - - temp.resize(buffered_block_size()); - } - -/* -* ECB_Encryption Constructor -*/ -ECB_Encryption::ECB_Encryption(BlockCipher* ciph, - BlockCipherModePaddingMethod* pad, - const SymmetricKey& key) : - Buffered_Filter(ciph->parallel_bytes(), 0) - { - cipher = ciph; - padder = pad; - - temp.resize(buffered_block_size()); - - cipher->set_key(key); - } - -/* -* ECB_Encryption Destructor -*/ -ECB_Encryption::~ECB_Encryption() - { - delete cipher; - delete padder; - } - -/* -* Return an ECB mode name -*/ -std::string ECB_Encryption::name() const - { - return (cipher->name() + "/ECB/" + padder->name()); - } - -/* -* Encrypt in ECB mode -*/ -void ECB_Encryption::write(const byte input[], size_t length) - { - Buffered_Filter::write(input, length); - } - -/* -* Finish encrypting in ECB mode -*/ -void ECB_Encryption::end_msg() - { - size_t last_block = current_position() % cipher->block_size(); - - SecureVector padding(cipher->block_size()); - padder->pad(padding, padding.size(), last_block); - - size_t pad_bytes = padder->pad_bytes(cipher->block_size(), last_block); - - if(pad_bytes) - Buffered_Filter::write(padding, pad_bytes); - Buffered_Filter::end_msg(); - } - -void ECB_Encryption::buffered_block(const byte input[], size_t input_length) - { - const size_t blocks_in_temp = temp.size() / cipher->block_size(); - size_t blocks = input_length / cipher->block_size(); - - while(blocks) - { - size_t to_proc = std::min(blocks, blocks_in_temp); - - cipher->encrypt_n(input, &temp[0], to_proc); - - send(temp, to_proc * cipher->block_size()); - - input += to_proc * cipher->block_size(); - blocks -= to_proc; - } - } - -void ECB_Encryption::buffered_final(const byte input[], size_t input_length) - { - if(input_length % cipher->block_size() == 0) - buffered_block(input, input_length); - else if(input_length != 0) - throw Encoding_Error(name() + ": Did not pad to full blocksize"); - } - -/* -* ECB_Decryption Constructor -*/ -ECB_Decryption::ECB_Decryption(BlockCipher* ciph, - BlockCipherModePaddingMethod* pad) : - Buffered_Filter(ciph->parallel_bytes(), 1) - { - cipher = ciph; - padder = pad; - - temp.resize(buffered_block_size()); - } - -/* -* ECB_Decryption Constructor -*/ -ECB_Decryption::ECB_Decryption(BlockCipher* ciph, - BlockCipherModePaddingMethod* pad, - const SymmetricKey& key) : - Buffered_Filter(ciph->parallel_bytes(), 1) - { - cipher = ciph; - padder = pad; - - temp.resize(buffered_block_size()); - - cipher->set_key(key); - } - -/* -* ECB_Decryption Destructor -*/ -ECB_Decryption::~ECB_Decryption() - { - delete cipher; - delete padder; - } - -/* -* Return an ECB mode name -*/ -std::string ECB_Decryption::name() const - { - return (cipher->name() + "/ECB/" + padder->name()); - } - -/* -* Decrypt in ECB mode -*/ -void ECB_Decryption::write(const byte input[], size_t length) - { - Buffered_Filter::write(input, length); - } - -/* -* Finish decrypting in ECB mode -*/ -void ECB_Decryption::end_msg() - { - Buffered_Filter::end_msg(); - } - -/* -* Decrypt in ECB mode -*/ -void ECB_Decryption::buffered_block(const byte input[], size_t length) - { - const size_t blocks_in_temp = temp.size() / cipher->block_size(); - size_t blocks = length / cipher->block_size(); - - while(blocks) - { - size_t to_proc = std::min(blocks, blocks_in_temp); - - cipher->decrypt_n(input, &temp[0], to_proc); - - send(temp, to_proc * cipher->block_size()); - - input += to_proc * cipher->block_size(); - blocks -= to_proc; - } - } - -/* -* Finish encrypting in ECB mode -*/ -void ECB_Decryption::buffered_final(const byte input[], size_t length) - { - if(length == 0 || length % cipher->block_size() != 0) - throw Decoding_Error(name() + ": Ciphertext not multiple of block size"); - - size_t extra_blocks = (length - 1) / cipher->block_size(); - - buffered_block(input, extra_blocks * cipher->block_size()); - - input += extra_blocks * cipher->block_size(); - - cipher->decrypt(input, temp); - send(temp, padder->unpad(temp, cipher->block_size())); - } - -} -/* -* CBC Padding Methods -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -/* -* Default amount of padding -*/ -size_t BlockCipherModePaddingMethod::pad_bytes(size_t bs, size_t pos) const - { - return (bs - pos); - } - -/* -* Pad with PKCS #7 Method -*/ -void PKCS7_Padding::pad(byte block[], size_t size, size_t position) const - { - const size_t bytes_remaining = size - position; - const byte pad_value = static_cast(bytes_remaining); - - BOTAN_ASSERT_EQUAL(pad_value, bytes_remaining, - "Overflow in PKCS7_Padding"); - - for(size_t j = 0; j != size; ++j) - block[j] = pad_value; - } - -/* -* Unpad with PKCS #7 Method -*/ -size_t PKCS7_Padding::unpad(const byte block[], size_t size) const - { - size_t position = block[size-1]; - if(position > size) - throw Decoding_Error(name()); - for(size_t j = size-position; j != size-1; ++j) - if(block[j] != position) - throw Decoding_Error(name()); - return (size-position); - } - -/* -* Query if the size is valid for this method -*/ -bool PKCS7_Padding::valid_blocksize(size_t size) const - { - if(size > 0 && size < 256) - return true; - else - return false; - } - -/* -* Pad with ANSI X9.23 Method -*/ -void ANSI_X923_Padding::pad(byte block[], size_t size, size_t position) const - { - for(size_t j = 0; j != size-position; ++j) - block[j] = 0; - block[size-position-1] = static_cast(size-position); - } - -/* -* Unpad with ANSI X9.23 Method -*/ -size_t ANSI_X923_Padding::unpad(const byte block[], size_t size) const - { - size_t position = block[size-1]; - if(position > size) - throw Decoding_Error(name()); - for(size_t j = size-position; j != size-1; ++j) - if(block[j] != 0) - throw Decoding_Error(name()); - return (size-position); - } - -/* -* Query if the size is valid for this method -*/ -bool ANSI_X923_Padding::valid_blocksize(size_t size) const - { - if(size > 0 && size < 256) - return true; - else - return false; - } - -/* -* Pad with One and Zeros Method -*/ -void OneAndZeros_Padding::pad(byte block[], size_t size, size_t) const - { - block[0] = 0x80; - for(size_t j = 1; j != size; ++j) - block[j] = 0x00; - } - -/* -* Unpad with One and Zeros Method -*/ -size_t OneAndZeros_Padding::unpad(const byte block[], size_t size) const - { - while(size) - { - if(block[size-1] == 0x80) - break; - if(block[size-1] != 0x00) - throw Decoding_Error(name()); - size--; - } - if(!size) - throw Decoding_Error(name()); - return (size-1); - } - -/* -* Query if the size is valid for this method -*/ -bool OneAndZeros_Padding::valid_blocksize(size_t size) const - { - return (size > 0); - } - -} -/* -* XTS Mode -* (C) 2009 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include -#include - -namespace Botan { - -namespace { - -void poly_double(byte tweak[], size_t size) - { - const byte polynomial = (size == 16) ? 0x87 : 0x1B; - - byte carry = 0; - for(size_t i = 0; i != size; ++i) - { - byte carry2 = (tweak[i] >> 7); - tweak[i] = (tweak[i] << 1) | carry; - carry = carry2; - } - - if(carry) - tweak[0] ^= polynomial; - } - -/* XTS needs to process at least 2 blocks in parallel - because block_size+1 bytes are needed at the end -*/ -size_t xts_parallelism(BlockCipher* cipher) - { - return std::max(cipher->parallel_bytes(), - 2 * cipher->block_size()); - } - -} - -/* -* XTS_Encryption constructor -*/ -XTS_Encryption::XTS_Encryption(BlockCipher* ciph) : - Buffered_Filter(xts_parallelism(ciph), ciph->block_size() + 1), - cipher(ciph) - { - if(cipher->block_size() != 8 && cipher->block_size() != 16) - throw std::invalid_argument("Bad cipher for XTS: " + cipher->name()); - - cipher2 = cipher->clone(); - tweak.resize(buffered_block_size()); - } - -/* -* XTS_Encryption constructor -*/ -XTS_Encryption::XTS_Encryption(BlockCipher* ciph, - const SymmetricKey& key, - const InitializationVector& iv) : - Buffered_Filter(xts_parallelism(ciph), ciph->block_size() + 1), - cipher(ciph) - { - if(cipher->block_size() != 8 && cipher->block_size() != 16) - throw std::invalid_argument("Bad cipher for XTS: " + cipher->name()); - - cipher2 = cipher->clone(); - tweak.resize(buffered_block_size()); - - set_key(key); - set_iv(iv); - } - -/* -* Return the name -*/ -std::string XTS_Encryption::name() const - { - return (cipher->name() + "/XTS"); - } - -/* -* Set new tweak -*/ -void XTS_Encryption::set_iv(const InitializationVector& iv) - { - if(!valid_iv_length(iv.length())) - throw Invalid_IV_Length(name(), iv.length()); - - const size_t blocks_in_tweak = tweak.size() / cipher->block_size(); - - tweak.copy(iv.begin(), iv.length()); - cipher2->encrypt(tweak); - - for(size_t i = 1; i < blocks_in_tweak; ++i) - { - tweak.copy(i*cipher->block_size(), - &tweak[(i-1)*cipher->block_size()], - cipher->block_size()); - - poly_double(&tweak[i*cipher->block_size()], cipher->block_size()); - } - } - -void XTS_Encryption::set_key(const SymmetricKey& key) - { - size_t key_half = key.length() / 2; - - if(key.length() % 2 == 1 || !cipher->valid_keylength(key_half)) - throw Invalid_Key_Length(name(), key.length()); - - cipher->set_key(key.begin(), key_half); - cipher2->set_key(key.begin() + key_half, key_half); - } - -/* -* Encrypt in XTS mode -*/ -void XTS_Encryption::write(const byte input[], size_t length) - { - Buffered_Filter::write(input, length); - } -/* -* Finish encrypting in XTS mode -*/ -void XTS_Encryption::end_msg() - { - Buffered_Filter::end_msg(); - } - -void XTS_Encryption::buffered_block(const byte input[], size_t length) - { - const size_t blocks_in_tweak = tweak.size() / cipher->block_size(); - size_t blocks = length / cipher->block_size(); - - SecureVector temp(tweak.size()); - - while(blocks) - { - size_t to_proc = std::min(blocks, blocks_in_tweak); - size_t to_proc_bytes = to_proc * cipher->block_size(); - - xor_buf(temp, input, tweak, to_proc_bytes); - - cipher->encrypt_n(&temp[0], &temp[0], to_proc); - - xor_buf(temp, tweak, to_proc_bytes); - - send(temp, to_proc_bytes); - - tweak.copy(&tweak[(to_proc-1)*cipher->block_size()], - cipher->block_size()); - poly_double(&tweak[0], cipher->block_size()); - - for(size_t i = 1; i < blocks_in_tweak; ++i) - { - tweak.copy(i*cipher->block_size(), - &tweak[(i-1)*cipher->block_size()], - cipher->block_size()); - - poly_double(&tweak[i*cipher->block_size()], cipher->block_size()); - } - - input += to_proc * cipher->block_size(); - blocks -= to_proc; - } - } - -/* -* Finish encrypting in XTS mode -*/ -void XTS_Encryption::buffered_final(const byte input[], size_t length) - { - if(length <= cipher->block_size()) - throw Encoding_Error("XTS_Encryption: insufficient data to encrypt"); - - if(length % cipher->block_size() == 0) - { - buffered_block(input, length); - } - else - { // steal ciphertext - - size_t leftover_blocks = - ((length / cipher->block_size()) - 1) * cipher->block_size(); - - buffered_block(input, leftover_blocks); - - input += leftover_blocks; - length -= leftover_blocks; - - SecureVector temp(input, length); - - xor_buf(temp, tweak, cipher->block_size()); - cipher->encrypt(temp); - xor_buf(temp, tweak, cipher->block_size()); - - poly_double(&tweak[0], cipher->block_size()); - - for(size_t i = 0; i != length - cipher->block_size(); ++i) - std::swap(temp[i], temp[i + cipher->block_size()]); - - xor_buf(temp, tweak, cipher->block_size()); - cipher->encrypt(temp); - xor_buf(temp, tweak, cipher->block_size()); - - send(temp, temp.size()); - } - - buffer_reset(); - } - -/* -* XTS_Decryption constructor -*/ -XTS_Decryption::XTS_Decryption(BlockCipher* ciph) : - Buffered_Filter(xts_parallelism(ciph), ciph->block_size() + 1), - cipher(ciph) - { - if(cipher->block_size() != 8 && cipher->block_size() != 16) - throw std::invalid_argument("Bad cipher for XTS: " + cipher->name()); - - cipher2 = ciph->clone(); - tweak.resize(buffered_block_size()); - } - -/* -* XTS_Decryption constructor -*/ -XTS_Decryption::XTS_Decryption(BlockCipher* ciph, - const SymmetricKey& key, - const InitializationVector& iv) : - Buffered_Filter(xts_parallelism(ciph), ciph->block_size() + 1), - cipher(ciph) - { - if(cipher->block_size() != 8 && cipher->block_size() != 16) - throw std::invalid_argument("Bad cipher for XTS: " + cipher->name()); - - cipher2 = ciph->clone(); - tweak.resize(buffered_block_size()); - - set_key(key); - set_iv(iv); - } - -/* -* Return the name -*/ -std::string XTS_Decryption::name() const - { - return (cipher->name() + "/XTS"); - } - -/* -* Set new tweak -*/ -void XTS_Decryption::set_iv(const InitializationVector& iv) - { - if(!valid_iv_length(iv.length())) - throw Invalid_IV_Length(name(), iv.length()); - - const size_t blocks_in_tweak = tweak.size() / cipher->block_size(); - - tweak.copy(iv.begin(), iv.length()); - cipher2->encrypt(tweak); - - for(size_t i = 1; i < blocks_in_tweak; ++i) - { - tweak.copy(i*cipher->block_size(), - &tweak[(i-1)*cipher->block_size()], - cipher->block_size()); - - poly_double(&tweak[i*cipher->block_size()], cipher->block_size()); - } - } - -void XTS_Decryption::set_key(const SymmetricKey& key) - { - size_t key_half = key.length() / 2; - - if(key.length() % 2 == 1 || !cipher->valid_keylength(key_half)) - throw Invalid_Key_Length(name(), key.length()); - - cipher->set_key(key.begin(), key_half); - cipher2->set_key(key.begin() + key_half, key_half); - } - -/* -* Decrypt in XTS mode -*/ -void XTS_Decryption::write(const byte input[], size_t length) - { - Buffered_Filter::write(input, length); - } - -/* -* Finish decrypting in XTS mode -*/ -void XTS_Decryption::end_msg() - { - Buffered_Filter::end_msg(); - } - -void XTS_Decryption::buffered_block(const byte input[], size_t input_length) - { - const size_t blocks_in_tweak = tweak.size() / cipher->block_size(); - size_t blocks = input_length / cipher->block_size(); - - SecureVector temp(tweak.size()); - - while(blocks) - { - size_t to_proc = std::min(blocks, blocks_in_tweak); - size_t to_proc_bytes = to_proc * cipher->block_size(); - - xor_buf(temp, input, tweak, to_proc_bytes); - - cipher->decrypt_n(&temp[0], &temp[0], to_proc); - - xor_buf(temp, tweak, to_proc_bytes); - - send(temp, to_proc_bytes); - - tweak.copy(&tweak[(to_proc-1)*cipher->block_size()], - cipher->block_size()); - poly_double(&tweak[0], cipher->block_size()); - - for(size_t i = 1; i < blocks_in_tweak; ++i) - { - tweak.copy(i*cipher->block_size(), - &tweak[(i-1)*cipher->block_size()], - cipher->block_size()); - - poly_double(&tweak[i*cipher->block_size()], cipher->block_size()); - } - - input += to_proc * cipher->block_size(); - blocks -= to_proc; - } - } - -void XTS_Decryption::buffered_final(const byte input[], size_t length) - { - if(length <= cipher->block_size()) - throw Decoding_Error("XTS_Decryption: insufficient data to decrypt"); - - if(length % cipher->block_size() == 0) - { - buffered_block(input, length); - } - else - { - size_t leftover_blocks = - ((length / cipher->block_size()) - 1) * cipher->block_size(); - - buffered_block(input, leftover_blocks); - - input += leftover_blocks; - length -= leftover_blocks; - - SecureVector temp(input, length); - SecureVector tweak_copy(&tweak[0], cipher->block_size()); - - poly_double(&tweak_copy[0], cipher->block_size()); - - xor_buf(temp, tweak_copy, cipher->block_size()); - cipher->decrypt(temp); - xor_buf(temp, tweak_copy, cipher->block_size()); - - for(size_t i = 0; i != length - cipher->block_size(); ++i) - std::swap(temp[i], temp[i + cipher->block_size()]); - - xor_buf(temp, tweak, cipher->block_size()); - cipher->decrypt(temp); - xor_buf(temp, tweak, cipher->block_size()); - - send(temp, length); - } - - buffer_reset(); - } - -} -/* -* Pipe Output Buffer -* (C) 1999-2007,2011 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -/* -* Read data from a message -*/ -size_t Output_Buffers::read(byte output[], size_t length, - Pipe::message_id msg) - { - SecureQueue* q = get(msg); - if(q) - return q->read(output, length); - return 0; - } - -/* -* Peek at data in a message -*/ -size_t Output_Buffers::peek(byte output[], size_t length, - size_t stream_offset, - Pipe::message_id msg) const - { - SecureQueue* q = get(msg); - if(q) - return q->peek(output, length, stream_offset); - return 0; - } - -/* -* Check available bytes in a message -*/ -size_t Output_Buffers::remaining(Pipe::message_id msg) const - { - SecureQueue* q = get(msg); - if(q) - return q->size(); - return 0; - } - -/* -* Add a new output queue -*/ -void Output_Buffers::add(SecureQueue* queue) - { - BOTAN_ASSERT(queue, "argument was NULL"); - - BOTAN_ASSERT(buffers.size() < buffers.max_size(), - "No more room in container"); - - buffers.push_back(queue); - } - -/* -* Retire old output queues -*/ -void Output_Buffers::retire() - { - for(size_t i = 0; i != buffers.size(); ++i) - if(buffers[i] && buffers[i]->size() == 0) - { - delete buffers[i]; - buffers[i] = 0; - } - - while(buffers.size() && !buffers[0]) - { - buffers.pop_front(); - offset = offset + Pipe::message_id(1); - } - } - -/* -* Get a particular output queue -*/ -SecureQueue* Output_Buffers::get(Pipe::message_id msg) const - { - if(msg < offset) - return 0; - - BOTAN_ASSERT(msg < message_count(), - "Message number out of range"); - - return buffers[msg-offset]; - } - -/* -* Return the total number of messages -*/ -Pipe::message_id Output_Buffers::message_count() const - { - return (offset + buffers.size()); - } - -/* -* Output_Buffers Constructor -*/ -Output_Buffers::Output_Buffers() - { - offset = 0; - } - -/* -* Output_Buffers Destructor -*/ -Output_Buffers::~Output_Buffers() - { - for(size_t j = 0; j != buffers.size(); ++j) - delete buffers[j]; - } - -} -/* -* Pipe -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -namespace { - -/* -* A Filter that does nothing -*/ -class Null_Filter : public Filter - { - public: - void write(const byte input[], size_t length) - { send(input, length); } - - std::string name() const { return "Null"; } - }; - -} - -/* -* Pipe Constructor -*/ -Pipe::Pipe(Filter* f1, Filter* f2, Filter* f3, Filter* f4) - { - init(); - append(f1); - append(f2); - append(f3); - append(f4); - } - -/* -* Pipe Constructor -*/ -Pipe::Pipe(Filter* filter_array[], size_t count) - { - init(); - for(size_t j = 0; j != count; ++j) - append(filter_array[j]); - } - -/* -* Pipe Destructor -*/ -Pipe::~Pipe() - { - destruct(pipe); - delete outputs; - } - -/* -* Initialize the Pipe -*/ -void Pipe::init() - { - outputs = new Output_Buffers; - pipe = 0; - default_read = 0; - inside_msg = false; - } - -/* -* Reset the Pipe -*/ -void Pipe::reset() - { - destruct(pipe); - pipe = 0; - inside_msg = false; - } - -/* -* Destroy the Pipe -*/ -void Pipe::destruct(Filter* to_kill) - { - if(!to_kill || dynamic_cast(to_kill)) - return; - for(size_t j = 0; j != to_kill->total_ports(); ++j) - destruct(to_kill->next[j]); - delete to_kill; - } - -/* -* Test if the Pipe has any data in it -*/ -bool Pipe::end_of_data() const - { - return (remaining() == 0); - } - -/* -* Set the default read message -*/ -void Pipe::set_default_msg(message_id msg) - { - if(msg >= message_count()) - throw Invalid_Argument("Pipe::set_default_msg: msg number is too high"); - default_read = msg; - } - -/* -* Process a full message at once -*/ -void Pipe::process_msg(const byte input[], size_t length) - { - start_msg(); - write(input, length); - end_msg(); - } - -/* -* Process a full message at once -*/ -void Pipe::process_msg(const MemoryRegion& input) - { - process_msg(&input[0], input.size()); - } - -/* -* Process a full message at once -*/ -void Pipe::process_msg(const std::string& input) - { - process_msg(reinterpret_cast(input.data()), input.length()); - } - -/* -* Process a full message at once -*/ -void Pipe::process_msg(DataSource& input) - { - start_msg(); - write(input); - end_msg(); - } - -/* -* Start a new message -*/ -void Pipe::start_msg() - { - if(inside_msg) - throw Invalid_State("Pipe::start_msg: Message was already started"); - if(pipe == 0) - pipe = new Null_Filter; - find_endpoints(pipe); - pipe->new_msg(); - inside_msg = true; - } - -/* -* End the current message -*/ -void Pipe::end_msg() - { - if(!inside_msg) - throw Invalid_State("Pipe::end_msg: Message was already ended"); - pipe->finish_msg(); - clear_endpoints(pipe); - if(dynamic_cast(pipe)) - { - delete pipe; - pipe = 0; - } - inside_msg = false; - - outputs->retire(); - } - -/* -* Find the endpoints of the Pipe -*/ -void Pipe::find_endpoints(Filter* f) - { - for(size_t j = 0; j != f->total_ports(); ++j) - if(f->next[j] && !dynamic_cast(f->next[j])) - find_endpoints(f->next[j]); - else - { - SecureQueue* q = new SecureQueue; - f->next[j] = q; - outputs->add(q); - } - } - -/* -* Remove the SecureQueues attached to the Filter -*/ -void Pipe::clear_endpoints(Filter* f) - { - if(!f) return; - for(size_t j = 0; j != f->total_ports(); ++j) - { - if(f->next[j] && dynamic_cast(f->next[j])) - f->next[j] = 0; - clear_endpoints(f->next[j]); - } - } - -/* -* Append a Filter to the Pipe -*/ -void Pipe::append(Filter* filter) - { - if(inside_msg) - throw Invalid_State("Cannot append to a Pipe while it is processing"); - if(!filter) - return; - if(dynamic_cast(filter)) - throw Invalid_Argument("Pipe::append: SecureQueue cannot be used"); - if(filter->owned) - throw Invalid_Argument("Filters cannot be shared among multiple Pipes"); - - filter->owned = true; - - if(!pipe) pipe = filter; - else pipe->attach(filter); - } - -/* -* Prepend a Filter to the Pipe -*/ -void Pipe::prepend(Filter* filter) - { - if(inside_msg) - throw Invalid_State("Cannot prepend to a Pipe while it is processing"); - if(!filter) - return; - if(dynamic_cast(filter)) - throw Invalid_Argument("Pipe::prepend: SecureQueue cannot be used"); - if(filter->owned) - throw Invalid_Argument("Filters cannot be shared among multiple Pipes"); - - filter->owned = true; - - if(pipe) filter->attach(pipe); - pipe = filter; - } - -/* -* Pop a Filter off the Pipe -*/ -void Pipe::pop() - { - if(inside_msg) - throw Invalid_State("Cannot pop off a Pipe while it is processing"); - - if(!pipe) - return; - - if(pipe->total_ports() > 1) - throw Invalid_State("Cannot pop off a Filter with multiple ports"); - - Filter* f = pipe; - size_t owns = f->owns(); - pipe = pipe->next[0]; - delete f; - - while(owns--) - { - f = pipe; - pipe = pipe->next[0]; - delete f; - } - } - -/* -* Return the number of messages in this Pipe -*/ -Pipe::message_id Pipe::message_count() const - { - return outputs->message_count(); - } - -/* -* Static Member Variables -*/ -const Pipe::message_id Pipe::LAST_MESSAGE = - static_cast(-2); - -const Pipe::message_id Pipe::DEFAULT_MESSAGE = - static_cast(-1); - -} -/* -* Pipe I/O -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include - -namespace Botan { - -/* -* Write data from a pipe into an ostream -*/ -std::ostream& operator<<(std::ostream& stream, Pipe& pipe) - { - SecureVector buffer(DEFAULT_BUFFERSIZE); - while(stream.good() && pipe.remaining()) - { - size_t got = pipe.read(&buffer[0], buffer.size()); - stream.write(reinterpret_cast(&buffer[0]), got); - } - if(!stream.good()) - throw Stream_IO_Error("Pipe output operator (iostream) has failed"); - return stream; - } - -/* -* Read data from an istream into a pipe -*/ -std::istream& operator>>(std::istream& stream, Pipe& pipe) - { - SecureVector buffer(DEFAULT_BUFFERSIZE); - while(stream.good()) - { - stream.read(reinterpret_cast(&buffer[0]), buffer.size()); - pipe.write(&buffer[0], stream.gcount()); - } - if(stream.bad() || (stream.fail() && !stream.eof())) - throw Stream_IO_Error("Pipe input operator (iostream) has failed"); - return stream; - } - -} -/* -* Pipe Reading/Writing -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -/* -* Look up the canonical ID for a queue -*/ -Pipe::message_id Pipe::get_message_no(const std::string& func_name, - message_id msg) const - { - if(msg == DEFAULT_MESSAGE) - msg = default_msg(); - else if(msg == LAST_MESSAGE) - msg = message_count() - 1; - - if(msg >= message_count()) - throw Invalid_Message_Number(func_name, msg); - - return msg; - } - -/* -* Write into a Pipe -*/ -void Pipe::write(const byte input[], size_t length) - { - if(!inside_msg) - throw Invalid_State("Cannot write to a Pipe while it is not processing"); - pipe->write(input, length); - } - -/* -* Write into a Pipe -*/ -void Pipe::write(const MemoryRegion& input) - { - write(&input[0], input.size()); - } - -/* -* Write a string into a Pipe -*/ -void Pipe::write(const std::string& str) - { - write(reinterpret_cast(str.data()), str.size()); - } - -/* -* Write a single byte into a Pipe -*/ -void Pipe::write(byte input) - { - write(&input, 1); - } - -/* -* Write the contents of a DataSource into a Pipe -*/ -void Pipe::write(DataSource& source) - { - SecureVector buffer(DEFAULT_BUFFERSIZE); - while(!source.end_of_data()) - { - size_t got = source.read(&buffer[0], buffer.size()); - write(&buffer[0], got); - } - } - -/* -* Read some data from the pipe -*/ -size_t Pipe::read(byte output[], size_t length, message_id msg) - { - return outputs->read(output, length, get_message_no("read", msg)); - } - -/* -* Read some data from the pipe -*/ -size_t Pipe::read(byte output[], size_t length) - { - return read(output, length, DEFAULT_MESSAGE); - } - -/* -* Read a single byte from the pipe -*/ -size_t Pipe::read(byte& out, message_id msg) - { - return read(&out, 1, msg); - } - -/* -* Return all data in the pipe -*/ -SecureVector Pipe::read_all(message_id msg) - { - msg = ((msg != DEFAULT_MESSAGE) ? msg : default_msg()); - SecureVector buffer(remaining(msg)); - size_t got = read(&buffer[0], buffer.size(), msg); - buffer.resize(got); - return buffer; - } - -/* -* Return all data in the pipe as a string -*/ -std::string Pipe::read_all_as_string(message_id msg) - { - msg = ((msg != DEFAULT_MESSAGE) ? msg : default_msg()); - SecureVector buffer(DEFAULT_BUFFERSIZE); - std::string str; - str.reserve(remaining(msg)); - - while(true) - { - size_t got = read(&buffer[0], buffer.size(), msg); - if(got == 0) - break; - str.append(reinterpret_cast(&buffer[0]), got); - } - - return str; - } - -/* -* Find out how many bytes are ready to read -*/ -size_t Pipe::remaining(message_id msg) const - { - return outputs->remaining(get_message_no("remaining", msg)); - } - -/* -* Peek at some data in the pipe -*/ -size_t Pipe::peek(byte output[], size_t length, - size_t offset, message_id msg) const - { - return outputs->peek(output, length, offset, get_message_no("peek", msg)); - } - -/* -* Peek at some data in the pipe -*/ -size_t Pipe::peek(byte output[], size_t length, size_t offset) const - { - return peek(output, length, offset, DEFAULT_MESSAGE); - } - -/* -* Peek at a byte in the pipe -*/ -size_t Pipe::peek(byte& out, size_t offset, message_id msg) const - { - return peek(&out, 1, offset, msg); - } - -} -/* -* PK Filters -* (C) 1999-2009 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -/* -* Append to the buffer -*/ -void PK_Encryptor_Filter::write(const byte input[], size_t length) - { - buffer += std::make_pair(input, length); - } - -/* -* Encrypt the message -*/ -void PK_Encryptor_Filter::end_msg() - { - send(cipher->encrypt(buffer, rng)); - buffer.clear(); - } - -/* -* Append to the buffer -*/ -void PK_Decryptor_Filter::write(const byte input[], size_t length) - { - buffer += std::make_pair(input, length); - } - -/* -* Decrypt the message -*/ -void PK_Decryptor_Filter::end_msg() - { - send(cipher->decrypt(buffer)); - buffer.clear(); - } - -/* -* Add more data -*/ -void PK_Signer_Filter::write(const byte input[], size_t length) - { - signer->update(input, length); - } - -/* -* Sign the message -*/ -void PK_Signer_Filter::end_msg() - { - send(signer->signature(rng)); - } - -/* -* Add more data -*/ -void PK_Verifier_Filter::write(const byte input[], size_t length) - { - verifier->update(input, length); - } - -/* -* Verify the message -*/ -void PK_Verifier_Filter::end_msg() - { - if(signature.empty()) - throw Invalid_State("PK_Verifier_Filter: No signature to check against"); - bool is_valid = verifier->check_signature(signature); - send((is_valid ? 1 : 0)); - } - -/* -* Set the signature to check -*/ -void PK_Verifier_Filter::set_signature(const byte sig[], size_t length) - { - signature.resize(length); - copy_mem(&signature[0], sig, length); - } - -/* -* Set the signature to check -*/ -void PK_Verifier_Filter::set_signature(const MemoryRegion& sig) - { - signature = sig; - } - -/* -* PK_Verifier_Filter Constructor -*/ -PK_Verifier_Filter::PK_Verifier_Filter(PK_Verifier* v, const byte sig[], - size_t length) : - verifier(v), signature(sig, length) - { - } - -/* -* PK_Verifier_Filter Constructor -*/ -PK_Verifier_Filter::PK_Verifier_Filter(PK_Verifier* v, - const MemoryRegion& sig) : - verifier(v), signature(sig) - { - } - -} -/* -* SecureQueue -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include - -namespace Botan { - -/** -* A node in a SecureQueue -*/ -class SecureQueueNode - { - public: - SecureQueueNode() : buffer(DEFAULT_BUFFERSIZE) - { next = 0; start = end = 0; } - - ~SecureQueueNode() { next = 0; start = end = 0; } - - size_t write(const byte input[], size_t length) - { - size_t copied = std::min(length, buffer.size() - end); - copy_mem(&buffer[end], input, copied); - end += copied; - return copied; - } - - size_t read(byte output[], size_t length) - { - size_t copied = std::min(length, end - start); - copy_mem(output, &buffer[start], copied); - start += copied; - return copied; - } - - size_t peek(byte output[], size_t length, size_t offset = 0) - { - const size_t left = end - start; - if(offset >= left) return 0; - size_t copied = std::min(length, left - offset); - copy_mem(output, &buffer[start + offset], copied); - return copied; - } - - size_t size() const { return (end - start); } - private: - friend class SecureQueue; - SecureQueueNode* next; - SecureVector buffer; - size_t start, end; - }; - -/* -* Create a SecureQueue -*/ -SecureQueue::SecureQueue() - { - set_next(0, 0); - head = tail = new SecureQueueNode; - } - -/* -* Copy a SecureQueue -*/ -SecureQueue::SecureQueue(const SecureQueue& input) : - Fanout_Filter(), DataSource() - { - set_next(0, 0); - - head = tail = new SecureQueueNode; - SecureQueueNode* temp = input.head; - while(temp) - { - write(&temp->buffer[temp->start], temp->end - temp->start); - temp = temp->next; - } - } - -/* -* Destroy this SecureQueue -*/ -void SecureQueue::destroy() - { - SecureQueueNode* temp = head; - while(temp) - { - SecureQueueNode* holder = temp->next; - delete temp; - temp = holder; - } - head = tail = 0; - } - -/* -* Copy a SecureQueue -*/ -SecureQueue& SecureQueue::operator=(const SecureQueue& input) - { - destroy(); - head = tail = new SecureQueueNode; - SecureQueueNode* temp = input.head; - while(temp) - { - write(&temp->buffer[temp->start], temp->end - temp->start); - temp = temp->next; - } - return (*this); - } - -/* -* Add some bytes to the queue -*/ -void SecureQueue::write(const byte input[], size_t length) - { - if(!head) - head = tail = new SecureQueueNode; - while(length) - { - const size_t n = tail->write(input, length); - input += n; - length -= n; - if(length) - { - tail->next = new SecureQueueNode; - tail = tail->next; - } - } - } - -/* -* Read some bytes from the queue -*/ -size_t SecureQueue::read(byte output[], size_t length) - { - size_t got = 0; - while(length && head) - { - const size_t n = head->read(output, length); - output += n; - got += n; - length -= n; - if(head->size() == 0) - { - SecureQueueNode* holder = head->next; - delete head; - head = holder; - } - } - return got; - } - -/* -* Read data, but do not remove it from queue -*/ -size_t SecureQueue::peek(byte output[], size_t length, size_t offset) const - { - SecureQueueNode* current = head; - - while(offset && current) - { - if(offset >= current->size()) - { - offset -= current->size(); - current = current->next; - } - else - break; - } - - size_t got = 0; - while(length && current) - { - const size_t n = current->peek(output, length, offset); - offset = 0; - output += n; - got += n; - length -= n; - current = current->next; - } - return got; - } - -/* -* Return how many bytes the queue holds -*/ -size_t SecureQueue::size() const - { - SecureQueueNode* current = head; - size_t count = 0; - - while(current) - { - count += current->size(); - current = current->next; - } - return count; - } - -/* -* Test if the queue has any data in it -*/ -bool SecureQueue::end_of_data() const - { - return (size() == 0); - } - -} -/* -* Blue Midnight Wish 512 (Round 2 tweaked) -* (C) 2009 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -namespace { - -inline u64bit S0(u64bit X) - { - return (X >> 1) ^ (X << 3) ^ rotate_left(X, 4) ^ rotate_left(X, 37); - } - -inline u64bit S1(u64bit X) - { - return (X >> 1) ^ (X << 2) ^ rotate_left(X, 13) ^ rotate_left(X, 43); - } - -inline u64bit S2(u64bit X) - { - return (X >> 2) ^ (X << 1) ^ rotate_left(X, 19) ^ rotate_left(X, 53); - } - -inline u64bit S3(u64bit X) - { - return (X >> 2) ^ (X << 2) ^ rotate_left(X, 28) ^ rotate_left(X, 59); - } - -inline u64bit S4(u64bit X) - { - return (X >> 1) ^ X; - } - -/** -* Blue Midnight Wish 512 compression function -*/ -void BMW_512_compress(u64bit H[16], const u64bit M[16], u64bit Q[32]) - { - const size_t EXPAND_1_ROUNDS = 2; - - for(size_t i = 0; i != 16; ++i) - Q[i] = H[i] ^ M[i]; - - Q[16] = Q[ 5] - Q[ 7] + Q[10] + Q[13] + Q[14]; - Q[17] = Q[ 6] - Q[ 8] + Q[11] + Q[14] - Q[15]; - Q[18] = Q[ 0] + Q[ 7] + Q[ 9] - Q[12] + Q[15]; - Q[19] = Q[ 0] - Q[ 1] + Q[ 8] - Q[10] + Q[13]; - Q[20] = Q[ 1] + Q[ 2] + Q[ 9] - Q[11] - Q[14]; - Q[21] = Q[ 3] - Q[ 2] + Q[10] - Q[12] + Q[15]; - Q[22] = Q[ 4] - Q[ 0] - Q[ 3] - Q[11] + Q[13]; - Q[23] = Q[ 1] - Q[ 4] - Q[ 5] - Q[12] - Q[14]; - Q[24] = Q[ 2] - Q[ 5] - Q[ 6] + Q[13] - Q[15]; - Q[25] = Q[ 0] - Q[ 3] + Q[ 6] - Q[ 7] + Q[14]; - Q[26] = Q[ 8] - Q[ 1] - Q[ 4] - Q[ 7] + Q[15]; - Q[27] = Q[ 8] - Q[ 0] - Q[ 2] - Q[ 5] + Q[ 9]; - Q[28] = Q[ 1] + Q[ 3] - Q[ 6] - Q[ 9] + Q[10]; - Q[29] = Q[ 2] + Q[ 4] + Q[ 7] + Q[10] + Q[11]; - Q[30] = Q[ 3] - Q[ 5] + Q[ 8] - Q[11] - Q[12]; - Q[31] = Q[12] - Q[ 4] - Q[ 6] - Q[ 9] + Q[13]; - - Q[ 0] = S0(Q[16]) + H[ 1]; - Q[ 1] = S1(Q[17]) + H[ 2]; - Q[ 2] = S2(Q[18]) + H[ 3]; - Q[ 3] = S3(Q[19]) + H[ 4]; - Q[ 4] = S4(Q[20]) + H[ 5]; - Q[ 5] = S0(Q[21]) + H[ 6]; - Q[ 6] = S1(Q[22]) + H[ 7]; - Q[ 7] = S2(Q[23]) + H[ 8]; - Q[ 8] = S3(Q[24]) + H[ 9]; - Q[ 9] = S4(Q[25]) + H[10]; - Q[10] = S0(Q[26]) + H[11]; - Q[11] = S1(Q[27]) + H[12]; - Q[12] = S2(Q[28]) + H[13]; - Q[13] = S3(Q[29]) + H[14]; - Q[14] = S4(Q[30]) + H[15]; - Q[15] = S0(Q[31]) + H[ 0]; - - for(size_t i = 16; i != 16 + EXPAND_1_ROUNDS; ++i) - { - Q[i] = S1(Q[i-16]) + S2(Q[i-15]) + S3(Q[i-14]) + S0(Q[i-13]) + - S1(Q[i-12]) + S2(Q[i-11]) + S3(Q[i-10]) + S0(Q[i- 9]) + - S1(Q[i- 8]) + S2(Q[i- 7]) + S3(Q[i- 6]) + S0(Q[i- 5]) + - S1(Q[i- 4]) + S2(Q[i- 3]) + S3(Q[i- 2]) + S0(Q[i- 1]) + - ((rotate_left(M[(i-16) % 16], ((i-16)%16) + 1) + - rotate_left(M[(i-13) % 16], ((i-13)%16) + 1) - - rotate_left(M[(i- 6) % 16], ((i-6)%16) + 1) + - (0x0555555555555555ULL * i)) ^ H[(i-16+7)%16]); - } - - for(size_t i = 16 + EXPAND_1_ROUNDS; i != 32; ++i) - { - Q[i] = Q[i-16] + rotate_left(Q[i-15], 5) + - Q[i-14] + rotate_left(Q[i-13], 11) + - Q[i-12] + rotate_left(Q[i-11], 27) + - Q[i-10] + rotate_left(Q[i- 9], 32) + - Q[i- 8] + rotate_left(Q[i- 7], 37) + - Q[i- 6] + rotate_left(Q[i- 5], 43) + - Q[i- 4] + rotate_left(Q[i- 3], 53) + - S4(Q[i - 2]) + ((Q[i-1] >> 2) ^ Q[i-1]) + - ((rotate_left(M[(i-16) % 16], ((i-16)%16 + 1)) + - rotate_left(M[(i-13) % 16], ((i-13)%16 + 1)) - - rotate_left(M[(i- 6) % 16], ((i-6)%16 + 1)) + - (0x0555555555555555ULL * i)) ^ H[(i-16+7)%16]); - } - - u64bit XL = Q[16] ^ Q[17] ^ Q[18] ^ Q[19] ^ - Q[20] ^ Q[21] ^ Q[22] ^ Q[23]; - - u64bit XH = Q[24] ^ Q[25] ^ Q[26] ^ Q[27] ^ - Q[28] ^ Q[29] ^ Q[30] ^ Q[31]; - - XH ^= XL; - - H[ 0] = ((XH << 5) ^ (Q[16] >> 5) ^ M[0]) + (XL ^ Q[24] ^ Q[0]); - H[ 1] = ((XH >> 7) ^ (Q[17] << 8) ^ M[1]) + (XL ^ Q[25] ^ Q[1]); - H[ 2] = ((XH >> 5) ^ (Q[18] << 5) ^ M[2]) + (XL ^ Q[26] ^ Q[2]); - H[ 3] = ((XH >> 1) ^ (Q[19] << 5) ^ M[3]) + (XL ^ Q[27] ^ Q[3]); - H[ 4] = ((XH >> 3) ^ (Q[20] ) ^ M[4]) + (XL ^ Q[28] ^ Q[4]); - H[ 5] = ((XH << 6) ^ (Q[21] >> 6) ^ M[5]) + (XL ^ Q[29] ^ Q[5]); - H[ 6] = ((XH >> 4) ^ (Q[22] << 6) ^ M[6]) + (XL ^ Q[30] ^ Q[6]); - H[ 7] = ((XH >> 11) ^ (Q[23] << 2) ^ M[7]) + (XL ^ Q[31] ^ Q[7]); - - H[ 8] = rotate_left(H[4], 9) + (XH ^ Q[24] ^ M[ 8]) + ((XL << 8) ^ Q[23] ^ Q[ 8]); - H[ 9] = rotate_left(H[5], 10) + (XH ^ Q[25] ^ M[ 9]) + ((XL >> 6) ^ Q[16] ^ Q[ 9]); - H[10] = rotate_left(H[6], 11) + (XH ^ Q[26] ^ M[10]) + ((XL << 6) ^ Q[17] ^ Q[10]); - H[11] = rotate_left(H[7], 12) + (XH ^ Q[27] ^ M[11]) + ((XL << 4) ^ Q[18] ^ Q[11]); - H[12] = rotate_left(H[0], 13) + (XH ^ Q[28] ^ M[12]) + ((XL >> 3) ^ Q[19] ^ Q[12]); - H[13] = rotate_left(H[1], 14) + (XH ^ Q[29] ^ M[13]) + ((XL >> 4) ^ Q[20] ^ Q[13]); - H[14] = rotate_left(H[2], 15) + (XH ^ Q[30] ^ M[14]) + ((XL >> 7) ^ Q[21] ^ Q[14]); - H[15] = rotate_left(H[3], 16) + (XH ^ Q[31] ^ M[15]) + ((XL >> 2) ^ Q[22] ^ Q[15]); - } - -} - -void BMW_512::compress_n(const byte input[], size_t blocks) - { - for(size_t i = 0; i != blocks; ++i) - { - load_le(&M[0], input, M.size()); - - BMW_512_compress(&H[0], &M[0], &Q[0]); - - input += hash_block_size(); - } - } - -/* -* Copy out the digest -*/ -void BMW_512::copy_out(byte output[]) - { - u64bit final[16] = { - 0xAAAAAAAAAAAAAAA0ULL, 0xAAAAAAAAAAAAAAA1ULL, - 0xAAAAAAAAAAAAAAA2ULL, 0xAAAAAAAAAAAAAAA3ULL, - 0xAAAAAAAAAAAAAAA4ULL, 0xAAAAAAAAAAAAAAA5ULL, - 0xAAAAAAAAAAAAAAA6ULL, 0xAAAAAAAAAAAAAAA7ULL, - 0xAAAAAAAAAAAAAAA8ULL, 0xAAAAAAAAAAAAAAA9ULL, - 0xAAAAAAAAAAAAAAAAULL, 0xAAAAAAAAAAAAAAABULL, - 0xAAAAAAAAAAAAAAACULL, 0xAAAAAAAAAAAAAAADULL, - 0xAAAAAAAAAAAAAAAEULL, 0xAAAAAAAAAAAAAAAFULL }; - - BMW_512_compress(final, &H[0], &Q[0]); - - for(size_t i = 0; i != output_length(); i += 8) - store_le(final[8 + i/8], output + i); - } - -/* -* Clear memory of sensitive data -*/ -void BMW_512::clear() - { - MDx_HashFunction::clear(); - zeroise(M); - zeroise(Q); - - H[ 0] = 0x8081828384858687ULL; - H[ 1] = 0x88898A8B8C8D8E8FULL; - H[ 2] = 0x9091929394959697ULL; - H[ 3] = 0x98999A9B9C9D9E9FULL; - H[ 4] = 0xA0A1A2A3A4A5A6A7ULL; - H[ 5] = 0xA8A9AAABACADAEAFULL; - H[ 6] = 0xB0B1B2B3B4B5B6B7ULL; - H[ 7] = 0xB8B9BABBBCBDBEBFULL; - H[ 8] = 0xC0C1C2C3C4C5C6C7ULL; - H[ 9] = 0xC8C9CACBCCCDCECFULL; - H[10] = 0xD0D1D2D3D4D5D6D7ULL; - H[11] = 0xD8D9DADBDCDDDEDFULL; - H[12] = 0xE0E1E2E3E4E5E6E7ULL; - H[13] = 0xE8E9EAEBECEDEEEFULL; - H[14] = 0xF0F1F2F3F4F5F6F7ULL; - H[15] = 0xF8F9FAFBFCFDFEFFULL; - } - -} -/* -* Comb4P hash combiner -* (C) 2010 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include - -namespace Botan { - -namespace { - -void comb4p_round(MemoryRegion& out, - const MemoryRegion& in, - byte round_no, - HashFunction* h1, - HashFunction* h2) - { - h1->update(round_no); - h2->update(round_no); - - h1->update(&in[0], in.size()); - h2->update(&in[0], in.size()); - - SecureVector h_buf = h1->final(); - xor_buf(&out[0], &h_buf[0], std::min(out.size(), h_buf.size())); - - h_buf = h2->final(); - xor_buf(&out[0], &h_buf[0], std::min(out.size(), h_buf.size())); - } - -} - -Comb4P::Comb4P(HashFunction* h1, HashFunction* h2) : - hash1(h1), hash2(h2) - { - if(hash1->name() == hash2->name()) - throw std::invalid_argument("Comb4P: Must use two distinct hashes"); - - if(hash1->output_length() != hash2->output_length()) - throw std::invalid_argument("Comb4P: Incompatible hashes " + - hash1->name() + " and " + - hash2->name()); - - clear(); - } - -size_t Comb4P::hash_block_size() const - { - if(hash1->hash_block_size() == hash2->hash_block_size()) - return hash1->hash_block_size(); - - /* - * Return LCM of the block sizes? This would probably be OK for - * HMAC, which is the main thing relying on knowing the block size. - */ - return 0; - } - -void Comb4P::clear() - { - hash1->clear(); - hash2->clear(); - - // Prep for processing next message, if any - hash1->update(0); - hash2->update(0); - } - -void Comb4P::add_data(const byte input[], size_t length) - { - hash1->update(input, length); - hash2->update(input, length); - } - -void Comb4P::final_result(byte out[]) - { - SecureVector h1 = hash1->final(); - SecureVector h2 = hash2->final(); - - // First round - xor_buf(&h1[0], &h2[0], std::min(h1.size(), h2.size())); - - // Second round - comb4p_round(h2, h1, 1, hash1, hash2); - - // Third round - comb4p_round(h1, h2, 2, hash1, hash2); - - copy_mem(out , &h1[0], h1.size()); - copy_mem(out + h1.size(), &h2[0], h2.size()); - - // Prep for processing next message, if any - hash1->update(0); - hash2->update(0); - } - -} - -/* -* GOST 34.11 -* (C) 2009 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -/** -* GOST 34.11 Constructor -*/ -GOST_34_11::GOST_34_11() : - cipher(GOST_28147_89_Params("R3411_CryptoPro")), - buffer(32), - sum(32), - hash(32) - { - count = 0; - position = 0; - } - -void GOST_34_11::clear() - { - cipher.clear(); - zeroise(sum); - zeroise(hash); - count = 0; - position = 0; - } - -/** -* Hash additional inputs -*/ -void GOST_34_11::add_data(const byte input[], size_t length) - { - count += length; - - if(position) - { - buffer.copy(position, input, length); - - if(position + length >= hash_block_size()) - { - compress_n(&buffer[0], 1); - input += (hash_block_size() - position); - length -= (hash_block_size() - position); - position = 0; - } - } - - const size_t full_blocks = length / hash_block_size(); - const size_t remaining = length % hash_block_size(); - - if(full_blocks) - compress_n(input, full_blocks); - - buffer.copy(position, input + full_blocks * hash_block_size(), remaining); - position += remaining; - } - -/** -* The GOST 34.11 compression function -*/ -void GOST_34_11::compress_n(const byte input[], size_t blocks) - { - for(size_t i = 0; i != blocks; ++i) - { - for(u16bit j = 0, carry = 0; j != 32; ++j) - { - u16bit s = sum[j] + input[32*i+j] + carry; - carry = get_byte(0, s); - sum[j] = get_byte(1, s); - } - - byte S[32] = { 0 }; - - u64bit U[4], V[4]; - load_be(U, &hash[0], 4); - load_be(V, input + 32*i, 4); - - for(size_t j = 0; j != 4; ++j) - { - byte key[32] = { 0 }; - - // P transformation - for(size_t k = 0; k != 4; ++k) - for(size_t l = 0; l != 8; ++l) - key[4*l+k] = get_byte(l, U[k]) ^ get_byte(l, V[k]); - - cipher.set_key(key, 32); - cipher.encrypt(&hash[8*j], S + 8*j); - - if(j == 3) - break; - - // A(x) - u64bit A_U = U[0]; - U[0] = U[1]; - U[1] = U[2]; - U[2] = U[3]; - U[3] = U[0] ^ A_U; - - if(j == 1) // C_3 - { - U[0] ^= 0x00FF00FF00FF00FFULL; - U[1] ^= 0xFF00FF00FF00FF00ULL; - U[2] ^= 0x00FFFF00FF0000FFULL; - U[3] ^= 0xFF000000FFFF00FFULL; - } - - // A(A(x)) - u64bit AA_V_1 = V[0] ^ V[1]; - u64bit AA_V_2 = V[1] ^ V[2]; - V[0] = V[2]; - V[1] = V[3]; - V[2] = AA_V_1; - V[3] = AA_V_2; - } - - byte S2[32] = { 0 }; - - // 12 rounds of psi - S2[ 0] = S[24]; - S2[ 1] = S[25]; - S2[ 2] = S[26]; - S2[ 3] = S[27]; - S2[ 4] = S[28]; - S2[ 5] = S[29]; - S2[ 6] = S[30]; - S2[ 7] = S[31]; - S2[ 8] = S[ 0] ^ S[ 2] ^ S[ 4] ^ S[ 6] ^ S[24] ^ S[30]; - S2[ 9] = S[ 1] ^ S[ 3] ^ S[ 5] ^ S[ 7] ^ S[25] ^ S[31]; - S2[10] = S[ 0] ^ S[ 8] ^ S[24] ^ S[26] ^ S[30]; - S2[11] = S[ 1] ^ S[ 9] ^ S[25] ^ S[27] ^ S[31]; - S2[12] = S[ 0] ^ S[ 4] ^ S[ 6] ^ S[10] ^ S[24] ^ S[26] ^ S[28] ^ S[30]; - S2[13] = S[ 1] ^ S[ 5] ^ S[ 7] ^ S[11] ^ S[25] ^ S[27] ^ S[29] ^ S[31]; - S2[14] = S[ 0] ^ S[ 4] ^ S[ 8] ^ S[12] ^ S[24] ^ S[26] ^ S[28]; - S2[15] = S[ 1] ^ S[ 5] ^ S[ 9] ^ S[13] ^ S[25] ^ S[27] ^ S[29]; - S2[16] = S[ 2] ^ S[ 6] ^ S[10] ^ S[14] ^ S[26] ^ S[28] ^ S[30]; - S2[17] = S[ 3] ^ S[ 7] ^ S[11] ^ S[15] ^ S[27] ^ S[29] ^ S[31]; - S2[18] = S[ 0] ^ S[ 2] ^ S[ 6] ^ S[ 8] ^ S[12] ^ S[16] ^ S[24] ^ S[28]; - S2[19] = S[ 1] ^ S[ 3] ^ S[ 7] ^ S[ 9] ^ S[13] ^ S[17] ^ S[25] ^ S[29]; - S2[20] = S[ 2] ^ S[ 4] ^ S[ 8] ^ S[10] ^ S[14] ^ S[18] ^ S[26] ^ S[30]; - S2[21] = S[ 3] ^ S[ 5] ^ S[ 9] ^ S[11] ^ S[15] ^ S[19] ^ S[27] ^ S[31]; - S2[22] = S[ 0] ^ S[ 2] ^ S[10] ^ S[12] ^ S[16] ^ S[20] ^ S[24] ^ S[28] ^ S[30]; - S2[23] = S[ 1] ^ S[ 3] ^ S[11] ^ S[13] ^ S[17] ^ S[21] ^ S[25] ^ S[29] ^ S[31]; - S2[24] = S[ 0] ^ S[ 6] ^ S[12] ^ S[14] ^ S[18] ^ S[22] ^ S[24] ^ S[26]; - S2[25] = S[ 1] ^ S[ 7] ^ S[13] ^ S[15] ^ S[19] ^ S[23] ^ S[25] ^ S[27]; - S2[26] = S[ 2] ^ S[ 8] ^ S[14] ^ S[16] ^ S[20] ^ S[24] ^ S[26] ^ S[28]; - S2[27] = S[ 3] ^ S[ 9] ^ S[15] ^ S[17] ^ S[21] ^ S[25] ^ S[27] ^ S[29]; - S2[28] = S[ 4] ^ S[10] ^ S[16] ^ S[18] ^ S[22] ^ S[26] ^ S[28] ^ S[30]; - S2[29] = S[ 5] ^ S[11] ^ S[17] ^ S[19] ^ S[23] ^ S[27] ^ S[29] ^ S[31]; - S2[30] = S[ 0] ^ S[ 2] ^ S[ 4] ^ S[12] ^ S[18] ^ S[20] ^ S[28]; - S2[31] = S[ 1] ^ S[ 3] ^ S[ 5] ^ S[13] ^ S[19] ^ S[21] ^ S[29]; - - xor_buf(S, S2, input + 32*i, 32); - - S2[0] = S[0] ^ S[2] ^ S[4] ^ S[6] ^ S[24] ^ S[30]; - S2[1] = S[1] ^ S[3] ^ S[5] ^ S[7] ^ S[25] ^ S[31]; - - copy_mem(S, S+2, 30); - S[30] = S2[0]; - S[31] = S2[1]; - - xor_buf(S, &hash[0], 32); - - // 61 rounds of psi - S2[ 0] = S[ 2] ^ S[ 6] ^ S[14] ^ S[20] ^ S[22] ^ S[26] ^ S[28] ^ S[30]; - S2[ 1] = S[ 3] ^ S[ 7] ^ S[15] ^ S[21] ^ S[23] ^ S[27] ^ S[29] ^ S[31]; - S2[ 2] = S[ 0] ^ S[ 2] ^ S[ 6] ^ S[ 8] ^ S[16] ^ S[22] ^ S[28]; - S2[ 3] = S[ 1] ^ S[ 3] ^ S[ 7] ^ S[ 9] ^ S[17] ^ S[23] ^ S[29]; - S2[ 4] = S[ 2] ^ S[ 4] ^ S[ 8] ^ S[10] ^ S[18] ^ S[24] ^ S[30]; - S2[ 5] = S[ 3] ^ S[ 5] ^ S[ 9] ^ S[11] ^ S[19] ^ S[25] ^ S[31]; - S2[ 6] = S[ 0] ^ S[ 2] ^ S[10] ^ S[12] ^ S[20] ^ S[24] ^ S[26] ^ S[30]; - S2[ 7] = S[ 1] ^ S[ 3] ^ S[11] ^ S[13] ^ S[21] ^ S[25] ^ S[27] ^ S[31]; - S2[ 8] = S[ 0] ^ S[ 6] ^ S[12] ^ S[14] ^ S[22] ^ S[24] ^ S[26] ^ S[28] ^ S[30]; - S2[ 9] = S[ 1] ^ S[ 7] ^ S[13] ^ S[15] ^ S[23] ^ S[25] ^ S[27] ^ S[29] ^ S[31]; - S2[10] = S[ 0] ^ S[ 4] ^ S[ 6] ^ S[ 8] ^ S[14] ^ S[16] ^ S[26] ^ S[28]; - S2[11] = S[ 1] ^ S[ 5] ^ S[ 7] ^ S[ 9] ^ S[15] ^ S[17] ^ S[27] ^ S[29]; - S2[12] = S[ 2] ^ S[ 6] ^ S[ 8] ^ S[10] ^ S[16] ^ S[18] ^ S[28] ^ S[30]; - S2[13] = S[ 3] ^ S[ 7] ^ S[ 9] ^ S[11] ^ S[17] ^ S[19] ^ S[29] ^ S[31]; - S2[14] = S[ 0] ^ S[ 2] ^ S[ 6] ^ S[ 8] ^ S[10] ^ S[12] ^ S[18] ^ S[20] ^ S[24]; - S2[15] = S[ 1] ^ S[ 3] ^ S[ 7] ^ S[ 9] ^ S[11] ^ S[13] ^ S[19] ^ S[21] ^ S[25]; - S2[16] = S[ 2] ^ S[ 4] ^ S[ 8] ^ S[10] ^ S[12] ^ S[14] ^ S[20] ^ S[22] ^ S[26]; - S2[17] = S[ 3] ^ S[ 5] ^ S[ 9] ^ S[11] ^ S[13] ^ S[15] ^ S[21] ^ S[23] ^ S[27]; - S2[18] = S[ 4] ^ S[ 6] ^ S[10] ^ S[12] ^ S[14] ^ S[16] ^ S[22] ^ S[24] ^ S[28]; - S2[19] = S[ 5] ^ S[ 7] ^ S[11] ^ S[13] ^ S[15] ^ S[17] ^ S[23] ^ S[25] ^ S[29]; - S2[20] = S[ 6] ^ S[ 8] ^ S[12] ^ S[14] ^ S[16] ^ S[18] ^ S[24] ^ S[26] ^ S[30]; - S2[21] = S[ 7] ^ S[ 9] ^ S[13] ^ S[15] ^ S[17] ^ S[19] ^ S[25] ^ S[27] ^ S[31]; - S2[22] = S[ 0] ^ S[ 2] ^ S[ 4] ^ S[ 6] ^ S[ 8] ^ S[10] ^ S[14] ^ S[16] ^ - S[18] ^ S[20] ^ S[24] ^ S[26] ^ S[28] ^ S[30]; - S2[23] = S[ 1] ^ S[ 3] ^ S[ 5] ^ S[ 7] ^ S[ 9] ^ S[11] ^ S[15] ^ S[17] ^ - S[19] ^ S[21] ^ S[25] ^ S[27] ^ S[29] ^ S[31]; - S2[24] = S[ 0] ^ S[ 8] ^ S[10] ^ S[12] ^ S[16] ^ S[18] ^ S[20] ^ S[22] ^ - S[24] ^ S[26] ^ S[28]; - S2[25] = S[ 1] ^ S[ 9] ^ S[11] ^ S[13] ^ S[17] ^ S[19] ^ S[21] ^ S[23] ^ - S[25] ^ S[27] ^ S[29]; - S2[26] = S[ 2] ^ S[10] ^ S[12] ^ S[14] ^ S[18] ^ S[20] ^ S[22] ^ S[24] ^ - S[26] ^ S[28] ^ S[30]; - S2[27] = S[ 3] ^ S[11] ^ S[13] ^ S[15] ^ S[19] ^ S[21] ^ S[23] ^ S[25] ^ - S[27] ^ S[29] ^ S[31]; - S2[28] = S[ 0] ^ S[ 2] ^ S[ 6] ^ S[12] ^ S[14] ^ S[16] ^ S[20] ^ S[22] ^ S[26] ^ S[28]; - S2[29] = S[ 1] ^ S[ 3] ^ S[ 7] ^ S[13] ^ S[15] ^ S[17] ^ S[21] ^ S[23] ^ S[27] ^ S[29]; - S2[30] = S[ 2] ^ S[ 4] ^ S[ 8] ^ S[14] ^ S[16] ^ S[18] ^ S[22] ^ S[24] ^ S[28] ^ S[30]; - S2[31] = S[ 3] ^ S[ 5] ^ S[ 9] ^ S[15] ^ S[17] ^ S[19] ^ S[23] ^ S[25] ^ S[29] ^ S[31]; - - hash.copy(S2, 32); - } - } - -/** -* Produce the final GOST 34.11 output -*/ -void GOST_34_11::final_result(byte out[]) - { - if(position) - { - clear_mem(&buffer[0] + position, buffer.size() - position); - compress_n(&buffer[0], 1); - } - - SecureVector length_buf(32); - const u64bit bit_count = count * 8; - store_le(bit_count, &length_buf[0]); - - SecureVector sum_buf = sum; - - compress_n(&length_buf[0], 1); - compress_n(&sum_buf[0], 1); - - copy_mem(out, &hash[0], 32); - - clear(); - } - -} -/* -* HAS-160 -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -namespace HAS_160_F { - -/* -* HAS-160 F1 Function -*/ -inline void F1(u32bit A, u32bit& B, u32bit C, u32bit D, u32bit& E, - u32bit msg, u32bit rot) - { - E += rotate_left(A, rot) + (D ^ (B & (C ^ D))) + msg; - B = rotate_left(B, 10); - } - -/* -* HAS-160 F2 Function -*/ -inline void F2(u32bit A, u32bit& B, u32bit C, u32bit D, u32bit& E, - u32bit msg, u32bit rot) - { - E += rotate_left(A, rot) + (B ^ C ^ D) + msg + 0x5A827999; - B = rotate_left(B, 17); - } - -/* -* HAS-160 F3 Function -*/ -inline void F3(u32bit A, u32bit& B, u32bit C, u32bit D, u32bit& E, - u32bit msg, u32bit rot) - { - E += rotate_left(A, rot) + (C ^ (B | ~D)) + msg + 0x6ED9EBA1; - B = rotate_left(B, 25); - } - -/* -* HAS-160 F4 Function -*/ -inline void F4(u32bit A, u32bit& B, u32bit C, u32bit D, u32bit& E, - u32bit msg, u32bit rot) - { - E += rotate_left(A, rot) + (B ^ C ^ D) + msg + 0x8F1BBCDC; - B = rotate_left(B, 30); - } - -} - -/* -* HAS-160 Compression Function -*/ -void HAS_160::compress_n(const byte input[], size_t blocks) - { - using namespace HAS_160_F; - - u32bit A = digest[0], B = digest[1], C = digest[2], - D = digest[3], E = digest[4]; - - for(size_t i = 0; i != blocks; ++i) - { - load_le(&X[0], input, 16); - - X[16] = X[ 0] ^ X[ 1] ^ X[ 2] ^ X[ 3]; - X[17] = X[ 4] ^ X[ 5] ^ X[ 6] ^ X[ 7]; - X[18] = X[ 8] ^ X[ 9] ^ X[10] ^ X[11]; - X[19] = X[12] ^ X[13] ^ X[14] ^ X[15]; - F1(A,B,C,D,E,X[18], 5); F1(E,A,B,C,D,X[ 0],11); - F1(D,E,A,B,C,X[ 1], 7); F1(C,D,E,A,B,X[ 2],15); - F1(B,C,D,E,A,X[ 3], 6); F1(A,B,C,D,E,X[19],13); - F1(E,A,B,C,D,X[ 4], 8); F1(D,E,A,B,C,X[ 5],14); - F1(C,D,E,A,B,X[ 6], 7); F1(B,C,D,E,A,X[ 7],12); - F1(A,B,C,D,E,X[16], 9); F1(E,A,B,C,D,X[ 8],11); - F1(D,E,A,B,C,X[ 9], 8); F1(C,D,E,A,B,X[10],15); - F1(B,C,D,E,A,X[11], 6); F1(A,B,C,D,E,X[17],12); - F1(E,A,B,C,D,X[12], 9); F1(D,E,A,B,C,X[13],14); - F1(C,D,E,A,B,X[14], 5); F1(B,C,D,E,A,X[15],13); - - X[16] = X[ 3] ^ X[ 6] ^ X[ 9] ^ X[12]; - X[17] = X[ 2] ^ X[ 5] ^ X[ 8] ^ X[15]; - X[18] = X[ 1] ^ X[ 4] ^ X[11] ^ X[14]; - X[19] = X[ 0] ^ X[ 7] ^ X[10] ^ X[13]; - F2(A,B,C,D,E,X[18], 5); F2(E,A,B,C,D,X[ 3],11); - F2(D,E,A,B,C,X[ 6], 7); F2(C,D,E,A,B,X[ 9],15); - F2(B,C,D,E,A,X[12], 6); F2(A,B,C,D,E,X[19],13); - F2(E,A,B,C,D,X[15], 8); F2(D,E,A,B,C,X[ 2],14); - F2(C,D,E,A,B,X[ 5], 7); F2(B,C,D,E,A,X[ 8],12); - F2(A,B,C,D,E,X[16], 9); F2(E,A,B,C,D,X[11],11); - F2(D,E,A,B,C,X[14], 8); F2(C,D,E,A,B,X[ 1],15); - F2(B,C,D,E,A,X[ 4], 6); F2(A,B,C,D,E,X[17],12); - F2(E,A,B,C,D,X[ 7], 9); F2(D,E,A,B,C,X[10],14); - F2(C,D,E,A,B,X[13], 5); F2(B,C,D,E,A,X[ 0],13); - - X[16] = X[ 5] ^ X[ 7] ^ X[12] ^ X[14]; - X[17] = X[ 0] ^ X[ 2] ^ X[ 9] ^ X[11]; - X[18] = X[ 4] ^ X[ 6] ^ X[13] ^ X[15]; - X[19] = X[ 1] ^ X[ 3] ^ X[ 8] ^ X[10]; - F3(A,B,C,D,E,X[18], 5); F3(E,A,B,C,D,X[12],11); - F3(D,E,A,B,C,X[ 5], 7); F3(C,D,E,A,B,X[14],15); - F3(B,C,D,E,A,X[ 7], 6); F3(A,B,C,D,E,X[19],13); - F3(E,A,B,C,D,X[ 0], 8); F3(D,E,A,B,C,X[ 9],14); - F3(C,D,E,A,B,X[ 2], 7); F3(B,C,D,E,A,X[11],12); - F3(A,B,C,D,E,X[16], 9); F3(E,A,B,C,D,X[ 4],11); - F3(D,E,A,B,C,X[13], 8); F3(C,D,E,A,B,X[ 6],15); - F3(B,C,D,E,A,X[15], 6); F3(A,B,C,D,E,X[17],12); - F3(E,A,B,C,D,X[ 8], 9); F3(D,E,A,B,C,X[ 1],14); - F3(C,D,E,A,B,X[10], 5); F3(B,C,D,E,A,X[ 3],13); - - X[16] = X[ 2] ^ X[ 7] ^ X[ 8] ^ X[13]; - X[17] = X[ 3] ^ X[ 4] ^ X[ 9] ^ X[14]; - X[18] = X[ 0] ^ X[ 5] ^ X[10] ^ X[15]; - X[19] = X[ 1] ^ X[ 6] ^ X[11] ^ X[12]; - F4(A,B,C,D,E,X[18], 5); F4(E,A,B,C,D,X[ 7],11); - F4(D,E,A,B,C,X[ 2], 7); F4(C,D,E,A,B,X[13],15); - F4(B,C,D,E,A,X[ 8], 6); F4(A,B,C,D,E,X[19],13); - F4(E,A,B,C,D,X[ 3], 8); F4(D,E,A,B,C,X[14],14); - F4(C,D,E,A,B,X[ 9], 7); F4(B,C,D,E,A,X[ 4],12); - F4(A,B,C,D,E,X[16], 9); F4(E,A,B,C,D,X[15],11); - F4(D,E,A,B,C,X[10], 8); F4(C,D,E,A,B,X[ 5],15); - F4(B,C,D,E,A,X[ 0], 6); F4(A,B,C,D,E,X[17],12); - F4(E,A,B,C,D,X[11], 9); F4(D,E,A,B,C,X[ 6],14); - F4(C,D,E,A,B,X[ 1], 5); F4(B,C,D,E,A,X[12],13); - - A = (digest[0] += A); - B = (digest[1] += B); - C = (digest[2] += C); - D = (digest[3] += D); - E = (digest[4] += E); - - input += hash_block_size(); - } - } - -/* -* Copy out the digest -*/ -void HAS_160::copy_out(byte output[]) - { - for(size_t i = 0; i != output_length(); i += 4) - store_le(digest[i/4], output + i); - } - -/* -* Clear memory of sensitive data -*/ -void HAS_160::clear() - { - MDx_HashFunction::clear(); - zeroise(X); - digest[0] = 0x67452301; - digest[1] = 0xEFCDAB89; - digest[2] = 0x98BADCFE; - digest[3] = 0x10325476; - digest[4] = 0xC3D2E1F0; - } - -} -/* -* Keccak -* (C) 2010 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -namespace { - -void keccak_f_1600(u64bit A[25]) - { - static const u64bit RC[24] = { - 0x0000000000000001ULL, 0x0000000000008082ULL, 0x800000000000808AULL, - 0x8000000080008000ULL, 0x000000000000808BULL, 0x0000000080000001ULL, - 0x8000000080008081ULL, 0x8000000000008009ULL, 0x000000000000008AULL, - 0x0000000000000088ULL, 0x0000000080008009ULL, 0x000000008000000AULL, - 0x000000008000808BULL, 0x800000000000008BULL, 0x8000000000008089ULL, - 0x8000000000008003ULL, 0x8000000000008002ULL, 0x8000000000000080ULL, - 0x000000000000800AULL, 0x800000008000000AULL, 0x8000000080008081ULL, - 0x8000000000008080ULL, 0x0000000080000001ULL, 0x8000000080008008ULL - }; - - for(size_t i = 0; i != 24; ++i) - { - const u64bit C0 = A[0] ^ A[5] ^ A[10] ^ A[15] ^ A[20]; - const u64bit C1 = A[1] ^ A[6] ^ A[11] ^ A[16] ^ A[21]; - const u64bit C2 = A[2] ^ A[7] ^ A[12] ^ A[17] ^ A[22]; - const u64bit C3 = A[3] ^ A[8] ^ A[13] ^ A[18] ^ A[23]; - const u64bit C4 = A[4] ^ A[9] ^ A[14] ^ A[19] ^ A[24]; - - const u64bit D0 = rotate_left(C0, 1) ^ C3; - const u64bit D1 = rotate_left(C1, 1) ^ C4; - const u64bit D2 = rotate_left(C2, 1) ^ C0; - const u64bit D3 = rotate_left(C3, 1) ^ C1; - const u64bit D4 = rotate_left(C4, 1) ^ C2; - - const u64bit B00 = A[ 0] ^ D1; - const u64bit B01 = rotate_left(A[ 6] ^ D2, 44); - const u64bit B02 = rotate_left(A[12] ^ D3, 43); - const u64bit B03 = rotate_left(A[18] ^ D4, 21); - const u64bit B04 = rotate_left(A[24] ^ D0, 14); - const u64bit B05 = rotate_left(A[ 3] ^ D4, 28); - const u64bit B06 = rotate_left(A[ 9] ^ D0, 20); - const u64bit B07 = rotate_left(A[10] ^ D1, 3); - const u64bit B08 = rotate_left(A[16] ^ D2, 45); - const u64bit B09 = rotate_left(A[22] ^ D3, 61); - const u64bit B10 = rotate_left(A[ 1] ^ D2, 1); - const u64bit B11 = rotate_left(A[ 7] ^ D3, 6); - const u64bit B12 = rotate_left(A[13] ^ D4, 25); - const u64bit B13 = rotate_left(A[19] ^ D0, 8); - const u64bit B14 = rotate_left(A[20] ^ D1, 18); - const u64bit B15 = rotate_left(A[ 4] ^ D0, 27); - const u64bit B16 = rotate_left(A[ 5] ^ D1, 36); - const u64bit B17 = rotate_left(A[11] ^ D2, 10); - const u64bit B18 = rotate_left(A[17] ^ D3, 15); - const u64bit B19 = rotate_left(A[23] ^ D4, 56); - const u64bit B20 = rotate_left(A[ 2] ^ D3, 62); - const u64bit B21 = rotate_left(A[ 8] ^ D4, 55); - const u64bit B22 = rotate_left(A[14] ^ D0, 39); - const u64bit B23 = rotate_left(A[15] ^ D1, 41); - const u64bit B24 = rotate_left(A[21] ^ D2, 2); - - A[ 0] = B00 ^ (~B01 & B02); - A[ 1] = B01 ^ (~B02 & B03); - A[ 2] = B02 ^ (~B03 & B04); - A[ 3] = B03 ^ (~B04 & B00); - A[ 4] = B04 ^ (~B00 & B01); - A[ 5] = B05 ^ (~B06 & B07); - A[ 6] = B06 ^ (~B07 & B08); - A[ 7] = B07 ^ (~B08 & B09); - A[ 8] = B08 ^ (~B09 & B05); - A[ 9] = B09 ^ (~B05 & B06); - A[10] = B10 ^ (~B11 & B12); - A[11] = B11 ^ (~B12 & B13); - A[12] = B12 ^ (~B13 & B14); - A[13] = B13 ^ (~B14 & B10); - A[14] = B14 ^ (~B10 & B11); - A[15] = B15 ^ (~B16 & B17); - A[16] = B16 ^ (~B17 & B18); - A[17] = B17 ^ (~B18 & B19); - A[18] = B18 ^ (~B19 & B15); - A[19] = B19 ^ (~B15 & B16); - A[20] = B20 ^ (~B21 & B22); - A[21] = B21 ^ (~B22 & B23); - A[22] = B22 ^ (~B23 & B24); - A[23] = B23 ^ (~B24 & B20); - A[24] = B24 ^ (~B20 & B21); - - A[0] ^= RC[i]; - } - } - -} - -Keccak_1600::Keccak_1600(size_t output_bits) : - output_bits(output_bits), - bitrate(1600 - 2*output_bits), - S(25), - S_pos(0) - { - // We only support the parameters for the SHA-3 proposal - - if(output_bits != 224 && output_bits != 256 && - output_bits != 384 && output_bits != 512) - throw Invalid_Argument("Keccak_1600: Invalid output length " + - to_string(output_bits)); - } - -std::string Keccak_1600::name() const - { - return "Keccak-1600(" + to_string(output_bits) + ")"; - } - -HashFunction* Keccak_1600::clone() const - { - return new Keccak_1600(output_bits); - } - -void Keccak_1600::clear() - { - zeroise(S); - S_pos = 0; - } - -void Keccak_1600::add_data(const byte input[], size_t length) - { - if(length == 0) - return; - - while(length) - { - size_t to_take = std::min(length, bitrate / 8 - S_pos); - - length -= to_take; - - while(to_take && S_pos % 8) - { - S[S_pos / 8] ^= static_cast(input[0]) << (8 * (S_pos % 8)); - - ++S_pos; - ++input; - --to_take; - } - - while(to_take && to_take % 8 == 0) - { - S[S_pos / 8] ^= load_le(input, 0); - S_pos += 8; - input += 8; - to_take -= 8; - } - - while(to_take) - { - S[S_pos / 8] ^= static_cast(input[0]) << (8 * (S_pos % 8)); - - ++S_pos; - ++input; - --to_take; - } - - if(S_pos == bitrate / 8) - { - keccak_f_1600(&S[0]); - S_pos = 0; - } - } - } - -void Keccak_1600::final_result(byte output[]) - { - MemoryVector padding(bitrate / 8 - S_pos); - - padding[0] = 0x01; - padding[padding.size()-1] |= 0x80; - - add_data(padding, padding.size()); - - /* - * We never have to run the permutation again because we only support - * limited output lengths - */ - for(size_t i = 0; i != output_bits/8; ++i) - output[i] = get_byte(7 - (i % 8), S[i/8]); - - clear(); - } - -} -/* -* MD2 -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -/** -* MD2 Compression Function -*/ -void MD2::hash(const byte input[]) - { - static const byte SBOX[256] = { - 0x29, 0x2E, 0x43, 0xC9, 0xA2, 0xD8, 0x7C, 0x01, 0x3D, 0x36, 0x54, 0xA1, - 0xEC, 0xF0, 0x06, 0x13, 0x62, 0xA7, 0x05, 0xF3, 0xC0, 0xC7, 0x73, 0x8C, - 0x98, 0x93, 0x2B, 0xD9, 0xBC, 0x4C, 0x82, 0xCA, 0x1E, 0x9B, 0x57, 0x3C, - 0xFD, 0xD4, 0xE0, 0x16, 0x67, 0x42, 0x6F, 0x18, 0x8A, 0x17, 0xE5, 0x12, - 0xBE, 0x4E, 0xC4, 0xD6, 0xDA, 0x9E, 0xDE, 0x49, 0xA0, 0xFB, 0xF5, 0x8E, - 0xBB, 0x2F, 0xEE, 0x7A, 0xA9, 0x68, 0x79, 0x91, 0x15, 0xB2, 0x07, 0x3F, - 0x94, 0xC2, 0x10, 0x89, 0x0B, 0x22, 0x5F, 0x21, 0x80, 0x7F, 0x5D, 0x9A, - 0x5A, 0x90, 0x32, 0x27, 0x35, 0x3E, 0xCC, 0xE7, 0xBF, 0xF7, 0x97, 0x03, - 0xFF, 0x19, 0x30, 0xB3, 0x48, 0xA5, 0xB5, 0xD1, 0xD7, 0x5E, 0x92, 0x2A, - 0xAC, 0x56, 0xAA, 0xC6, 0x4F, 0xB8, 0x38, 0xD2, 0x96, 0xA4, 0x7D, 0xB6, - 0x76, 0xFC, 0x6B, 0xE2, 0x9C, 0x74, 0x04, 0xF1, 0x45, 0x9D, 0x70, 0x59, - 0x64, 0x71, 0x87, 0x20, 0x86, 0x5B, 0xCF, 0x65, 0xE6, 0x2D, 0xA8, 0x02, - 0x1B, 0x60, 0x25, 0xAD, 0xAE, 0xB0, 0xB9, 0xF6, 0x1C, 0x46, 0x61, 0x69, - 0x34, 0x40, 0x7E, 0x0F, 0x55, 0x47, 0xA3, 0x23, 0xDD, 0x51, 0xAF, 0x3A, - 0xC3, 0x5C, 0xF9, 0xCE, 0xBA, 0xC5, 0xEA, 0x26, 0x2C, 0x53, 0x0D, 0x6E, - 0x85, 0x28, 0x84, 0x09, 0xD3, 0xDF, 0xCD, 0xF4, 0x41, 0x81, 0x4D, 0x52, - 0x6A, 0xDC, 0x37, 0xC8, 0x6C, 0xC1, 0xAB, 0xFA, 0x24, 0xE1, 0x7B, 0x08, - 0x0C, 0xBD, 0xB1, 0x4A, 0x78, 0x88, 0x95, 0x8B, 0xE3, 0x63, 0xE8, 0x6D, - 0xE9, 0xCB, 0xD5, 0xFE, 0x3B, 0x00, 0x1D, 0x39, 0xF2, 0xEF, 0xB7, 0x0E, - 0x66, 0x58, 0xD0, 0xE4, 0xA6, 0x77, 0x72, 0xF8, 0xEB, 0x75, 0x4B, 0x0A, - 0x31, 0x44, 0x50, 0xB4, 0x8F, 0xED, 0x1F, 0x1A, 0xDB, 0x99, 0x8D, 0x33, - 0x9F, 0x11, 0x83, 0x14 }; - - X.copy(16, input, hash_block_size()); - xor_buf(&X[32], &X[0], &X[16], hash_block_size()); - byte T = 0; - - for(size_t i = 0; i != 18; ++i) - { - for(size_t k = 0; k != 48; k += 8) - { - T = X[k ] ^= SBOX[T]; T = X[k+1] ^= SBOX[T]; - T = X[k+2] ^= SBOX[T]; T = X[k+3] ^= SBOX[T]; - T = X[k+4] ^= SBOX[T]; T = X[k+5] ^= SBOX[T]; - T = X[k+6] ^= SBOX[T]; T = X[k+7] ^= SBOX[T]; - } - - T += static_cast(i); - } - - T = checksum[15]; - for(size_t i = 0; i != hash_block_size(); ++i) - T = checksum[i] ^= SBOX[input[i] ^ T]; - } - -/** -* Update the hash -*/ -void MD2::add_data(const byte input[], size_t length) - { - buffer.copy(position, input, length); - - if(position + length >= hash_block_size()) - { - hash(&buffer[0]); - input += (hash_block_size() - position); - length -= (hash_block_size() - position); - while(length >= hash_block_size()) - { - hash(input); - input += hash_block_size(); - length -= hash_block_size(); - } - buffer.copy(input, length); - position = 0; - } - position += length; - } - -/** -* Finalize a MD2 Hash -*/ -void MD2::final_result(byte output[]) - { - for(size_t i = position; i != hash_block_size(); ++i) - buffer[i] = static_cast(hash_block_size() - position); - - hash(&buffer[0]); - hash(&checksum[0]); - copy_mem(output, &X[0], output_length()); - clear(); - } - -/** -* Clear memory of sensitive data -*/ -void MD2::clear() - { - zeroise(X); - zeroise(checksum); - zeroise(buffer); - position = 0; - } - -} -/* -* MD4 -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -namespace { - -/* -* MD4 FF Function -*/ -inline void FF(u32bit& A, u32bit B, u32bit C, u32bit D, u32bit M, byte S) - { - A += (D ^ (B & (C ^ D))) + M; - A = rotate_left(A, S); - } - -/* -* MD4 GG Function -*/ -inline void GG(u32bit& A, u32bit B, u32bit C, u32bit D, u32bit M, byte S) - { - A += ((B & C) | (D & (B | C))) + M + 0x5A827999; - A = rotate_left(A, S); - } - -/* -* MD4 HH Function -*/ -inline void HH(u32bit& A, u32bit B, u32bit C, u32bit D, u32bit M, byte S) - { - A += (B ^ C ^ D) + M + 0x6ED9EBA1; - A = rotate_left(A, S); - } - -} - -/* -* MD4 Compression Function -*/ -void MD4::compress_n(const byte input[], size_t blocks) - { - u32bit A = digest[0], B = digest[1], C = digest[2], D = digest[3]; - - for(size_t i = 0; i != blocks; ++i) - { - load_le(&M[0], input, M.size()); - - FF(A,B,C,D,M[ 0], 3); FF(D,A,B,C,M[ 1], 7); - FF(C,D,A,B,M[ 2],11); FF(B,C,D,A,M[ 3],19); - FF(A,B,C,D,M[ 4], 3); FF(D,A,B,C,M[ 5], 7); - FF(C,D,A,B,M[ 6],11); FF(B,C,D,A,M[ 7],19); - FF(A,B,C,D,M[ 8], 3); FF(D,A,B,C,M[ 9], 7); - FF(C,D,A,B,M[10],11); FF(B,C,D,A,M[11],19); - FF(A,B,C,D,M[12], 3); FF(D,A,B,C,M[13], 7); - FF(C,D,A,B,M[14],11); FF(B,C,D,A,M[15],19); - - GG(A,B,C,D,M[ 0], 3); GG(D,A,B,C,M[ 4], 5); - GG(C,D,A,B,M[ 8], 9); GG(B,C,D,A,M[12],13); - GG(A,B,C,D,M[ 1], 3); GG(D,A,B,C,M[ 5], 5); - GG(C,D,A,B,M[ 9], 9); GG(B,C,D,A,M[13],13); - GG(A,B,C,D,M[ 2], 3); GG(D,A,B,C,M[ 6], 5); - GG(C,D,A,B,M[10], 9); GG(B,C,D,A,M[14],13); - GG(A,B,C,D,M[ 3], 3); GG(D,A,B,C,M[ 7], 5); - GG(C,D,A,B,M[11], 9); GG(B,C,D,A,M[15],13); - - HH(A,B,C,D,M[ 0], 3); HH(D,A,B,C,M[ 8], 9); - HH(C,D,A,B,M[ 4],11); HH(B,C,D,A,M[12],15); - HH(A,B,C,D,M[ 2], 3); HH(D,A,B,C,M[10], 9); - HH(C,D,A,B,M[ 6],11); HH(B,C,D,A,M[14],15); - HH(A,B,C,D,M[ 1], 3); HH(D,A,B,C,M[ 9], 9); - HH(C,D,A,B,M[ 5],11); HH(B,C,D,A,M[13],15); - HH(A,B,C,D,M[ 3], 3); HH(D,A,B,C,M[11], 9); - HH(C,D,A,B,M[ 7],11); HH(B,C,D,A,M[15],15); - - A = (digest[0] += A); - B = (digest[1] += B); - C = (digest[2] += C); - D = (digest[3] += D); - - input += hash_block_size(); - } - } - -/* -* Copy out the digest -*/ -void MD4::copy_out(byte output[]) - { - for(size_t i = 0; i != output_length(); i += 4) - store_le(digest[i/4], output + i); - } - -/* -* Clear memory of sensitive data -*/ -void MD4::clear() - { - MDx_HashFunction::clear(); - zeroise(M); - digest[0] = 0x67452301; - digest[1] = 0xEFCDAB89; - digest[2] = 0x98BADCFE; - digest[3] = 0x10325476; - } - -} -/* -* MD5 -* (C) 1999-2008 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -namespace { - -/* -* MD5 FF Function -*/ -inline void FF(u32bit& A, u32bit B, u32bit C, u32bit D, u32bit msg, - byte S, u32bit magic) - { - A += (D ^ (B & (C ^ D))) + msg + magic; - A = rotate_left(A, S) + B; - } - -/* -* MD5 GG Function -*/ -inline void GG(u32bit& A, u32bit B, u32bit C, u32bit D, u32bit msg, - byte S, u32bit magic) - { - A += (C ^ (D & (B ^ C))) + msg + magic; - A = rotate_left(A, S) + B; - } - -/* -* MD5 HH Function -*/ -inline void HH(u32bit& A, u32bit B, u32bit C, u32bit D, u32bit msg, - byte S, u32bit magic) - { - A += (B ^ C ^ D) + msg + magic; - A = rotate_left(A, S) + B; - } - -/* -* MD5 II Function -*/ -inline void II(u32bit& A, u32bit B, u32bit C, u32bit D, u32bit msg, - byte S, u32bit magic) - { - A += (C ^ (B | ~D)) + msg + magic; - A = rotate_left(A, S) + B; - } - -} - -/* -* MD5 Compression Function -*/ -void MD5::compress_n(const byte input[], size_t blocks) - { - u32bit A = digest[0], B = digest[1], C = digest[2], D = digest[3]; - - for(size_t i = 0; i != blocks; ++i) - { - load_le(&M[0], input, M.size()); - - FF(A,B,C,D,M[ 0], 7,0xD76AA478); FF(D,A,B,C,M[ 1],12,0xE8C7B756); - FF(C,D,A,B,M[ 2],17,0x242070DB); FF(B,C,D,A,M[ 3],22,0xC1BDCEEE); - FF(A,B,C,D,M[ 4], 7,0xF57C0FAF); FF(D,A,B,C,M[ 5],12,0x4787C62A); - FF(C,D,A,B,M[ 6],17,0xA8304613); FF(B,C,D,A,M[ 7],22,0xFD469501); - FF(A,B,C,D,M[ 8], 7,0x698098D8); FF(D,A,B,C,M[ 9],12,0x8B44F7AF); - FF(C,D,A,B,M[10],17,0xFFFF5BB1); FF(B,C,D,A,M[11],22,0x895CD7BE); - FF(A,B,C,D,M[12], 7,0x6B901122); FF(D,A,B,C,M[13],12,0xFD987193); - FF(C,D,A,B,M[14],17,0xA679438E); FF(B,C,D,A,M[15],22,0x49B40821); - - GG(A,B,C,D,M[ 1], 5,0xF61E2562); GG(D,A,B,C,M[ 6], 9,0xC040B340); - GG(C,D,A,B,M[11],14,0x265E5A51); GG(B,C,D,A,M[ 0],20,0xE9B6C7AA); - GG(A,B,C,D,M[ 5], 5,0xD62F105D); GG(D,A,B,C,M[10], 9,0x02441453); - GG(C,D,A,B,M[15],14,0xD8A1E681); GG(B,C,D,A,M[ 4],20,0xE7D3FBC8); - GG(A,B,C,D,M[ 9], 5,0x21E1CDE6); GG(D,A,B,C,M[14], 9,0xC33707D6); - GG(C,D,A,B,M[ 3],14,0xF4D50D87); GG(B,C,D,A,M[ 8],20,0x455A14ED); - GG(A,B,C,D,M[13], 5,0xA9E3E905); GG(D,A,B,C,M[ 2], 9,0xFCEFA3F8); - GG(C,D,A,B,M[ 7],14,0x676F02D9); GG(B,C,D,A,M[12],20,0x8D2A4C8A); - - HH(A,B,C,D,M[ 5], 4,0xFFFA3942); HH(D,A,B,C,M[ 8],11,0x8771F681); - HH(C,D,A,B,M[11],16,0x6D9D6122); HH(B,C,D,A,M[14],23,0xFDE5380C); - HH(A,B,C,D,M[ 1], 4,0xA4BEEA44); HH(D,A,B,C,M[ 4],11,0x4BDECFA9); - HH(C,D,A,B,M[ 7],16,0xF6BB4B60); HH(B,C,D,A,M[10],23,0xBEBFBC70); - HH(A,B,C,D,M[13], 4,0x289B7EC6); HH(D,A,B,C,M[ 0],11,0xEAA127FA); - HH(C,D,A,B,M[ 3],16,0xD4EF3085); HH(B,C,D,A,M[ 6],23,0x04881D05); - HH(A,B,C,D,M[ 9], 4,0xD9D4D039); HH(D,A,B,C,M[12],11,0xE6DB99E5); - HH(C,D,A,B,M[15],16,0x1FA27CF8); HH(B,C,D,A,M[ 2],23,0xC4AC5665); - - II(A,B,C,D,M[ 0], 6,0xF4292244); II(D,A,B,C,M[ 7],10,0x432AFF97); - II(C,D,A,B,M[14],15,0xAB9423A7); II(B,C,D,A,M[ 5],21,0xFC93A039); - II(A,B,C,D,M[12], 6,0x655B59C3); II(D,A,B,C,M[ 3],10,0x8F0CCC92); - II(C,D,A,B,M[10],15,0xFFEFF47D); II(B,C,D,A,M[ 1],21,0x85845DD1); - II(A,B,C,D,M[ 8], 6,0x6FA87E4F); II(D,A,B,C,M[15],10,0xFE2CE6E0); - II(C,D,A,B,M[ 6],15,0xA3014314); II(B,C,D,A,M[13],21,0x4E0811A1); - II(A,B,C,D,M[ 4], 6,0xF7537E82); II(D,A,B,C,M[11],10,0xBD3AF235); - II(C,D,A,B,M[ 2],15,0x2AD7D2BB); II(B,C,D,A,M[ 9],21,0xEB86D391); - - A = (digest[0] += A); - B = (digest[1] += B); - C = (digest[2] += C); - D = (digest[3] += D); - - input += hash_block_size(); - } - } - -/* -* Copy out the digest -*/ -void MD5::copy_out(byte output[]) - { - for(size_t i = 0; i != output_length(); i += 4) - store_le(digest[i/4], output + i); - } - -/* -* Clear memory of sensitive data -*/ -void MD5::clear() - { - MDx_HashFunction::clear(); - zeroise(M); - digest[0] = 0x67452301; - digest[1] = 0xEFCDAB89; - digest[2] = 0x98BADCFE; - digest[3] = 0x10325476; - } - -} -/* -* Merkle-Damgard Hash Function -* (C) 1999-2008 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -/* -* MDx_HashFunction Constructor -*/ -MDx_HashFunction::MDx_HashFunction(size_t block_len, - bool byte_end, - bool bit_end, - size_t cnt_size) : - buffer(block_len), - BIG_BYTE_ENDIAN(byte_end), - BIG_BIT_ENDIAN(bit_end), - COUNT_SIZE(cnt_size) - { - count = position = 0; - } - -/* -* Clear memory of sensitive data -*/ -void MDx_HashFunction::clear() - { - zeroise(buffer); - count = position = 0; - } - -/* -* Update the hash -*/ -void MDx_HashFunction::add_data(const byte input[], size_t length) - { - count += length; - - if(position) - { - buffer.copy(position, input, length); - - if(position + length >= buffer.size()) - { - compress_n(&buffer[0], 1); - input += (buffer.size() - position); - length -= (buffer.size() - position); - position = 0; - } - } - - const size_t full_blocks = length / buffer.size(); - const size_t remaining = length % buffer.size(); - - if(full_blocks) - compress_n(input, full_blocks); - - buffer.copy(position, input + full_blocks * buffer.size(), remaining); - position += remaining; - } - -/* -* Finalize a hash -*/ -void MDx_HashFunction::final_result(byte output[]) - { - buffer[position] = (BIG_BIT_ENDIAN ? 0x80 : 0x01); - for(size_t i = position+1; i != buffer.size(); ++i) - buffer[i] = 0; - - if(position >= buffer.size() - COUNT_SIZE) - { - compress_n(&buffer[0], 1); - zeroise(buffer); - } - - write_count(&buffer[buffer.size() - COUNT_SIZE]); - - compress_n(&buffer[0], 1); - copy_out(output); - clear(); - } - -/* -* Write the count bits to the buffer -*/ -void MDx_HashFunction::write_count(byte out[]) - { - if(COUNT_SIZE < 8) - throw Invalid_State("MDx_HashFunction::write_count: COUNT_SIZE < 8"); - if(COUNT_SIZE >= output_length() || COUNT_SIZE >= hash_block_size()) - throw Invalid_Argument("MDx_HashFunction: COUNT_SIZE is too big"); - - const u64bit bit_count = count * 8; - - if(BIG_BYTE_ENDIAN) - store_be(bit_count, out + COUNT_SIZE - 8); - else - store_le(bit_count, out + COUNT_SIZE - 8); - } - -} -/* -* Parallel -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -/* -* Update the hash -*/ -void Parallel::add_data(const byte input[], size_t length) - { - for(size_t i = 0; i != hashes.size(); ++i) - hashes[i]->update(input, length); - } - -/* -* Finalize the hash -*/ -void Parallel::final_result(byte hash[]) - { - size_t offset = 0; - for(size_t i = 0; i != hashes.size(); ++i) - { - hashes[i]->final(hash + offset); - offset += hashes[i]->output_length(); - } - } - -/* -* Return output size -*/ -size_t Parallel::output_length() const - { - size_t sum = 0; - for(size_t i = 0; i != hashes.size(); ++i) - sum += hashes[i]->output_length(); - return sum; - } - -/* -* Return the name of this type -*/ -std::string Parallel::name() const - { - std::string hash_names; - for(size_t i = 0; i != hashes.size(); ++i) - { - if(i) - hash_names += ','; - hash_names += hashes[i]->name(); - } - return "Parallel(" + hash_names + ")"; - } - -/* -* Return a clone of this object -*/ -HashFunction* Parallel::clone() const - { - std::vector hash_copies; - for(size_t i = 0; i != hashes.size(); ++i) - hash_copies.push_back(hashes[i]->clone()); - return new Parallel(hash_copies); - } - -/* -* Clear memory of sensitive data -*/ -void Parallel::clear() - { - for(size_t i = 0; i != hashes.size(); ++i) - hashes[i]->clear(); - } - -/* -* Parallel Constructor -*/ -Parallel::Parallel(const std::vector& hash_in) : - hashes(hash_in) - { - } - -/* -* Parallel Destructor -*/ -Parallel::~Parallel() - { - for(size_t i = 0; i != hashes.size(); ++i) - delete hashes[i]; - } - -} -/* -* RIPEMD-128 -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -namespace RIPEMD_128_F { - -/* -* RIPEMD-128 F1 Function -*/ -inline void F1(u32bit& A, u32bit B, u32bit C, u32bit D, - u32bit msg, u32bit shift) - { - A += (B ^ C ^ D) + msg; - A = rotate_left(A, shift); - } - -/* -* RIPEMD-128 F2 Function -*/ -inline void F2(u32bit& A, u32bit B, u32bit C, u32bit D, - u32bit msg, u32bit shift, u32bit magic) - { - A += (D ^ (B & (C ^ D))) + msg + magic; - A = rotate_left(A, shift); - } - -/* -* RIPEMD-128 F3 Function -*/ -inline void F3(u32bit& A, u32bit B, u32bit C, u32bit D, - u32bit msg, u32bit shift, u32bit magic) - { - A += (D ^ (B | ~C)) + msg + magic; - A = rotate_left(A, shift); - } - -/* -* RIPEMD-128 F4 Function -*/ -inline void F4(u32bit& A, u32bit B, u32bit C, u32bit D, - u32bit msg, u32bit shift, u32bit magic) - { - A += (C ^ (D & (B ^ C))) + msg + magic; - A = rotate_left(A, shift); - } - -} - -/* -* RIPEMD-128 Compression Function -*/ -void RIPEMD_128::compress_n(const byte input[], size_t blocks) - { - using namespace RIPEMD_128_F; - - const u32bit MAGIC2 = 0x5A827999, MAGIC3 = 0x6ED9EBA1, - MAGIC4 = 0x8F1BBCDC, MAGIC5 = 0x50A28BE6, - MAGIC6 = 0x5C4DD124, MAGIC7 = 0x6D703EF3; - - for(size_t i = 0; i != blocks; ++i) - { - load_le(&M[0], input, M.size()); - - u32bit A1 = digest[0], A2 = A1, B1 = digest[1], B2 = B1, - C1 = digest[2], C2 = C1, D1 = digest[3], D2 = D1; - - F1(A1,B1,C1,D1,M[ 0],11 ); F4(A2,B2,C2,D2,M[ 5], 8,MAGIC5); - F1(D1,A1,B1,C1,M[ 1],14 ); F4(D2,A2,B2,C2,M[14], 9,MAGIC5); - F1(C1,D1,A1,B1,M[ 2],15 ); F4(C2,D2,A2,B2,M[ 7], 9,MAGIC5); - F1(B1,C1,D1,A1,M[ 3],12 ); F4(B2,C2,D2,A2,M[ 0],11,MAGIC5); - F1(A1,B1,C1,D1,M[ 4], 5 ); F4(A2,B2,C2,D2,M[ 9],13,MAGIC5); - F1(D1,A1,B1,C1,M[ 5], 8 ); F4(D2,A2,B2,C2,M[ 2],15,MAGIC5); - F1(C1,D1,A1,B1,M[ 6], 7 ); F4(C2,D2,A2,B2,M[11],15,MAGIC5); - F1(B1,C1,D1,A1,M[ 7], 9 ); F4(B2,C2,D2,A2,M[ 4], 5,MAGIC5); - F1(A1,B1,C1,D1,M[ 8],11 ); F4(A2,B2,C2,D2,M[13], 7,MAGIC5); - F1(D1,A1,B1,C1,M[ 9],13 ); F4(D2,A2,B2,C2,M[ 6], 7,MAGIC5); - F1(C1,D1,A1,B1,M[10],14 ); F4(C2,D2,A2,B2,M[15], 8,MAGIC5); - F1(B1,C1,D1,A1,M[11],15 ); F4(B2,C2,D2,A2,M[ 8],11,MAGIC5); - F1(A1,B1,C1,D1,M[12], 6 ); F4(A2,B2,C2,D2,M[ 1],14,MAGIC5); - F1(D1,A1,B1,C1,M[13], 7 ); F4(D2,A2,B2,C2,M[10],14,MAGIC5); - F1(C1,D1,A1,B1,M[14], 9 ); F4(C2,D2,A2,B2,M[ 3],12,MAGIC5); - F1(B1,C1,D1,A1,M[15], 8 ); F4(B2,C2,D2,A2,M[12], 6,MAGIC5); - - F2(A1,B1,C1,D1,M[ 7], 7,MAGIC2); F3(A2,B2,C2,D2,M[ 6], 9,MAGIC6); - F2(D1,A1,B1,C1,M[ 4], 6,MAGIC2); F3(D2,A2,B2,C2,M[11],13,MAGIC6); - F2(C1,D1,A1,B1,M[13], 8,MAGIC2); F3(C2,D2,A2,B2,M[ 3],15,MAGIC6); - F2(B1,C1,D1,A1,M[ 1],13,MAGIC2); F3(B2,C2,D2,A2,M[ 7], 7,MAGIC6); - F2(A1,B1,C1,D1,M[10],11,MAGIC2); F3(A2,B2,C2,D2,M[ 0],12,MAGIC6); - F2(D1,A1,B1,C1,M[ 6], 9,MAGIC2); F3(D2,A2,B2,C2,M[13], 8,MAGIC6); - F2(C1,D1,A1,B1,M[15], 7,MAGIC2); F3(C2,D2,A2,B2,M[ 5], 9,MAGIC6); - F2(B1,C1,D1,A1,M[ 3],15,MAGIC2); F3(B2,C2,D2,A2,M[10],11,MAGIC6); - F2(A1,B1,C1,D1,M[12], 7,MAGIC2); F3(A2,B2,C2,D2,M[14], 7,MAGIC6); - F2(D1,A1,B1,C1,M[ 0],12,MAGIC2); F3(D2,A2,B2,C2,M[15], 7,MAGIC6); - F2(C1,D1,A1,B1,M[ 9],15,MAGIC2); F3(C2,D2,A2,B2,M[ 8],12,MAGIC6); - F2(B1,C1,D1,A1,M[ 5], 9,MAGIC2); F3(B2,C2,D2,A2,M[12], 7,MAGIC6); - F2(A1,B1,C1,D1,M[ 2],11,MAGIC2); F3(A2,B2,C2,D2,M[ 4], 6,MAGIC6); - F2(D1,A1,B1,C1,M[14], 7,MAGIC2); F3(D2,A2,B2,C2,M[ 9],15,MAGIC6); - F2(C1,D1,A1,B1,M[11],13,MAGIC2); F3(C2,D2,A2,B2,M[ 1],13,MAGIC6); - F2(B1,C1,D1,A1,M[ 8],12,MAGIC2); F3(B2,C2,D2,A2,M[ 2],11,MAGIC6); - - F3(A1,B1,C1,D1,M[ 3],11,MAGIC3); F2(A2,B2,C2,D2,M[15], 9,MAGIC7); - F3(D1,A1,B1,C1,M[10],13,MAGIC3); F2(D2,A2,B2,C2,M[ 5], 7,MAGIC7); - F3(C1,D1,A1,B1,M[14], 6,MAGIC3); F2(C2,D2,A2,B2,M[ 1],15,MAGIC7); - F3(B1,C1,D1,A1,M[ 4], 7,MAGIC3); F2(B2,C2,D2,A2,M[ 3],11,MAGIC7); - F3(A1,B1,C1,D1,M[ 9],14,MAGIC3); F2(A2,B2,C2,D2,M[ 7], 8,MAGIC7); - F3(D1,A1,B1,C1,M[15], 9,MAGIC3); F2(D2,A2,B2,C2,M[14], 6,MAGIC7); - F3(C1,D1,A1,B1,M[ 8],13,MAGIC3); F2(C2,D2,A2,B2,M[ 6], 6,MAGIC7); - F3(B1,C1,D1,A1,M[ 1],15,MAGIC3); F2(B2,C2,D2,A2,M[ 9],14,MAGIC7); - F3(A1,B1,C1,D1,M[ 2],14,MAGIC3); F2(A2,B2,C2,D2,M[11],12,MAGIC7); - F3(D1,A1,B1,C1,M[ 7], 8,MAGIC3); F2(D2,A2,B2,C2,M[ 8],13,MAGIC7); - F3(C1,D1,A1,B1,M[ 0],13,MAGIC3); F2(C2,D2,A2,B2,M[12], 5,MAGIC7); - F3(B1,C1,D1,A1,M[ 6], 6,MAGIC3); F2(B2,C2,D2,A2,M[ 2],14,MAGIC7); - F3(A1,B1,C1,D1,M[13], 5,MAGIC3); F2(A2,B2,C2,D2,M[10],13,MAGIC7); - F3(D1,A1,B1,C1,M[11],12,MAGIC3); F2(D2,A2,B2,C2,M[ 0],13,MAGIC7); - F3(C1,D1,A1,B1,M[ 5], 7,MAGIC3); F2(C2,D2,A2,B2,M[ 4], 7,MAGIC7); - F3(B1,C1,D1,A1,M[12], 5,MAGIC3); F2(B2,C2,D2,A2,M[13], 5,MAGIC7); - - F4(A1,B1,C1,D1,M[ 1],11,MAGIC4); F1(A2,B2,C2,D2,M[ 8],15 ); - F4(D1,A1,B1,C1,M[ 9],12,MAGIC4); F1(D2,A2,B2,C2,M[ 6], 5 ); - F4(C1,D1,A1,B1,M[11],14,MAGIC4); F1(C2,D2,A2,B2,M[ 4], 8 ); - F4(B1,C1,D1,A1,M[10],15,MAGIC4); F1(B2,C2,D2,A2,M[ 1],11 ); - F4(A1,B1,C1,D1,M[ 0],14,MAGIC4); F1(A2,B2,C2,D2,M[ 3],14 ); - F4(D1,A1,B1,C1,M[ 8],15,MAGIC4); F1(D2,A2,B2,C2,M[11],14 ); - F4(C1,D1,A1,B1,M[12], 9,MAGIC4); F1(C2,D2,A2,B2,M[15], 6 ); - F4(B1,C1,D1,A1,M[ 4], 8,MAGIC4); F1(B2,C2,D2,A2,M[ 0],14 ); - F4(A1,B1,C1,D1,M[13], 9,MAGIC4); F1(A2,B2,C2,D2,M[ 5], 6 ); - F4(D1,A1,B1,C1,M[ 3],14,MAGIC4); F1(D2,A2,B2,C2,M[12], 9 ); - F4(C1,D1,A1,B1,M[ 7], 5,MAGIC4); F1(C2,D2,A2,B2,M[ 2],12 ); - F4(B1,C1,D1,A1,M[15], 6,MAGIC4); F1(B2,C2,D2,A2,M[13], 9 ); - F4(A1,B1,C1,D1,M[14], 8,MAGIC4); F1(A2,B2,C2,D2,M[ 9],12 ); - F4(D1,A1,B1,C1,M[ 5], 6,MAGIC4); F1(D2,A2,B2,C2,M[ 7], 5 ); - F4(C1,D1,A1,B1,M[ 6], 5,MAGIC4); F1(C2,D2,A2,B2,M[10],15 ); - F4(B1,C1,D1,A1,M[ 2],12,MAGIC4); F1(B2,C2,D2,A2,M[14], 8 ); - - D2 = digest[1] + C1 + D2; - digest[1] = digest[2] + D1 + A2; - digest[2] = digest[3] + A1 + B2; - digest[3] = digest[0] + B1 + C2; - digest[0] = D2; - - input += hash_block_size(); - } - } - -/* -* Copy out the digest -*/ -void RIPEMD_128::copy_out(byte output[]) - { - for(size_t i = 0; i != output_length(); i += 4) - store_le(digest[i/4], output + i); - } - -/* -* Clear memory of sensitive data -*/ -void RIPEMD_128::clear() - { - MDx_HashFunction::clear(); - zeroise(M); - digest[0] = 0x67452301; - digest[1] = 0xEFCDAB89; - digest[2] = 0x98BADCFE; - digest[3] = 0x10325476; - } - -} -/* -* RIPEMD-160 -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -namespace { - -/* -* RIPEMD-160 F1 Function -*/ -inline void F1(u32bit& A, u32bit B, u32bit& C, u32bit D, u32bit E, - u32bit msg, u32bit shift) - { - A += (B ^ C ^ D) + msg; - A = rotate_left(A, shift) + E; - C = rotate_left(C, 10); - } - -/* -* RIPEMD-160 F2 Function -*/ -inline void F2(u32bit& A, u32bit B, u32bit& C, u32bit D, u32bit E, - u32bit msg, u32bit shift, u32bit magic) - { - A += (D ^ (B & (C ^ D))) + msg + magic; - A = rotate_left(A, shift) + E; - C = rotate_left(C, 10); - } - -/* -* RIPEMD-160 F3 Function -*/ -inline void F3(u32bit& A, u32bit B, u32bit& C, u32bit D, u32bit E, - u32bit msg, u32bit shift, u32bit magic) - { - A += (D ^ (B | ~C)) + msg + magic; - A = rotate_left(A, shift) + E; - C = rotate_left(C, 10); - } - -/* -* RIPEMD-160 F4 Function -*/ -inline void F4(u32bit& A, u32bit B, u32bit& C, u32bit D, u32bit E, - u32bit msg, u32bit shift, u32bit magic) - { - A += (C ^ (D & (B ^ C))) + msg + magic; - A = rotate_left(A, shift) + E; - C = rotate_left(C, 10); - } - -/* -* RIPEMD-160 F5 Function -*/ -inline void F5(u32bit& A, u32bit B, u32bit& C, u32bit D, u32bit E, - u32bit msg, u32bit shift, u32bit magic) - { - A += (B ^ (C | ~D)) + msg + magic; - A = rotate_left(A, shift) + E; - C = rotate_left(C, 10); - } - -} - -/* -* RIPEMD-160 Compression Function -*/ -void RIPEMD_160::compress_n(const byte input[], size_t blocks) - { - const u32bit MAGIC2 = 0x5A827999, MAGIC3 = 0x6ED9EBA1, - MAGIC4 = 0x8F1BBCDC, MAGIC5 = 0xA953FD4E, - MAGIC6 = 0x50A28BE6, MAGIC7 = 0x5C4DD124, - MAGIC8 = 0x6D703EF3, MAGIC9 = 0x7A6D76E9; - - for(size_t i = 0; i != blocks; ++i) - { - load_le(&M[0], input, M.size()); - - u32bit A1 = digest[0], A2 = A1, B1 = digest[1], B2 = B1, - C1 = digest[2], C2 = C1, D1 = digest[3], D2 = D1, - E1 = digest[4], E2 = E1; - - F1(A1,B1,C1,D1,E1,M[ 0],11 ); F5(A2,B2,C2,D2,E2,M[ 5], 8,MAGIC6); - F1(E1,A1,B1,C1,D1,M[ 1],14 ); F5(E2,A2,B2,C2,D2,M[14], 9,MAGIC6); - F1(D1,E1,A1,B1,C1,M[ 2],15 ); F5(D2,E2,A2,B2,C2,M[ 7], 9,MAGIC6); - F1(C1,D1,E1,A1,B1,M[ 3],12 ); F5(C2,D2,E2,A2,B2,M[ 0],11,MAGIC6); - F1(B1,C1,D1,E1,A1,M[ 4], 5 ); F5(B2,C2,D2,E2,A2,M[ 9],13,MAGIC6); - F1(A1,B1,C1,D1,E1,M[ 5], 8 ); F5(A2,B2,C2,D2,E2,M[ 2],15,MAGIC6); - F1(E1,A1,B1,C1,D1,M[ 6], 7 ); F5(E2,A2,B2,C2,D2,M[11],15,MAGIC6); - F1(D1,E1,A1,B1,C1,M[ 7], 9 ); F5(D2,E2,A2,B2,C2,M[ 4], 5,MAGIC6); - F1(C1,D1,E1,A1,B1,M[ 8],11 ); F5(C2,D2,E2,A2,B2,M[13], 7,MAGIC6); - F1(B1,C1,D1,E1,A1,M[ 9],13 ); F5(B2,C2,D2,E2,A2,M[ 6], 7,MAGIC6); - F1(A1,B1,C1,D1,E1,M[10],14 ); F5(A2,B2,C2,D2,E2,M[15], 8,MAGIC6); - F1(E1,A1,B1,C1,D1,M[11],15 ); F5(E2,A2,B2,C2,D2,M[ 8],11,MAGIC6); - F1(D1,E1,A1,B1,C1,M[12], 6 ); F5(D2,E2,A2,B2,C2,M[ 1],14,MAGIC6); - F1(C1,D1,E1,A1,B1,M[13], 7 ); F5(C2,D2,E2,A2,B2,M[10],14,MAGIC6); - F1(B1,C1,D1,E1,A1,M[14], 9 ); F5(B2,C2,D2,E2,A2,M[ 3],12,MAGIC6); - F1(A1,B1,C1,D1,E1,M[15], 8 ); F5(A2,B2,C2,D2,E2,M[12], 6,MAGIC6); - - F2(E1,A1,B1,C1,D1,M[ 7], 7,MAGIC2); F4(E2,A2,B2,C2,D2,M[ 6], 9,MAGIC7); - F2(D1,E1,A1,B1,C1,M[ 4], 6,MAGIC2); F4(D2,E2,A2,B2,C2,M[11],13,MAGIC7); - F2(C1,D1,E1,A1,B1,M[13], 8,MAGIC2); F4(C2,D2,E2,A2,B2,M[ 3],15,MAGIC7); - F2(B1,C1,D1,E1,A1,M[ 1],13,MAGIC2); F4(B2,C2,D2,E2,A2,M[ 7], 7,MAGIC7); - F2(A1,B1,C1,D1,E1,M[10],11,MAGIC2); F4(A2,B2,C2,D2,E2,M[ 0],12,MAGIC7); - F2(E1,A1,B1,C1,D1,M[ 6], 9,MAGIC2); F4(E2,A2,B2,C2,D2,M[13], 8,MAGIC7); - F2(D1,E1,A1,B1,C1,M[15], 7,MAGIC2); F4(D2,E2,A2,B2,C2,M[ 5], 9,MAGIC7); - F2(C1,D1,E1,A1,B1,M[ 3],15,MAGIC2); F4(C2,D2,E2,A2,B2,M[10],11,MAGIC7); - F2(B1,C1,D1,E1,A1,M[12], 7,MAGIC2); F4(B2,C2,D2,E2,A2,M[14], 7,MAGIC7); - F2(A1,B1,C1,D1,E1,M[ 0],12,MAGIC2); F4(A2,B2,C2,D2,E2,M[15], 7,MAGIC7); - F2(E1,A1,B1,C1,D1,M[ 9],15,MAGIC2); F4(E2,A2,B2,C2,D2,M[ 8],12,MAGIC7); - F2(D1,E1,A1,B1,C1,M[ 5], 9,MAGIC2); F4(D2,E2,A2,B2,C2,M[12], 7,MAGIC7); - F2(C1,D1,E1,A1,B1,M[ 2],11,MAGIC2); F4(C2,D2,E2,A2,B2,M[ 4], 6,MAGIC7); - F2(B1,C1,D1,E1,A1,M[14], 7,MAGIC2); F4(B2,C2,D2,E2,A2,M[ 9],15,MAGIC7); - F2(A1,B1,C1,D1,E1,M[11],13,MAGIC2); F4(A2,B2,C2,D2,E2,M[ 1],13,MAGIC7); - F2(E1,A1,B1,C1,D1,M[ 8],12,MAGIC2); F4(E2,A2,B2,C2,D2,M[ 2],11,MAGIC7); - - F3(D1,E1,A1,B1,C1,M[ 3],11,MAGIC3); F3(D2,E2,A2,B2,C2,M[15], 9,MAGIC8); - F3(C1,D1,E1,A1,B1,M[10],13,MAGIC3); F3(C2,D2,E2,A2,B2,M[ 5], 7,MAGIC8); - F3(B1,C1,D1,E1,A1,M[14], 6,MAGIC3); F3(B2,C2,D2,E2,A2,M[ 1],15,MAGIC8); - F3(A1,B1,C1,D1,E1,M[ 4], 7,MAGIC3); F3(A2,B2,C2,D2,E2,M[ 3],11,MAGIC8); - F3(E1,A1,B1,C1,D1,M[ 9],14,MAGIC3); F3(E2,A2,B2,C2,D2,M[ 7], 8,MAGIC8); - F3(D1,E1,A1,B1,C1,M[15], 9,MAGIC3); F3(D2,E2,A2,B2,C2,M[14], 6,MAGIC8); - F3(C1,D1,E1,A1,B1,M[ 8],13,MAGIC3); F3(C2,D2,E2,A2,B2,M[ 6], 6,MAGIC8); - F3(B1,C1,D1,E1,A1,M[ 1],15,MAGIC3); F3(B2,C2,D2,E2,A2,M[ 9],14,MAGIC8); - F3(A1,B1,C1,D1,E1,M[ 2],14,MAGIC3); F3(A2,B2,C2,D2,E2,M[11],12,MAGIC8); - F3(E1,A1,B1,C1,D1,M[ 7], 8,MAGIC3); F3(E2,A2,B2,C2,D2,M[ 8],13,MAGIC8); - F3(D1,E1,A1,B1,C1,M[ 0],13,MAGIC3); F3(D2,E2,A2,B2,C2,M[12], 5,MAGIC8); - F3(C1,D1,E1,A1,B1,M[ 6], 6,MAGIC3); F3(C2,D2,E2,A2,B2,M[ 2],14,MAGIC8); - F3(B1,C1,D1,E1,A1,M[13], 5,MAGIC3); F3(B2,C2,D2,E2,A2,M[10],13,MAGIC8); - F3(A1,B1,C1,D1,E1,M[11],12,MAGIC3); F3(A2,B2,C2,D2,E2,M[ 0],13,MAGIC8); - F3(E1,A1,B1,C1,D1,M[ 5], 7,MAGIC3); F3(E2,A2,B2,C2,D2,M[ 4], 7,MAGIC8); - F3(D1,E1,A1,B1,C1,M[12], 5,MAGIC3); F3(D2,E2,A2,B2,C2,M[13], 5,MAGIC8); - - F4(C1,D1,E1,A1,B1,M[ 1],11,MAGIC4); F2(C2,D2,E2,A2,B2,M[ 8],15,MAGIC9); - F4(B1,C1,D1,E1,A1,M[ 9],12,MAGIC4); F2(B2,C2,D2,E2,A2,M[ 6], 5,MAGIC9); - F4(A1,B1,C1,D1,E1,M[11],14,MAGIC4); F2(A2,B2,C2,D2,E2,M[ 4], 8,MAGIC9); - F4(E1,A1,B1,C1,D1,M[10],15,MAGIC4); F2(E2,A2,B2,C2,D2,M[ 1],11,MAGIC9); - F4(D1,E1,A1,B1,C1,M[ 0],14,MAGIC4); F2(D2,E2,A2,B2,C2,M[ 3],14,MAGIC9); - F4(C1,D1,E1,A1,B1,M[ 8],15,MAGIC4); F2(C2,D2,E2,A2,B2,M[11],14,MAGIC9); - F4(B1,C1,D1,E1,A1,M[12], 9,MAGIC4); F2(B2,C2,D2,E2,A2,M[15], 6,MAGIC9); - F4(A1,B1,C1,D1,E1,M[ 4], 8,MAGIC4); F2(A2,B2,C2,D2,E2,M[ 0],14,MAGIC9); - F4(E1,A1,B1,C1,D1,M[13], 9,MAGIC4); F2(E2,A2,B2,C2,D2,M[ 5], 6,MAGIC9); - F4(D1,E1,A1,B1,C1,M[ 3],14,MAGIC4); F2(D2,E2,A2,B2,C2,M[12], 9,MAGIC9); - F4(C1,D1,E1,A1,B1,M[ 7], 5,MAGIC4); F2(C2,D2,E2,A2,B2,M[ 2],12,MAGIC9); - F4(B1,C1,D1,E1,A1,M[15], 6,MAGIC4); F2(B2,C2,D2,E2,A2,M[13], 9,MAGIC9); - F4(A1,B1,C1,D1,E1,M[14], 8,MAGIC4); F2(A2,B2,C2,D2,E2,M[ 9],12,MAGIC9); - F4(E1,A1,B1,C1,D1,M[ 5], 6,MAGIC4); F2(E2,A2,B2,C2,D2,M[ 7], 5,MAGIC9); - F4(D1,E1,A1,B1,C1,M[ 6], 5,MAGIC4); F2(D2,E2,A2,B2,C2,M[10],15,MAGIC9); - F4(C1,D1,E1,A1,B1,M[ 2],12,MAGIC4); F2(C2,D2,E2,A2,B2,M[14], 8,MAGIC9); - - F5(B1,C1,D1,E1,A1,M[ 4], 9,MAGIC5); F1(B2,C2,D2,E2,A2,M[12], 8 ); - F5(A1,B1,C1,D1,E1,M[ 0],15,MAGIC5); F1(A2,B2,C2,D2,E2,M[15], 5 ); - F5(E1,A1,B1,C1,D1,M[ 5], 5,MAGIC5); F1(E2,A2,B2,C2,D2,M[10],12 ); - F5(D1,E1,A1,B1,C1,M[ 9],11,MAGIC5); F1(D2,E2,A2,B2,C2,M[ 4], 9 ); - F5(C1,D1,E1,A1,B1,M[ 7], 6,MAGIC5); F1(C2,D2,E2,A2,B2,M[ 1],12 ); - F5(B1,C1,D1,E1,A1,M[12], 8,MAGIC5); F1(B2,C2,D2,E2,A2,M[ 5], 5 ); - F5(A1,B1,C1,D1,E1,M[ 2],13,MAGIC5); F1(A2,B2,C2,D2,E2,M[ 8],14 ); - F5(E1,A1,B1,C1,D1,M[10],12,MAGIC5); F1(E2,A2,B2,C2,D2,M[ 7], 6 ); - F5(D1,E1,A1,B1,C1,M[14], 5,MAGIC5); F1(D2,E2,A2,B2,C2,M[ 6], 8 ); - F5(C1,D1,E1,A1,B1,M[ 1],12,MAGIC5); F1(C2,D2,E2,A2,B2,M[ 2],13 ); - F5(B1,C1,D1,E1,A1,M[ 3],13,MAGIC5); F1(B2,C2,D2,E2,A2,M[13], 6 ); - F5(A1,B1,C1,D1,E1,M[ 8],14,MAGIC5); F1(A2,B2,C2,D2,E2,M[14], 5 ); - F5(E1,A1,B1,C1,D1,M[11],11,MAGIC5); F1(E2,A2,B2,C2,D2,M[ 0],15 ); - F5(D1,E1,A1,B1,C1,M[ 6], 8,MAGIC5); F1(D2,E2,A2,B2,C2,M[ 3],13 ); - F5(C1,D1,E1,A1,B1,M[15], 5,MAGIC5); F1(C2,D2,E2,A2,B2,M[ 9],11 ); - F5(B1,C1,D1,E1,A1,M[13], 6,MAGIC5); F1(B2,C2,D2,E2,A2,M[11],11 ); - - C1 = digest[1] + C1 + D2; - digest[1] = digest[2] + D1 + E2; - digest[2] = digest[3] + E1 + A2; - digest[3] = digest[4] + A1 + B2; - digest[4] = digest[0] + B1 + C2; - digest[0] = C1; - - input += hash_block_size(); - } - } - -/* -* Copy out the digest -*/ -void RIPEMD_160::copy_out(byte output[]) - { - for(size_t i = 0; i != output_length(); i += 4) - store_le(digest[i/4], output + i); - } - -/* -* Clear memory of sensitive data -*/ -void RIPEMD_160::clear() - { - MDx_HashFunction::clear(); - zeroise(M); - digest[0] = 0x67452301; - digest[1] = 0xEFCDAB89; - digest[2] = 0x98BADCFE; - digest[3] = 0x10325476; - digest[4] = 0xC3D2E1F0; - } - -} -/* -* SHA-160 -* (C) 1999-2008,2011 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -namespace SHA1_F { - -namespace { - -/* -* SHA-160 F1 Function -*/ -inline void F1(u32bit A, u32bit& B, u32bit C, u32bit D, u32bit& E, u32bit msg) - { - E += (D ^ (B & (C ^ D))) + msg + 0x5A827999 + rotate_left(A, 5); - B = rotate_left(B, 30); - } - -/* -* SHA-160 F2 Function -*/ -inline void F2(u32bit A, u32bit& B, u32bit C, u32bit D, u32bit& E, u32bit msg) - { - E += (B ^ C ^ D) + msg + 0x6ED9EBA1 + rotate_left(A, 5); - B = rotate_left(B, 30); - } - -/* -* SHA-160 F3 Function -*/ -inline void F3(u32bit A, u32bit& B, u32bit C, u32bit D, u32bit& E, u32bit msg) - { - E += ((B & C) | ((B | C) & D)) + msg + 0x8F1BBCDC + rotate_left(A, 5); - B = rotate_left(B, 30); - } - -/* -* SHA-160 F4 Function -*/ -inline void F4(u32bit A, u32bit& B, u32bit C, u32bit D, u32bit& E, u32bit msg) - { - E += (B ^ C ^ D) + msg + 0xCA62C1D6 + rotate_left(A, 5); - B = rotate_left(B, 30); - } - -} - -} - -/* -* SHA-160 Compression Function -*/ -void SHA_160::compress_n(const byte input[], size_t blocks) - { - using namespace SHA1_F; - - u32bit A = digest[0], B = digest[1], C = digest[2], - D = digest[3], E = digest[4]; - - for(size_t i = 0; i != blocks; ++i) - { - load_be(&W[0], input, 16); - - for(size_t j = 16; j != 80; j += 8) - { - W[j ] = rotate_left((W[j-3] ^ W[j-8] ^ W[j-14] ^ W[j-16]), 1); - W[j+1] = rotate_left((W[j-2] ^ W[j-7] ^ W[j-13] ^ W[j-15]), 1); - W[j+2] = rotate_left((W[j-1] ^ W[j-6] ^ W[j-12] ^ W[j-14]), 1); - W[j+3] = rotate_left((W[j ] ^ W[j-5] ^ W[j-11] ^ W[j-13]), 1); - W[j+4] = rotate_left((W[j+1] ^ W[j-4] ^ W[j-10] ^ W[j-12]), 1); - W[j+5] = rotate_left((W[j+2] ^ W[j-3] ^ W[j- 9] ^ W[j-11]), 1); - W[j+6] = rotate_left((W[j+3] ^ W[j-2] ^ W[j- 8] ^ W[j-10]), 1); - W[j+7] = rotate_left((W[j+4] ^ W[j-1] ^ W[j- 7] ^ W[j- 9]), 1); - } - - F1(A, B, C, D, E, W[ 0]); F1(E, A, B, C, D, W[ 1]); - F1(D, E, A, B, C, W[ 2]); F1(C, D, E, A, B, W[ 3]); - F1(B, C, D, E, A, W[ 4]); F1(A, B, C, D, E, W[ 5]); - F1(E, A, B, C, D, W[ 6]); F1(D, E, A, B, C, W[ 7]); - F1(C, D, E, A, B, W[ 8]); F1(B, C, D, E, A, W[ 9]); - F1(A, B, C, D, E, W[10]); F1(E, A, B, C, D, W[11]); - F1(D, E, A, B, C, W[12]); F1(C, D, E, A, B, W[13]); - F1(B, C, D, E, A, W[14]); F1(A, B, C, D, E, W[15]); - F1(E, A, B, C, D, W[16]); F1(D, E, A, B, C, W[17]); - F1(C, D, E, A, B, W[18]); F1(B, C, D, E, A, W[19]); - - F2(A, B, C, D, E, W[20]); F2(E, A, B, C, D, W[21]); - F2(D, E, A, B, C, W[22]); F2(C, D, E, A, B, W[23]); - F2(B, C, D, E, A, W[24]); F2(A, B, C, D, E, W[25]); - F2(E, A, B, C, D, W[26]); F2(D, E, A, B, C, W[27]); - F2(C, D, E, A, B, W[28]); F2(B, C, D, E, A, W[29]); - F2(A, B, C, D, E, W[30]); F2(E, A, B, C, D, W[31]); - F2(D, E, A, B, C, W[32]); F2(C, D, E, A, B, W[33]); - F2(B, C, D, E, A, W[34]); F2(A, B, C, D, E, W[35]); - F2(E, A, B, C, D, W[36]); F2(D, E, A, B, C, W[37]); - F2(C, D, E, A, B, W[38]); F2(B, C, D, E, A, W[39]); - - F3(A, B, C, D, E, W[40]); F3(E, A, B, C, D, W[41]); - F3(D, E, A, B, C, W[42]); F3(C, D, E, A, B, W[43]); - F3(B, C, D, E, A, W[44]); F3(A, B, C, D, E, W[45]); - F3(E, A, B, C, D, W[46]); F3(D, E, A, B, C, W[47]); - F3(C, D, E, A, B, W[48]); F3(B, C, D, E, A, W[49]); - F3(A, B, C, D, E, W[50]); F3(E, A, B, C, D, W[51]); - F3(D, E, A, B, C, W[52]); F3(C, D, E, A, B, W[53]); - F3(B, C, D, E, A, W[54]); F3(A, B, C, D, E, W[55]); - F3(E, A, B, C, D, W[56]); F3(D, E, A, B, C, W[57]); - F3(C, D, E, A, B, W[58]); F3(B, C, D, E, A, W[59]); - - F4(A, B, C, D, E, W[60]); F4(E, A, B, C, D, W[61]); - F4(D, E, A, B, C, W[62]); F4(C, D, E, A, B, W[63]); - F4(B, C, D, E, A, W[64]); F4(A, B, C, D, E, W[65]); - F4(E, A, B, C, D, W[66]); F4(D, E, A, B, C, W[67]); - F4(C, D, E, A, B, W[68]); F4(B, C, D, E, A, W[69]); - F4(A, B, C, D, E, W[70]); F4(E, A, B, C, D, W[71]); - F4(D, E, A, B, C, W[72]); F4(C, D, E, A, B, W[73]); - F4(B, C, D, E, A, W[74]); F4(A, B, C, D, E, W[75]); - F4(E, A, B, C, D, W[76]); F4(D, E, A, B, C, W[77]); - F4(C, D, E, A, B, W[78]); F4(B, C, D, E, A, W[79]); - - A = (digest[0] += A); - B = (digest[1] += B); - C = (digest[2] += C); - D = (digest[3] += D); - E = (digest[4] += E); - - input += hash_block_size(); - } - } - -/* -* Copy out the digest -*/ -void SHA_160::copy_out(byte output[]) - { - for(size_t i = 0; i != output_length(); i += 4) - store_be(digest[i/4], output + i); - } - -/* -* Clear memory of sensitive data -*/ -void SHA_160::clear() - { - MDx_HashFunction::clear(); - zeroise(W); - digest[0] = 0x67452301; - digest[1] = 0xEFCDAB89; - digest[2] = 0x98BADCFE; - digest[3] = 0x10325476; - digest[4] = 0xC3D2E1F0; - } - -} -/* -* SHA-{224,256} -* (C) 1999-2010 Jack Lloyd -* 2007 FlexSecure GmbH -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -namespace { - -namespace SHA2_32 { - -/* -* SHA-256 Rho Function -*/ -inline u32bit rho(u32bit X, u32bit rot1, u32bit rot2, u32bit rot3) - { - return (rotate_right(X, rot1) ^ rotate_right(X, rot2) ^ - rotate_right(X, rot3)); - } - -/* -* SHA-256 Sigma Function -*/ -inline u32bit sigma(u32bit X, u32bit rot1, u32bit rot2, u32bit shift) - { - return (rotate_right(X, rot1) ^ rotate_right(X, rot2) ^ (X >> shift)); - } - -/* -* SHA-256 F1 Function -* -* Use a macro as many compilers won't inline a function this big, -* even though it is much faster if inlined. -*/ -#define SHA2_32_F(A, B, C, D, E, F, G, H, M1, M2, M3, M4, magic) \ - do { \ - H += magic + rho(E, 6, 11, 25) + ((E & F) ^ (~E & G)) + M1; \ - D += H; \ - H += rho(A, 2, 13, 22) + ((A & B) | ((A | B) & C)); \ - M1 += sigma(M2, 17, 19, 10) + M3 + sigma(M4, 7, 18, 3); \ - } while(0); - -/* -* SHA-224 / SHA-256 compression function -*/ -void compress(MemoryRegion& digest, - const byte input[], size_t blocks) - { - u32bit A = digest[0], B = digest[1], C = digest[2], - D = digest[3], E = digest[4], F = digest[5], - G = digest[6], H = digest[7]; - - for(size_t i = 0; i != blocks; ++i) - { - u32bit W00 = load_be(input, 0); - u32bit W01 = load_be(input, 1); - u32bit W02 = load_be(input, 2); - u32bit W03 = load_be(input, 3); - u32bit W04 = load_be(input, 4); - u32bit W05 = load_be(input, 5); - u32bit W06 = load_be(input, 6); - u32bit W07 = load_be(input, 7); - u32bit W08 = load_be(input, 8); - u32bit W09 = load_be(input, 9); - u32bit W10 = load_be(input, 10); - u32bit W11 = load_be(input, 11); - u32bit W12 = load_be(input, 12); - u32bit W13 = load_be(input, 13); - u32bit W14 = load_be(input, 14); - u32bit W15 = load_be(input, 15); - - SHA2_32_F(A, B, C, D, E, F, G, H, W00, W14, W09, W01, 0x428A2F98); - SHA2_32_F(H, A, B, C, D, E, F, G, W01, W15, W10, W02, 0x71374491); - SHA2_32_F(G, H, A, B, C, D, E, F, W02, W00, W11, W03, 0xB5C0FBCF); - SHA2_32_F(F, G, H, A, B, C, D, E, W03, W01, W12, W04, 0xE9B5DBA5); - SHA2_32_F(E, F, G, H, A, B, C, D, W04, W02, W13, W05, 0x3956C25B); - SHA2_32_F(D, E, F, G, H, A, B, C, W05, W03, W14, W06, 0x59F111F1); - SHA2_32_F(C, D, E, F, G, H, A, B, W06, W04, W15, W07, 0x923F82A4); - SHA2_32_F(B, C, D, E, F, G, H, A, W07, W05, W00, W08, 0xAB1C5ED5); - SHA2_32_F(A, B, C, D, E, F, G, H, W08, W06, W01, W09, 0xD807AA98); - SHA2_32_F(H, A, B, C, D, E, F, G, W09, W07, W02, W10, 0x12835B01); - SHA2_32_F(G, H, A, B, C, D, E, F, W10, W08, W03, W11, 0x243185BE); - SHA2_32_F(F, G, H, A, B, C, D, E, W11, W09, W04, W12, 0x550C7DC3); - SHA2_32_F(E, F, G, H, A, B, C, D, W12, W10, W05, W13, 0x72BE5D74); - SHA2_32_F(D, E, F, G, H, A, B, C, W13, W11, W06, W14, 0x80DEB1FE); - SHA2_32_F(C, D, E, F, G, H, A, B, W14, W12, W07, W15, 0x9BDC06A7); - SHA2_32_F(B, C, D, E, F, G, H, A, W15, W13, W08, W00, 0xC19BF174); - SHA2_32_F(A, B, C, D, E, F, G, H, W00, W14, W09, W01, 0xE49B69C1); - SHA2_32_F(H, A, B, C, D, E, F, G, W01, W15, W10, W02, 0xEFBE4786); - SHA2_32_F(G, H, A, B, C, D, E, F, W02, W00, W11, W03, 0x0FC19DC6); - SHA2_32_F(F, G, H, A, B, C, D, E, W03, W01, W12, W04, 0x240CA1CC); - SHA2_32_F(E, F, G, H, A, B, C, D, W04, W02, W13, W05, 0x2DE92C6F); - SHA2_32_F(D, E, F, G, H, A, B, C, W05, W03, W14, W06, 0x4A7484AA); - SHA2_32_F(C, D, E, F, G, H, A, B, W06, W04, W15, W07, 0x5CB0A9DC); - SHA2_32_F(B, C, D, E, F, G, H, A, W07, W05, W00, W08, 0x76F988DA); - SHA2_32_F(A, B, C, D, E, F, G, H, W08, W06, W01, W09, 0x983E5152); - SHA2_32_F(H, A, B, C, D, E, F, G, W09, W07, W02, W10, 0xA831C66D); - SHA2_32_F(G, H, A, B, C, D, E, F, W10, W08, W03, W11, 0xB00327C8); - SHA2_32_F(F, G, H, A, B, C, D, E, W11, W09, W04, W12, 0xBF597FC7); - SHA2_32_F(E, F, G, H, A, B, C, D, W12, W10, W05, W13, 0xC6E00BF3); - SHA2_32_F(D, E, F, G, H, A, B, C, W13, W11, W06, W14, 0xD5A79147); - SHA2_32_F(C, D, E, F, G, H, A, B, W14, W12, W07, W15, 0x06CA6351); - SHA2_32_F(B, C, D, E, F, G, H, A, W15, W13, W08, W00, 0x14292967); - SHA2_32_F(A, B, C, D, E, F, G, H, W00, W14, W09, W01, 0x27B70A85); - SHA2_32_F(H, A, B, C, D, E, F, G, W01, W15, W10, W02, 0x2E1B2138); - SHA2_32_F(G, H, A, B, C, D, E, F, W02, W00, W11, W03, 0x4D2C6DFC); - SHA2_32_F(F, G, H, A, B, C, D, E, W03, W01, W12, W04, 0x53380D13); - SHA2_32_F(E, F, G, H, A, B, C, D, W04, W02, W13, W05, 0x650A7354); - SHA2_32_F(D, E, F, G, H, A, B, C, W05, W03, W14, W06, 0x766A0ABB); - SHA2_32_F(C, D, E, F, G, H, A, B, W06, W04, W15, W07, 0x81C2C92E); - SHA2_32_F(B, C, D, E, F, G, H, A, W07, W05, W00, W08, 0x92722C85); - SHA2_32_F(A, B, C, D, E, F, G, H, W08, W06, W01, W09, 0xA2BFE8A1); - SHA2_32_F(H, A, B, C, D, E, F, G, W09, W07, W02, W10, 0xA81A664B); - SHA2_32_F(G, H, A, B, C, D, E, F, W10, W08, W03, W11, 0xC24B8B70); - SHA2_32_F(F, G, H, A, B, C, D, E, W11, W09, W04, W12, 0xC76C51A3); - SHA2_32_F(E, F, G, H, A, B, C, D, W12, W10, W05, W13, 0xD192E819); - SHA2_32_F(D, E, F, G, H, A, B, C, W13, W11, W06, W14, 0xD6990624); - SHA2_32_F(C, D, E, F, G, H, A, B, W14, W12, W07, W15, 0xF40E3585); - SHA2_32_F(B, C, D, E, F, G, H, A, W15, W13, W08, W00, 0x106AA070); - SHA2_32_F(A, B, C, D, E, F, G, H, W00, W14, W09, W01, 0x19A4C116); - SHA2_32_F(H, A, B, C, D, E, F, G, W01, W15, W10, W02, 0x1E376C08); - SHA2_32_F(G, H, A, B, C, D, E, F, W02, W00, W11, W03, 0x2748774C); - SHA2_32_F(F, G, H, A, B, C, D, E, W03, W01, W12, W04, 0x34B0BCB5); - SHA2_32_F(E, F, G, H, A, B, C, D, W04, W02, W13, W05, 0x391C0CB3); - SHA2_32_F(D, E, F, G, H, A, B, C, W05, W03, W14, W06, 0x4ED8AA4A); - SHA2_32_F(C, D, E, F, G, H, A, B, W06, W04, W15, W07, 0x5B9CCA4F); - SHA2_32_F(B, C, D, E, F, G, H, A, W07, W05, W00, W08, 0x682E6FF3); - SHA2_32_F(A, B, C, D, E, F, G, H, W08, W06, W01, W09, 0x748F82EE); - SHA2_32_F(H, A, B, C, D, E, F, G, W09, W07, W02, W10, 0x78A5636F); - SHA2_32_F(G, H, A, B, C, D, E, F, W10, W08, W03, W11, 0x84C87814); - SHA2_32_F(F, G, H, A, B, C, D, E, W11, W09, W04, W12, 0x8CC70208); - SHA2_32_F(E, F, G, H, A, B, C, D, W12, W10, W05, W13, 0x90BEFFFA); - SHA2_32_F(D, E, F, G, H, A, B, C, W13, W11, W06, W14, 0xA4506CEB); - SHA2_32_F(C, D, E, F, G, H, A, B, W14, W12, W07, W15, 0xBEF9A3F7); - SHA2_32_F(B, C, D, E, F, G, H, A, W15, W13, W08, W00, 0xC67178F2); - - A = (digest[0] += A); - B = (digest[1] += B); - C = (digest[2] += C); - D = (digest[3] += D); - E = (digest[4] += E); - F = (digest[5] += F); - G = (digest[6] += G); - H = (digest[7] += H); - - input += 64; - } - } - -} - -} - -/* -* SHA-224 compression function -*/ -void SHA_224::compress_n(const byte input[], size_t blocks) - { - SHA2_32::compress(digest, input, blocks); - } - -/* -* Copy out the digest -*/ -void SHA_224::copy_out(byte output[]) - { - for(size_t i = 0; i != output_length(); i += 4) - store_be(digest[i/4], output + i); - } - -/* -* Clear memory of sensitive data -*/ -void SHA_224::clear() - { - MDx_HashFunction::clear(); - digest[0] = 0xC1059ED8; - digest[1] = 0x367CD507; - digest[2] = 0x3070DD17; - digest[3] = 0xF70E5939; - digest[4] = 0xFFC00B31; - digest[5] = 0x68581511; - digest[6] = 0x64F98FA7; - digest[7] = 0xBEFA4FA4; - } - -/* -* SHA-256 compression function -*/ -void SHA_256::compress_n(const byte input[], size_t blocks) - { - SHA2_32::compress(digest, input, blocks); - } - -/* -* Copy out the digest -*/ -void SHA_256::copy_out(byte output[]) - { - for(size_t i = 0; i != output_length(); i += 4) - store_be(digest[i/4], output + i); - } - -/* -* Clear memory of sensitive data -*/ -void SHA_256::clear() - { - MDx_HashFunction::clear(); - digest[0] = 0x6A09E667; - digest[1] = 0xBB67AE85; - digest[2] = 0x3C6EF372; - digest[3] = 0xA54FF53A; - digest[4] = 0x510E527F; - digest[5] = 0x9B05688C; - digest[6] = 0x1F83D9AB; - digest[7] = 0x5BE0CD19; - } - -} -/* -* SHA-{384,512} -* (C) 1999-2011 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -namespace { - -namespace SHA2_64 { - -/* -* SHA-{384,512} Rho Function -*/ -inline u64bit rho(u64bit X, u32bit rot1, u32bit rot2, u32bit rot3) - { - return (rotate_right(X, rot1) ^ rotate_right(X, rot2) ^ - rotate_right(X, rot3)); - } - -/* -* SHA-{384,512} Sigma Function -*/ -inline u64bit sigma(u64bit X, u32bit rot1, u32bit rot2, u32bit shift) - { - return (rotate_right(X, rot1) ^ rotate_right(X, rot2) ^ (X >> shift)); - } - -/* -* SHA-512 F1 Function -* -* Use a macro as many compilers won't inline a function this big, -* even though it is much faster if inlined. -*/ -#define SHA2_64_F(A, B, C, D, E, F, G, H, M1, M2, M3, M4, magic) \ - do { \ - H += magic + rho(E, 14, 18, 41) + ((E & F) ^ (~E & G)) + M1; \ - D += H; \ - H += rho(A, 28, 34, 39) + ((A & B) | ((A | B) & C)); \ - M1 += sigma(M2, 19, 61, 6) + M3 + sigma(M4, 1, 8, 7); \ - } while(0); - -/* -* SHA-{384,512} Compression Function -*/ -void compress(MemoryRegion& digest, - const byte input[], size_t blocks) - { - u64bit A = digest[0], B = digest[1], C = digest[2], - D = digest[3], E = digest[4], F = digest[5], - G = digest[6], H = digest[7]; - - for(size_t i = 0; i != blocks; ++i) - { - u64bit W00 = load_be(input, 0); - u64bit W01 = load_be(input, 1); - u64bit W02 = load_be(input, 2); - u64bit W03 = load_be(input, 3); - u64bit W04 = load_be(input, 4); - u64bit W05 = load_be(input, 5); - u64bit W06 = load_be(input, 6); - u64bit W07 = load_be(input, 7); - u64bit W08 = load_be(input, 8); - u64bit W09 = load_be(input, 9); - u64bit W10 = load_be(input, 10); - u64bit W11 = load_be(input, 11); - u64bit W12 = load_be(input, 12); - u64bit W13 = load_be(input, 13); - u64bit W14 = load_be(input, 14); - u64bit W15 = load_be(input, 15); - - SHA2_64_F(A, B, C, D, E, F, G, H, W00, W14, W09, W01, 0x428A2F98D728AE22ULL); - SHA2_64_F(H, A, B, C, D, E, F, G, W01, W15, W10, W02, 0x7137449123EF65CDULL); - SHA2_64_F(G, H, A, B, C, D, E, F, W02, W00, W11, W03, 0xB5C0FBCFEC4D3B2FULL); - SHA2_64_F(F, G, H, A, B, C, D, E, W03, W01, W12, W04, 0xE9B5DBA58189DBBCULL); - SHA2_64_F(E, F, G, H, A, B, C, D, W04, W02, W13, W05, 0x3956C25BF348B538ULL); - SHA2_64_F(D, E, F, G, H, A, B, C, W05, W03, W14, W06, 0x59F111F1B605D019ULL); - SHA2_64_F(C, D, E, F, G, H, A, B, W06, W04, W15, W07, 0x923F82A4AF194F9BULL); - SHA2_64_F(B, C, D, E, F, G, H, A, W07, W05, W00, W08, 0xAB1C5ED5DA6D8118ULL); - SHA2_64_F(A, B, C, D, E, F, G, H, W08, W06, W01, W09, 0xD807AA98A3030242ULL); - SHA2_64_F(H, A, B, C, D, E, F, G, W09, W07, W02, W10, 0x12835B0145706FBEULL); - SHA2_64_F(G, H, A, B, C, D, E, F, W10, W08, W03, W11, 0x243185BE4EE4B28CULL); - SHA2_64_F(F, G, H, A, B, C, D, E, W11, W09, W04, W12, 0x550C7DC3D5FFB4E2ULL); - SHA2_64_F(E, F, G, H, A, B, C, D, W12, W10, W05, W13, 0x72BE5D74F27B896FULL); - SHA2_64_F(D, E, F, G, H, A, B, C, W13, W11, W06, W14, 0x80DEB1FE3B1696B1ULL); - SHA2_64_F(C, D, E, F, G, H, A, B, W14, W12, W07, W15, 0x9BDC06A725C71235ULL); - SHA2_64_F(B, C, D, E, F, G, H, A, W15, W13, W08, W00, 0xC19BF174CF692694ULL); - SHA2_64_F(A, B, C, D, E, F, G, H, W00, W14, W09, W01, 0xE49B69C19EF14AD2ULL); - SHA2_64_F(H, A, B, C, D, E, F, G, W01, W15, W10, W02, 0xEFBE4786384F25E3ULL); - SHA2_64_F(G, H, A, B, C, D, E, F, W02, W00, W11, W03, 0x0FC19DC68B8CD5B5ULL); - SHA2_64_F(F, G, H, A, B, C, D, E, W03, W01, W12, W04, 0x240CA1CC77AC9C65ULL); - SHA2_64_F(E, F, G, H, A, B, C, D, W04, W02, W13, W05, 0x2DE92C6F592B0275ULL); - SHA2_64_F(D, E, F, G, H, A, B, C, W05, W03, W14, W06, 0x4A7484AA6EA6E483ULL); - SHA2_64_F(C, D, E, F, G, H, A, B, W06, W04, W15, W07, 0x5CB0A9DCBD41FBD4ULL); - SHA2_64_F(B, C, D, E, F, G, H, A, W07, W05, W00, W08, 0x76F988DA831153B5ULL); - SHA2_64_F(A, B, C, D, E, F, G, H, W08, W06, W01, W09, 0x983E5152EE66DFABULL); - SHA2_64_F(H, A, B, C, D, E, F, G, W09, W07, W02, W10, 0xA831C66D2DB43210ULL); - SHA2_64_F(G, H, A, B, C, D, E, F, W10, W08, W03, W11, 0xB00327C898FB213FULL); - SHA2_64_F(F, G, H, A, B, C, D, E, W11, W09, W04, W12, 0xBF597FC7BEEF0EE4ULL); - SHA2_64_F(E, F, G, H, A, B, C, D, W12, W10, W05, W13, 0xC6E00BF33DA88FC2ULL); - SHA2_64_F(D, E, F, G, H, A, B, C, W13, W11, W06, W14, 0xD5A79147930AA725ULL); - SHA2_64_F(C, D, E, F, G, H, A, B, W14, W12, W07, W15, 0x06CA6351E003826FULL); - SHA2_64_F(B, C, D, E, F, G, H, A, W15, W13, W08, W00, 0x142929670A0E6E70ULL); - SHA2_64_F(A, B, C, D, E, F, G, H, W00, W14, W09, W01, 0x27B70A8546D22FFCULL); - SHA2_64_F(H, A, B, C, D, E, F, G, W01, W15, W10, W02, 0x2E1B21385C26C926ULL); - SHA2_64_F(G, H, A, B, C, D, E, F, W02, W00, W11, W03, 0x4D2C6DFC5AC42AEDULL); - SHA2_64_F(F, G, H, A, B, C, D, E, W03, W01, W12, W04, 0x53380D139D95B3DFULL); - SHA2_64_F(E, F, G, H, A, B, C, D, W04, W02, W13, W05, 0x650A73548BAF63DEULL); - SHA2_64_F(D, E, F, G, H, A, B, C, W05, W03, W14, W06, 0x766A0ABB3C77B2A8ULL); - SHA2_64_F(C, D, E, F, G, H, A, B, W06, W04, W15, W07, 0x81C2C92E47EDAEE6ULL); - SHA2_64_F(B, C, D, E, F, G, H, A, W07, W05, W00, W08, 0x92722C851482353BULL); - SHA2_64_F(A, B, C, D, E, F, G, H, W08, W06, W01, W09, 0xA2BFE8A14CF10364ULL); - SHA2_64_F(H, A, B, C, D, E, F, G, W09, W07, W02, W10, 0xA81A664BBC423001ULL); - SHA2_64_F(G, H, A, B, C, D, E, F, W10, W08, W03, W11, 0xC24B8B70D0F89791ULL); - SHA2_64_F(F, G, H, A, B, C, D, E, W11, W09, W04, W12, 0xC76C51A30654BE30ULL); - SHA2_64_F(E, F, G, H, A, B, C, D, W12, W10, W05, W13, 0xD192E819D6EF5218ULL); - SHA2_64_F(D, E, F, G, H, A, B, C, W13, W11, W06, W14, 0xD69906245565A910ULL); - SHA2_64_F(C, D, E, F, G, H, A, B, W14, W12, W07, W15, 0xF40E35855771202AULL); - SHA2_64_F(B, C, D, E, F, G, H, A, W15, W13, W08, W00, 0x106AA07032BBD1B8ULL); - SHA2_64_F(A, B, C, D, E, F, G, H, W00, W14, W09, W01, 0x19A4C116B8D2D0C8ULL); - SHA2_64_F(H, A, B, C, D, E, F, G, W01, W15, W10, W02, 0x1E376C085141AB53ULL); - SHA2_64_F(G, H, A, B, C, D, E, F, W02, W00, W11, W03, 0x2748774CDF8EEB99ULL); - SHA2_64_F(F, G, H, A, B, C, D, E, W03, W01, W12, W04, 0x34B0BCB5E19B48A8ULL); - SHA2_64_F(E, F, G, H, A, B, C, D, W04, W02, W13, W05, 0x391C0CB3C5C95A63ULL); - SHA2_64_F(D, E, F, G, H, A, B, C, W05, W03, W14, W06, 0x4ED8AA4AE3418ACBULL); - SHA2_64_F(C, D, E, F, G, H, A, B, W06, W04, W15, W07, 0x5B9CCA4F7763E373ULL); - SHA2_64_F(B, C, D, E, F, G, H, A, W07, W05, W00, W08, 0x682E6FF3D6B2B8A3ULL); - SHA2_64_F(A, B, C, D, E, F, G, H, W08, W06, W01, W09, 0x748F82EE5DEFB2FCULL); - SHA2_64_F(H, A, B, C, D, E, F, G, W09, W07, W02, W10, 0x78A5636F43172F60ULL); - SHA2_64_F(G, H, A, B, C, D, E, F, W10, W08, W03, W11, 0x84C87814A1F0AB72ULL); - SHA2_64_F(F, G, H, A, B, C, D, E, W11, W09, W04, W12, 0x8CC702081A6439ECULL); - SHA2_64_F(E, F, G, H, A, B, C, D, W12, W10, W05, W13, 0x90BEFFFA23631E28ULL); - SHA2_64_F(D, E, F, G, H, A, B, C, W13, W11, W06, W14, 0xA4506CEBDE82BDE9ULL); - SHA2_64_F(C, D, E, F, G, H, A, B, W14, W12, W07, W15, 0xBEF9A3F7B2C67915ULL); - SHA2_64_F(B, C, D, E, F, G, H, A, W15, W13, W08, W00, 0xC67178F2E372532BULL); - SHA2_64_F(A, B, C, D, E, F, G, H, W00, W14, W09, W01, 0xCA273ECEEA26619CULL); - SHA2_64_F(H, A, B, C, D, E, F, G, W01, W15, W10, W02, 0xD186B8C721C0C207ULL); - SHA2_64_F(G, H, A, B, C, D, E, F, W02, W00, W11, W03, 0xEADA7DD6CDE0EB1EULL); - SHA2_64_F(F, G, H, A, B, C, D, E, W03, W01, W12, W04, 0xF57D4F7FEE6ED178ULL); - SHA2_64_F(E, F, G, H, A, B, C, D, W04, W02, W13, W05, 0x06F067AA72176FBAULL); - SHA2_64_F(D, E, F, G, H, A, B, C, W05, W03, W14, W06, 0x0A637DC5A2C898A6ULL); - SHA2_64_F(C, D, E, F, G, H, A, B, W06, W04, W15, W07, 0x113F9804BEF90DAEULL); - SHA2_64_F(B, C, D, E, F, G, H, A, W07, W05, W00, W08, 0x1B710B35131C471BULL); - SHA2_64_F(A, B, C, D, E, F, G, H, W08, W06, W01, W09, 0x28DB77F523047D84ULL); - SHA2_64_F(H, A, B, C, D, E, F, G, W09, W07, W02, W10, 0x32CAAB7B40C72493ULL); - SHA2_64_F(G, H, A, B, C, D, E, F, W10, W08, W03, W11, 0x3C9EBE0A15C9BEBCULL); - SHA2_64_F(F, G, H, A, B, C, D, E, W11, W09, W04, W12, 0x431D67C49C100D4CULL); - SHA2_64_F(E, F, G, H, A, B, C, D, W12, W10, W05, W13, 0x4CC5D4BECB3E42B6ULL); - SHA2_64_F(D, E, F, G, H, A, B, C, W13, W11, W06, W14, 0x597F299CFC657E2AULL); - SHA2_64_F(C, D, E, F, G, H, A, B, W14, W12, W07, W15, 0x5FCB6FAB3AD6FAECULL); - SHA2_64_F(B, C, D, E, F, G, H, A, W15, W13, W08, W00, 0x6C44198C4A475817ULL); - - A = (digest[0] += A); - B = (digest[1] += B); - C = (digest[2] += C); - D = (digest[3] += D); - E = (digest[4] += E); - F = (digest[5] += F); - G = (digest[6] += G); - H = (digest[7] += H); - - input += 128; - } - } - -} - -} - -/* -* SHA-384 compression function -*/ -void SHA_384::compress_n(const byte input[], size_t blocks) - { - SHA2_64::compress(digest, input, blocks); - } - -/* -* Copy out the digest -*/ -void SHA_384::copy_out(byte output[]) - { - for(size_t i = 0; i != output_length(); i += 8) - store_be(digest[i/8], output + i); - } - -/* -* Clear memory of sensitive data -*/ -void SHA_384::clear() - { - MDx_HashFunction::clear(); - digest[0] = 0xCBBB9D5DC1059ED8ULL; - digest[1] = 0x629A292A367CD507ULL; - digest[2] = 0x9159015A3070DD17ULL; - digest[3] = 0x152FECD8F70E5939ULL; - digest[4] = 0x67332667FFC00B31ULL; - digest[5] = 0x8EB44A8768581511ULL; - digest[6] = 0xDB0C2E0D64F98FA7ULL; - digest[7] = 0x47B5481DBEFA4FA4ULL; - } - -/* -* SHA-512 compression function -*/ -void SHA_512::compress_n(const byte input[], size_t blocks) - { - SHA2_64::compress(digest, input, blocks); - } - -/* -* Copy out the digest -*/ -void SHA_512::copy_out(byte output[]) - { - for(size_t i = 0; i != output_length(); i += 8) - store_be(digest[i/8], output + i); - } - -/* -* Clear memory of sensitive data -*/ -void SHA_512::clear() - { - MDx_HashFunction::clear(); - digest[0] = 0x6A09E667F3BCC908ULL; - digest[1] = 0xBB67AE8584CAA73BULL; - digest[2] = 0x3C6EF372FE94F82BULL; - digest[3] = 0xA54FF53A5F1D36F1ULL; - digest[4] = 0x510E527FADE682D1ULL; - digest[5] = 0x9B05688C2B3E6C1FULL; - digest[6] = 0x1F83D9ABFB41BD6BULL; - digest[7] = 0x5BE0CD19137E2179ULL; - } - -} -/* -* The Skein-512 hash function -* (C) 2009-2010 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include - -namespace Botan { - -namespace { - -enum type_code { - SKEIN_KEY = 0, - SKEIN_CONFIG = 4, - SKEIN_PERSONALIZATION = 8, - SKEIN_PUBLIC_KEY = 12, - SKEIN_KEY_IDENTIFIER = 16, - SKEIN_NONCE = 20, - SKEIN_MSG = 48, - SKEIN_OUTPUT = 63 -}; - -void ubi_512(MemoryRegion& H, - MemoryRegion& T, - const byte msg[], size_t msg_len) - { - do - { - const size_t to_proc = std::min(msg_len, 64); - T[0] += to_proc; - - u64bit M[8] = { 0 }; - - load_le(M, msg, to_proc / 8); - - if(to_proc % 8) - { - for(size_t j = 0; j != to_proc % 8; ++j) - M[to_proc/8] |= static_cast(msg[8*(to_proc/8)+j]) << (8*j); - } - - H[8] = H[0] ^ H[1] ^ H[2] ^ H[3] ^ - H[4] ^ H[5] ^ H[6] ^ H[7] ^ 0x1BD11BDAA9FC1A22ULL; - - T[2] = T[0] ^ T[1]; - - u64bit X0 = M[0] + H[0]; - u64bit X1 = M[1] + H[1]; - u64bit X2 = M[2] + H[2]; - u64bit X3 = M[3] + H[3]; - u64bit X4 = M[4] + H[4]; - u64bit X5 = M[5] + H[5] + T[0]; - u64bit X6 = M[6] + H[6] + T[1]; - u64bit X7 = M[7] + H[7]; - -#define THREEFISH_ROUND(I1,I2,I3,I4,I5,I6,I7,I8,ROT1,ROT2,ROT3,ROT4) \ - do { \ - X##I1 += X##I2; X##I2 = rotate_left(X##I2, ROT1) ^ X##I1; \ - X##I3 += X##I4; X##I4 = rotate_left(X##I4, ROT2) ^ X##I3; \ - X##I5 += X##I6; X##I6 = rotate_left(X##I6, ROT3) ^ X##I5; \ - X##I7 += X##I8; X##I8 = rotate_left(X##I8, ROT4) ^ X##I7; \ - } while(0); - -#define THREEFISH_INJECT_KEY(r) \ - do { \ - X0 += H[(r ) % 9]; \ - X1 += H[(r+1) % 9]; \ - X2 += H[(r+2) % 9]; \ - X3 += H[(r+3) % 9]; \ - X4 += H[(r+4) % 9]; \ - X5 += H[(r+5) % 9] + T[(r ) % 3]; \ - X6 += H[(r+6) % 9] + T[(r+1) % 3]; \ - X7 += H[(r+7) % 9] + (r); \ - } while(0); - -#define THREEFISH_8_ROUNDS(R1,R2) \ - do { \ - THREEFISH_ROUND(0,1,2,3,4,5,6,7, 46,36,19,37); \ - THREEFISH_ROUND(2,1,4,7,6,5,0,3, 33,27,14,42); \ - THREEFISH_ROUND(4,1,6,3,0,5,2,7, 17,49,36,39); \ - THREEFISH_ROUND(6,1,0,7,2,5,4,3, 44, 9,54,56); \ - \ - THREEFISH_INJECT_KEY(R1); \ - \ - THREEFISH_ROUND(0,1,2,3,4,5,6,7, 39,30,34,24); \ - THREEFISH_ROUND(2,1,4,7,6,5,0,3, 13,50,10,17); \ - THREEFISH_ROUND(4,1,6,3,0,5,2,7, 25,29,39,43); \ - THREEFISH_ROUND(6,1,0,7,2,5,4,3, 8,35,56,22); \ - \ - THREEFISH_INJECT_KEY(R2); \ - } while(0); - - THREEFISH_8_ROUNDS(1,2); - THREEFISH_8_ROUNDS(3,4); - THREEFISH_8_ROUNDS(5,6); - THREEFISH_8_ROUNDS(7,8); - THREEFISH_8_ROUNDS(9,10); - THREEFISH_8_ROUNDS(11,12); - THREEFISH_8_ROUNDS(13,14); - THREEFISH_8_ROUNDS(15,16); - THREEFISH_8_ROUNDS(17,18); - - // message feed forward - H[0] = X0 ^ M[0]; - H[1] = X1 ^ M[1]; - H[2] = X2 ^ M[2]; - H[3] = X3 ^ M[3]; - H[4] = X4 ^ M[4]; - H[5] = X5 ^ M[5]; - H[6] = X6 ^ M[6]; - H[7] = X7 ^ M[7]; - - // clear first flag if set - T[1] &= ~(static_cast(1) << 62); - - msg_len -= to_proc; - msg += to_proc; - } while(msg_len); - } - -void reset_tweak(MemoryRegion& T, - type_code type, bool final) - { - T[0] = 0; - - T[1] = (static_cast(type) << 56) | - (static_cast(1) << 62) | - (static_cast(final) << 63); - } - -void initial_block(MemoryRegion& H, - MemoryRegion& T, - size_t output_bits, - const std::string& personalization) - { - zeroise(H); - - // ASCII("SHA3") followed by version (0x0001) code - byte config_str[32] = { 0x53, 0x48, 0x41, 0x33, 0x01, 0x00, 0 }; - store_le(u32bit(output_bits), config_str + 8); - - reset_tweak(T, SKEIN_CONFIG, true); - ubi_512(H, T, config_str, sizeof(config_str)); - - if(personalization != "") - { - /* - This is a limitation of this implementation, and not of the - algorithm specification. Could be fixed relatively easily, but - doesn't seem worth the trouble. - */ - if(personalization.length() > 64) - throw Invalid_Argument("Skein personalization must be <= 64 bytes"); - - const byte* bits = reinterpret_cast(personalization.data()); - - reset_tweak(T, SKEIN_PERSONALIZATION, true); - ubi_512(H, T, bits, personalization.length()); - } - - reset_tweak(T, SKEIN_MSG, false); - } - -} - -Skein_512::Skein_512(size_t arg_output_bits, - const std::string& arg_personalization) : - personalization(arg_personalization), - output_bits(arg_output_bits), - H(9), T(3), buffer(64), buf_pos(0) - { - if(output_bits == 0 || output_bits % 8 != 0 || output_bits > 64*1024) - throw Invalid_Argument("Bad output bits size for Skein-512"); - - initial_block(H, T, output_bits, personalization); - } - -std::string Skein_512::name() const - { - if(personalization != "") - return "Skein-512(" + to_string(output_bits) + "," + personalization + ")"; - return "Skein-512(" + to_string(output_bits) + ")"; - } - -HashFunction* Skein_512::clone() const - { - return new Skein_512(output_bits, personalization); - } - -void Skein_512::clear() - { - zeroise(H); - zeroise(T); - zeroise(buffer); - buf_pos = 0; - } - -void Skein_512::add_data(const byte input[], size_t length) - { - if(length == 0) - return; - - if(buf_pos) - { - buffer.copy(buf_pos, input, length); - if(buf_pos + length > 64) - { - ubi_512(H, T, &buffer[0], buffer.size()); - - input += (64 - buf_pos); - length -= (64 - buf_pos); - buf_pos = 0; - } - } - - const size_t full_blocks = (length - 1) / 64; - - if(full_blocks) - ubi_512(H, T, input, 64*full_blocks); - - length -= full_blocks * 64; - - buffer.copy(buf_pos, input + full_blocks * 64, length); - buf_pos += length; - } - -void Skein_512::final_result(byte out[]) - { - T[1] |= (static_cast(1) << 63); // final block flag - - for(size_t i = buf_pos; i != buffer.size(); ++i) - buffer[i] = 0; - - ubi_512(H, T, &buffer[0], buf_pos); - - byte counter[8] = { 0 }; - - size_t out_bytes = output_bits / 8; - - SecureVector H_out(9); - - while(out_bytes) - { - const size_t to_proc = std::min(out_bytes, 64); - - H_out.copy(&H[0], 8); - - reset_tweak(T, SKEIN_OUTPUT, true); - ubi_512(H_out, T, counter, sizeof(counter)); - - for(size_t i = 0; i != to_proc; ++i) - out[i] = get_byte(7-i%8, H_out[i/8]); - - out_bytes -= to_proc; - out += to_proc; - - for(size_t i = 0; i != sizeof(counter); ++i) - if(++counter[i]) - break; - } - - buf_pos = 0; - initial_block(H, T, output_bits, personalization); - } - -} -/* -* S-Box Tables for Tiger -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -const u64bit Tiger::SBOX1[256] = { - 0x02AAB17CF7E90C5EULL, 0xAC424B03E243A8ECULL, 0x72CD5BE30DD5FCD3ULL, - 0x6D019B93F6F97F3AULL, 0xCD9978FFD21F9193ULL, 0x7573A1C9708029E2ULL, - 0xB164326B922A83C3ULL, 0x46883EEE04915870ULL, 0xEAACE3057103ECE6ULL, - 0xC54169B808A3535CULL, 0x4CE754918DDEC47CULL, 0x0AA2F4DFDC0DF40CULL, - 0x10B76F18A74DBEFAULL, 0xC6CCB6235AD1AB6AULL, 0x13726121572FE2FFULL, - 0x1A488C6F199D921EULL, 0x4BC9F9F4DA0007CAULL, 0x26F5E6F6E85241C7ULL, - 0x859079DBEA5947B6ULL, 0x4F1885C5C99E8C92ULL, 0xD78E761EA96F864BULL, - 0x8E36428C52B5C17DULL, 0x69CF6827373063C1ULL, 0xB607C93D9BB4C56EULL, - 0x7D820E760E76B5EAULL, 0x645C9CC6F07FDC42ULL, 0xBF38A078243342E0ULL, - 0x5F6B343C9D2E7D04ULL, 0xF2C28AEB600B0EC6ULL, 0x6C0ED85F7254BCACULL, - 0x71592281A4DB4FE5ULL, 0x1967FA69CE0FED9FULL, 0xFD5293F8B96545DBULL, - 0xC879E9D7F2A7600BULL, 0x860248920193194EULL, 0xA4F9533B2D9CC0B3ULL, - 0x9053836C15957613ULL, 0xDB6DCF8AFC357BF1ULL, 0x18BEEA7A7A370F57ULL, - 0x037117CA50B99066ULL, 0x6AB30A9774424A35ULL, 0xF4E92F02E325249BULL, - 0x7739DB07061CCAE1ULL, 0xD8F3B49CECA42A05ULL, 0xBD56BE3F51382F73ULL, - 0x45FAED5843B0BB28ULL, 0x1C813D5C11BF1F83ULL, 0x8AF0E4B6D75FA169ULL, - 0x33EE18A487AD9999ULL, 0x3C26E8EAB1C94410ULL, 0xB510102BC0A822F9ULL, - 0x141EEF310CE6123BULL, 0xFC65B90059DDB154ULL, 0xE0158640C5E0E607ULL, - 0x884E079826C3A3CFULL, 0x930D0D9523C535FDULL, 0x35638D754E9A2B00ULL, - 0x4085FCCF40469DD5ULL, 0xC4B17AD28BE23A4CULL, 0xCAB2F0FC6A3E6A2EULL, - 0x2860971A6B943FCDULL, 0x3DDE6EE212E30446ULL, 0x6222F32AE01765AEULL, - 0x5D550BB5478308FEULL, 0xA9EFA98DA0EDA22AULL, 0xC351A71686C40DA7ULL, - 0x1105586D9C867C84ULL, 0xDCFFEE85FDA22853ULL, 0xCCFBD0262C5EEF76ULL, - 0xBAF294CB8990D201ULL, 0xE69464F52AFAD975ULL, 0x94B013AFDF133E14ULL, - 0x06A7D1A32823C958ULL, 0x6F95FE5130F61119ULL, 0xD92AB34E462C06C0ULL, - 0xED7BDE33887C71D2ULL, 0x79746D6E6518393EULL, 0x5BA419385D713329ULL, - 0x7C1BA6B948A97564ULL, 0x31987C197BFDAC67ULL, 0xDE6C23C44B053D02ULL, - 0x581C49FED002D64DULL, 0xDD474D6338261571ULL, 0xAA4546C3E473D062ULL, - 0x928FCE349455F860ULL, 0x48161BBACAAB94D9ULL, 0x63912430770E6F68ULL, - 0x6EC8A5E602C6641CULL, 0x87282515337DDD2BULL, 0x2CDA6B42034B701BULL, - 0xB03D37C181CB096DULL, 0xE108438266C71C6FULL, 0x2B3180C7EB51B255ULL, - 0xDF92B82F96C08BBCULL, 0x5C68C8C0A632F3BAULL, 0x5504CC861C3D0556ULL, - 0xABBFA4E55FB26B8FULL, 0x41848B0AB3BACEB4ULL, 0xB334A273AA445D32ULL, - 0xBCA696F0A85AD881ULL, 0x24F6EC65B528D56CULL, 0x0CE1512E90F4524AULL, - 0x4E9DD79D5506D35AULL, 0x258905FAC6CE9779ULL, 0x2019295B3E109B33ULL, - 0xF8A9478B73A054CCULL, 0x2924F2F934417EB0ULL, 0x3993357D536D1BC4ULL, - 0x38A81AC21DB6FF8BULL, 0x47C4FBF17D6016BFULL, 0x1E0FAADD7667E3F5ULL, - 0x7ABCFF62938BEB96ULL, 0xA78DAD948FC179C9ULL, 0x8F1F98B72911E50DULL, - 0x61E48EAE27121A91ULL, 0x4D62F7AD31859808ULL, 0xECEBA345EF5CEAEBULL, - 0xF5CEB25EBC9684CEULL, 0xF633E20CB7F76221ULL, 0xA32CDF06AB8293E4ULL, - 0x985A202CA5EE2CA4ULL, 0xCF0B8447CC8A8FB1ULL, 0x9F765244979859A3ULL, - 0xA8D516B1A1240017ULL, 0x0BD7BA3EBB5DC726ULL, 0xE54BCA55B86ADB39ULL, - 0x1D7A3AFD6C478063ULL, 0x519EC608E7669EDDULL, 0x0E5715A2D149AA23ULL, - 0x177D4571848FF194ULL, 0xEEB55F3241014C22ULL, 0x0F5E5CA13A6E2EC2ULL, - 0x8029927B75F5C361ULL, 0xAD139FABC3D6E436ULL, 0x0D5DF1A94CCF402FULL, - 0x3E8BD948BEA5DFC8ULL, 0xA5A0D357BD3FF77EULL, 0xA2D12E251F74F645ULL, - 0x66FD9E525E81A082ULL, 0x2E0C90CE7F687A49ULL, 0xC2E8BCBEBA973BC5ULL, - 0x000001BCE509745FULL, 0x423777BBE6DAB3D6ULL, 0xD1661C7EAEF06EB5ULL, - 0xA1781F354DAACFD8ULL, 0x2D11284A2B16AFFCULL, 0xF1FC4F67FA891D1FULL, - 0x73ECC25DCB920ADAULL, 0xAE610C22C2A12651ULL, 0x96E0A810D356B78AULL, - 0x5A9A381F2FE7870FULL, 0xD5AD62EDE94E5530ULL, 0xD225E5E8368D1427ULL, - 0x65977B70C7AF4631ULL, 0x99F889B2DE39D74FULL, 0x233F30BF54E1D143ULL, - 0x9A9675D3D9A63C97ULL, 0x5470554FF334F9A8ULL, 0x166ACB744A4F5688ULL, - 0x70C74CAAB2E4AEADULL, 0xF0D091646F294D12ULL, 0x57B82A89684031D1ULL, - 0xEFD95A5A61BE0B6BULL, 0x2FBD12E969F2F29AULL, 0x9BD37013FEFF9FE8ULL, - 0x3F9B0404D6085A06ULL, 0x4940C1F3166CFE15ULL, 0x09542C4DCDF3DEFBULL, - 0xB4C5218385CD5CE3ULL, 0xC935B7DC4462A641ULL, 0x3417F8A68ED3B63FULL, - 0xB80959295B215B40ULL, 0xF99CDAEF3B8C8572ULL, 0x018C0614F8FCB95DULL, - 0x1B14ACCD1A3ACDF3ULL, 0x84D471F200BB732DULL, 0xC1A3110E95E8DA16ULL, - 0x430A7220BF1A82B8ULL, 0xB77E090D39DF210EULL, 0x5EF4BD9F3CD05E9DULL, - 0x9D4FF6DA7E57A444ULL, 0xDA1D60E183D4A5F8ULL, 0xB287C38417998E47ULL, - 0xFE3EDC121BB31886ULL, 0xC7FE3CCC980CCBEFULL, 0xE46FB590189BFD03ULL, - 0x3732FD469A4C57DCULL, 0x7EF700A07CF1AD65ULL, 0x59C64468A31D8859ULL, - 0x762FB0B4D45B61F6ULL, 0x155BAED099047718ULL, 0x68755E4C3D50BAA6ULL, - 0xE9214E7F22D8B4DFULL, 0x2ADDBF532EAC95F4ULL, 0x32AE3909B4BD0109ULL, - 0x834DF537B08E3450ULL, 0xFA209DA84220728DULL, 0x9E691D9B9EFE23F7ULL, - 0x0446D288C4AE8D7FULL, 0x7B4CC524E169785BULL, 0x21D87F0135CA1385ULL, - 0xCEBB400F137B8AA5ULL, 0x272E2B66580796BEULL, 0x3612264125C2B0DEULL, - 0x057702BDAD1EFBB2ULL, 0xD4BABB8EACF84BE9ULL, 0x91583139641BC67BULL, - 0x8BDC2DE08036E024ULL, 0x603C8156F49F68EDULL, 0xF7D236F7DBEF5111ULL, - 0x9727C4598AD21E80ULL, 0xA08A0896670A5FD7ULL, 0xCB4A8F4309EBA9CBULL, - 0x81AF564B0F7036A1ULL, 0xC0B99AA778199ABDULL, 0x959F1EC83FC8E952ULL, - 0x8C505077794A81B9ULL, 0x3ACAAF8F056338F0ULL, 0x07B43F50627A6778ULL, - 0x4A44AB49F5ECCC77ULL, 0x3BC3D6E4B679EE98ULL, 0x9CC0D4D1CF14108CULL, - 0x4406C00B206BC8A0ULL, 0x82A18854C8D72D89ULL, 0x67E366B35C3C432CULL, - 0xB923DD61102B37F2ULL, 0x56AB2779D884271DULL, 0xBE83E1B0FF1525AFULL, - 0xFB7C65D4217E49A9ULL, 0x6BDBE0E76D48E7D4ULL, 0x08DF828745D9179EULL, - 0x22EA6A9ADD53BD34ULL, 0xE36E141C5622200AULL, 0x7F805D1B8CB750EEULL, - 0xAFE5C7A59F58E837ULL, 0xE27F996A4FB1C23CULL, 0xD3867DFB0775F0D0ULL, - 0xD0E673DE6E88891AULL, 0x123AEB9EAFB86C25ULL, 0x30F1D5D5C145B895ULL, - 0xBB434A2DEE7269E7ULL, 0x78CB67ECF931FA38ULL, 0xF33B0372323BBF9CULL, - 0x52D66336FB279C74ULL, 0x505F33AC0AFB4EAAULL, 0xE8A5CD99A2CCE187ULL, - 0x534974801E2D30BBULL, 0x8D2D5711D5876D90ULL, 0x1F1A412891BC038EULL, - 0xD6E2E71D82E56648ULL, 0x74036C3A497732B7ULL, 0x89B67ED96361F5ABULL, - 0xFFED95D8F1EA02A2ULL, 0xE72B3BD61464D43DULL, 0xA6300F170BDC4820ULL, - 0xEBC18760ED78A77AULL }; - -const u64bit Tiger::SBOX2[256] = { - 0xE6A6BE5A05A12138ULL, 0xB5A122A5B4F87C98ULL, 0x563C6089140B6990ULL, - 0x4C46CB2E391F5DD5ULL, 0xD932ADDBC9B79434ULL, 0x08EA70E42015AFF5ULL, - 0xD765A6673E478CF1ULL, 0xC4FB757EAB278D99ULL, 0xDF11C6862D6E0692ULL, - 0xDDEB84F10D7F3B16ULL, 0x6F2EF604A665EA04ULL, 0x4A8E0F0FF0E0DFB3ULL, - 0xA5EDEEF83DBCBA51ULL, 0xFC4F0A2A0EA4371EULL, 0xE83E1DA85CB38429ULL, - 0xDC8FF882BA1B1CE2ULL, 0xCD45505E8353E80DULL, 0x18D19A00D4DB0717ULL, - 0x34A0CFEDA5F38101ULL, 0x0BE77E518887CAF2ULL, 0x1E341438B3C45136ULL, - 0xE05797F49089CCF9ULL, 0xFFD23F9DF2591D14ULL, 0x543DDA228595C5CDULL, - 0x661F81FD99052A33ULL, 0x8736E641DB0F7B76ULL, 0x15227725418E5307ULL, - 0xE25F7F46162EB2FAULL, 0x48A8B2126C13D9FEULL, 0xAFDC541792E76EEAULL, - 0x03D912BFC6D1898FULL, 0x31B1AAFA1B83F51BULL, 0xF1AC2796E42AB7D9ULL, - 0x40A3A7D7FCD2EBACULL, 0x1056136D0AFBBCC5ULL, 0x7889E1DD9A6D0C85ULL, - 0xD33525782A7974AAULL, 0xA7E25D09078AC09BULL, 0xBD4138B3EAC6EDD0ULL, - 0x920ABFBE71EB9E70ULL, 0xA2A5D0F54FC2625CULL, 0xC054E36B0B1290A3ULL, - 0xF6DD59FF62FE932BULL, 0x3537354511A8AC7DULL, 0xCA845E9172FADCD4ULL, - 0x84F82B60329D20DCULL, 0x79C62CE1CD672F18ULL, 0x8B09A2ADD124642CULL, - 0xD0C1E96A19D9E726ULL, 0x5A786A9B4BA9500CULL, 0x0E020336634C43F3ULL, - 0xC17B474AEB66D822ULL, 0x6A731AE3EC9BAAC2ULL, 0x8226667AE0840258ULL, - 0x67D4567691CAECA5ULL, 0x1D94155C4875ADB5ULL, 0x6D00FD985B813FDFULL, - 0x51286EFCB774CD06ULL, 0x5E8834471FA744AFULL, 0xF72CA0AEE761AE2EULL, - 0xBE40E4CDAEE8E09AULL, 0xE9970BBB5118F665ULL, 0x726E4BEB33DF1964ULL, - 0x703B000729199762ULL, 0x4631D816F5EF30A7ULL, 0xB880B5B51504A6BEULL, - 0x641793C37ED84B6CULL, 0x7B21ED77F6E97D96ULL, 0x776306312EF96B73ULL, - 0xAE528948E86FF3F4ULL, 0x53DBD7F286A3F8F8ULL, 0x16CADCE74CFC1063ULL, - 0x005C19BDFA52C6DDULL, 0x68868F5D64D46AD3ULL, 0x3A9D512CCF1E186AULL, - 0x367E62C2385660AEULL, 0xE359E7EA77DCB1D7ULL, 0x526C0773749ABE6EULL, - 0x735AE5F9D09F734BULL, 0x493FC7CC8A558BA8ULL, 0xB0B9C1533041AB45ULL, - 0x321958BA470A59BDULL, 0x852DB00B5F46C393ULL, 0x91209B2BD336B0E5ULL, - 0x6E604F7D659EF19FULL, 0xB99A8AE2782CCB24ULL, 0xCCF52AB6C814C4C7ULL, - 0x4727D9AFBE11727BULL, 0x7E950D0C0121B34DULL, 0x756F435670AD471FULL, - 0xF5ADD442615A6849ULL, 0x4E87E09980B9957AULL, 0x2ACFA1DF50AEE355ULL, - 0xD898263AFD2FD556ULL, 0xC8F4924DD80C8FD6ULL, 0xCF99CA3D754A173AULL, - 0xFE477BACAF91BF3CULL, 0xED5371F6D690C12DULL, 0x831A5C285E687094ULL, - 0xC5D3C90A3708A0A4ULL, 0x0F7F903717D06580ULL, 0x19F9BB13B8FDF27FULL, - 0xB1BD6F1B4D502843ULL, 0x1C761BA38FFF4012ULL, 0x0D1530C4E2E21F3BULL, - 0x8943CE69A7372C8AULL, 0xE5184E11FEB5CE66ULL, 0x618BDB80BD736621ULL, - 0x7D29BAD68B574D0BULL, 0x81BB613E25E6FE5BULL, 0x071C9C10BC07913FULL, - 0xC7BEEB7909AC2D97ULL, 0xC3E58D353BC5D757ULL, 0xEB017892F38F61E8ULL, - 0xD4EFFB9C9B1CC21AULL, 0x99727D26F494F7ABULL, 0xA3E063A2956B3E03ULL, - 0x9D4A8B9A4AA09C30ULL, 0x3F6AB7D500090FB4ULL, 0x9CC0F2A057268AC0ULL, - 0x3DEE9D2DEDBF42D1ULL, 0x330F49C87960A972ULL, 0xC6B2720287421B41ULL, - 0x0AC59EC07C00369CULL, 0xEF4EAC49CB353425ULL, 0xF450244EEF0129D8ULL, - 0x8ACC46E5CAF4DEB6ULL, 0x2FFEAB63989263F7ULL, 0x8F7CB9FE5D7A4578ULL, - 0x5BD8F7644E634635ULL, 0x427A7315BF2DC900ULL, 0x17D0C4AA2125261CULL, - 0x3992486C93518E50ULL, 0xB4CBFEE0A2D7D4C3ULL, 0x7C75D6202C5DDD8DULL, - 0xDBC295D8E35B6C61ULL, 0x60B369D302032B19ULL, 0xCE42685FDCE44132ULL, - 0x06F3DDB9DDF65610ULL, 0x8EA4D21DB5E148F0ULL, 0x20B0FCE62FCD496FULL, - 0x2C1B912358B0EE31ULL, 0xB28317B818F5A308ULL, 0xA89C1E189CA6D2CFULL, - 0x0C6B18576AAADBC8ULL, 0xB65DEAA91299FAE3ULL, 0xFB2B794B7F1027E7ULL, - 0x04E4317F443B5BEBULL, 0x4B852D325939D0A6ULL, 0xD5AE6BEEFB207FFCULL, - 0x309682B281C7D374ULL, 0xBAE309A194C3B475ULL, 0x8CC3F97B13B49F05ULL, - 0x98A9422FF8293967ULL, 0x244B16B01076FF7CULL, 0xF8BF571C663D67EEULL, - 0x1F0D6758EEE30DA1ULL, 0xC9B611D97ADEB9B7ULL, 0xB7AFD5887B6C57A2ULL, - 0x6290AE846B984FE1ULL, 0x94DF4CDEACC1A5FDULL, 0x058A5BD1C5483AFFULL, - 0x63166CC142BA3C37ULL, 0x8DB8526EB2F76F40ULL, 0xE10880036F0D6D4EULL, - 0x9E0523C9971D311DULL, 0x45EC2824CC7CD691ULL, 0x575B8359E62382C9ULL, - 0xFA9E400DC4889995ULL, 0xD1823ECB45721568ULL, 0xDAFD983B8206082FULL, - 0xAA7D29082386A8CBULL, 0x269FCD4403B87588ULL, 0x1B91F5F728BDD1E0ULL, - 0xE4669F39040201F6ULL, 0x7A1D7C218CF04ADEULL, 0x65623C29D79CE5CEULL, - 0x2368449096C00BB1ULL, 0xAB9BF1879DA503BAULL, 0xBC23ECB1A458058EULL, - 0x9A58DF01BB401ECCULL, 0xA070E868A85F143DULL, 0x4FF188307DF2239EULL, - 0x14D565B41A641183ULL, 0xEE13337452701602ULL, 0x950E3DCF3F285E09ULL, - 0x59930254B9C80953ULL, 0x3BF299408930DA6DULL, 0xA955943F53691387ULL, - 0xA15EDECAA9CB8784ULL, 0x29142127352BE9A0ULL, 0x76F0371FFF4E7AFBULL, - 0x0239F450274F2228ULL, 0xBB073AF01D5E868BULL, 0xBFC80571C10E96C1ULL, - 0xD267088568222E23ULL, 0x9671A3D48E80B5B0ULL, 0x55B5D38AE193BB81ULL, - 0x693AE2D0A18B04B8ULL, 0x5C48B4ECADD5335FULL, 0xFD743B194916A1CAULL, - 0x2577018134BE98C4ULL, 0xE77987E83C54A4ADULL, 0x28E11014DA33E1B9ULL, - 0x270CC59E226AA213ULL, 0x71495F756D1A5F60ULL, 0x9BE853FB60AFEF77ULL, - 0xADC786A7F7443DBFULL, 0x0904456173B29A82ULL, 0x58BC7A66C232BD5EULL, - 0xF306558C673AC8B2ULL, 0x41F639C6B6C9772AULL, 0x216DEFE99FDA35DAULL, - 0x11640CC71C7BE615ULL, 0x93C43694565C5527ULL, 0xEA038E6246777839ULL, - 0xF9ABF3CE5A3E2469ULL, 0x741E768D0FD312D2ULL, 0x0144B883CED652C6ULL, - 0xC20B5A5BA33F8552ULL, 0x1AE69633C3435A9DULL, 0x97A28CA4088CFDECULL, - 0x8824A43C1E96F420ULL, 0x37612FA66EEEA746ULL, 0x6B4CB165F9CF0E5AULL, - 0x43AA1C06A0ABFB4AULL, 0x7F4DC26FF162796BULL, 0x6CBACC8E54ED9B0FULL, - 0xA6B7FFEFD2BB253EULL, 0x2E25BC95B0A29D4FULL, 0x86D6A58BDEF1388CULL, - 0xDED74AC576B6F054ULL, 0x8030BDBC2B45805DULL, 0x3C81AF70E94D9289ULL, - 0x3EFF6DDA9E3100DBULL, 0xB38DC39FDFCC8847ULL, 0x123885528D17B87EULL, - 0xF2DA0ED240B1B642ULL, 0x44CEFADCD54BF9A9ULL, 0x1312200E433C7EE6ULL, - 0x9FFCC84F3A78C748ULL, 0xF0CD1F72248576BBULL, 0xEC6974053638CFE4ULL, - 0x2BA7B67C0CEC4E4CULL, 0xAC2F4DF3E5CE32EDULL, 0xCB33D14326EA4C11ULL, - 0xA4E9044CC77E58BCULL, 0x5F513293D934FCEFULL, 0x5DC9645506E55444ULL, - 0x50DE418F317DE40AULL, 0x388CB31A69DDE259ULL, 0x2DB4A83455820A86ULL, - 0x9010A91E84711AE9ULL, 0x4DF7F0B7B1498371ULL, 0xD62A2EABC0977179ULL, - 0x22FAC097AA8D5C0EULL }; - -const u64bit Tiger::SBOX3[256] = { - 0xF49FCC2FF1DAF39BULL, 0x487FD5C66FF29281ULL, 0xE8A30667FCDCA83FULL, - 0x2C9B4BE3D2FCCE63ULL, 0xDA3FF74B93FBBBC2ULL, 0x2FA165D2FE70BA66ULL, - 0xA103E279970E93D4ULL, 0xBECDEC77B0E45E71ULL, 0xCFB41E723985E497ULL, - 0xB70AAA025EF75017ULL, 0xD42309F03840B8E0ULL, 0x8EFC1AD035898579ULL, - 0x96C6920BE2B2ABC5ULL, 0x66AF4163375A9172ULL, 0x2174ABDCCA7127FBULL, - 0xB33CCEA64A72FF41ULL, 0xF04A4933083066A5ULL, 0x8D970ACDD7289AF5ULL, - 0x8F96E8E031C8C25EULL, 0xF3FEC02276875D47ULL, 0xEC7BF310056190DDULL, - 0xF5ADB0AEBB0F1491ULL, 0x9B50F8850FD58892ULL, 0x4975488358B74DE8ULL, - 0xA3354FF691531C61ULL, 0x0702BBE481D2C6EEULL, 0x89FB24057DEDED98ULL, - 0xAC3075138596E902ULL, 0x1D2D3580172772EDULL, 0xEB738FC28E6BC30DULL, - 0x5854EF8F63044326ULL, 0x9E5C52325ADD3BBEULL, 0x90AA53CF325C4623ULL, - 0xC1D24D51349DD067ULL, 0x2051CFEEA69EA624ULL, 0x13220F0A862E7E4FULL, - 0xCE39399404E04864ULL, 0xD9C42CA47086FCB7ULL, 0x685AD2238A03E7CCULL, - 0x066484B2AB2FF1DBULL, 0xFE9D5D70EFBF79ECULL, 0x5B13B9DD9C481854ULL, - 0x15F0D475ED1509ADULL, 0x0BEBCD060EC79851ULL, 0xD58C6791183AB7F8ULL, - 0xD1187C5052F3EEE4ULL, 0xC95D1192E54E82FFULL, 0x86EEA14CB9AC6CA2ULL, - 0x3485BEB153677D5DULL, 0xDD191D781F8C492AULL, 0xF60866BAA784EBF9ULL, - 0x518F643BA2D08C74ULL, 0x8852E956E1087C22ULL, 0xA768CB8DC410AE8DULL, - 0x38047726BFEC8E1AULL, 0xA67738B4CD3B45AAULL, 0xAD16691CEC0DDE19ULL, - 0xC6D4319380462E07ULL, 0xC5A5876D0BA61938ULL, 0x16B9FA1FA58FD840ULL, - 0x188AB1173CA74F18ULL, 0xABDA2F98C99C021FULL, 0x3E0580AB134AE816ULL, - 0x5F3B05B773645ABBULL, 0x2501A2BE5575F2F6ULL, 0x1B2F74004E7E8BA9ULL, - 0x1CD7580371E8D953ULL, 0x7F6ED89562764E30ULL, 0xB15926FF596F003DULL, - 0x9F65293DA8C5D6B9ULL, 0x6ECEF04DD690F84CULL, 0x4782275FFF33AF88ULL, - 0xE41433083F820801ULL, 0xFD0DFE409A1AF9B5ULL, 0x4325A3342CDB396BULL, - 0x8AE77E62B301B252ULL, 0xC36F9E9F6655615AULL, 0x85455A2D92D32C09ULL, - 0xF2C7DEA949477485ULL, 0x63CFB4C133A39EBAULL, 0x83B040CC6EBC5462ULL, - 0x3B9454C8FDB326B0ULL, 0x56F56A9E87FFD78CULL, 0x2DC2940D99F42BC6ULL, - 0x98F7DF096B096E2DULL, 0x19A6E01E3AD852BFULL, 0x42A99CCBDBD4B40BULL, - 0xA59998AF45E9C559ULL, 0x366295E807D93186ULL, 0x6B48181BFAA1F773ULL, - 0x1FEC57E2157A0A1DULL, 0x4667446AF6201AD5ULL, 0xE615EBCACFB0F075ULL, - 0xB8F31F4F68290778ULL, 0x22713ED6CE22D11EULL, 0x3057C1A72EC3C93BULL, - 0xCB46ACC37C3F1F2FULL, 0xDBB893FD02AAF50EULL, 0x331FD92E600B9FCFULL, - 0xA498F96148EA3AD6ULL, 0xA8D8426E8B6A83EAULL, 0xA089B274B7735CDCULL, - 0x87F6B3731E524A11ULL, 0x118808E5CBC96749ULL, 0x9906E4C7B19BD394ULL, - 0xAFED7F7E9B24A20CULL, 0x6509EADEEB3644A7ULL, 0x6C1EF1D3E8EF0EDEULL, - 0xB9C97D43E9798FB4ULL, 0xA2F2D784740C28A3ULL, 0x7B8496476197566FULL, - 0x7A5BE3E6B65F069DULL, 0xF96330ED78BE6F10ULL, 0xEEE60DE77A076A15ULL, - 0x2B4BEE4AA08B9BD0ULL, 0x6A56A63EC7B8894EULL, 0x02121359BA34FEF4ULL, - 0x4CBF99F8283703FCULL, 0x398071350CAF30C8ULL, 0xD0A77A89F017687AULL, - 0xF1C1A9EB9E423569ULL, 0x8C7976282DEE8199ULL, 0x5D1737A5DD1F7ABDULL, - 0x4F53433C09A9FA80ULL, 0xFA8B0C53DF7CA1D9ULL, 0x3FD9DCBC886CCB77ULL, - 0xC040917CA91B4720ULL, 0x7DD00142F9D1DCDFULL, 0x8476FC1D4F387B58ULL, - 0x23F8E7C5F3316503ULL, 0x032A2244E7E37339ULL, 0x5C87A5D750F5A74BULL, - 0x082B4CC43698992EULL, 0xDF917BECB858F63CULL, 0x3270B8FC5BF86DDAULL, - 0x10AE72BB29B5DD76ULL, 0x576AC94E7700362BULL, 0x1AD112DAC61EFB8FULL, - 0x691BC30EC5FAA427ULL, 0xFF246311CC327143ULL, 0x3142368E30E53206ULL, - 0x71380E31E02CA396ULL, 0x958D5C960AAD76F1ULL, 0xF8D6F430C16DA536ULL, - 0xC8FFD13F1BE7E1D2ULL, 0x7578AE66004DDBE1ULL, 0x05833F01067BE646ULL, - 0xBB34B5AD3BFE586DULL, 0x095F34C9A12B97F0ULL, 0x247AB64525D60CA8ULL, - 0xDCDBC6F3017477D1ULL, 0x4A2E14D4DECAD24DULL, 0xBDB5E6D9BE0A1EEBULL, - 0x2A7E70F7794301ABULL, 0xDEF42D8A270540FDULL, 0x01078EC0A34C22C1ULL, - 0xE5DE511AF4C16387ULL, 0x7EBB3A52BD9A330AULL, 0x77697857AA7D6435ULL, - 0x004E831603AE4C32ULL, 0xE7A21020AD78E312ULL, 0x9D41A70C6AB420F2ULL, - 0x28E06C18EA1141E6ULL, 0xD2B28CBD984F6B28ULL, 0x26B75F6C446E9D83ULL, - 0xBA47568C4D418D7FULL, 0xD80BADBFE6183D8EULL, 0x0E206D7F5F166044ULL, - 0xE258A43911CBCA3EULL, 0x723A1746B21DC0BCULL, 0xC7CAA854F5D7CDD3ULL, - 0x7CAC32883D261D9CULL, 0x7690C26423BA942CULL, 0x17E55524478042B8ULL, - 0xE0BE477656A2389FULL, 0x4D289B5E67AB2DA0ULL, 0x44862B9C8FBBFD31ULL, - 0xB47CC8049D141365ULL, 0x822C1B362B91C793ULL, 0x4EB14655FB13DFD8ULL, - 0x1ECBBA0714E2A97BULL, 0x6143459D5CDE5F14ULL, 0x53A8FBF1D5F0AC89ULL, - 0x97EA04D81C5E5B00ULL, 0x622181A8D4FDB3F3ULL, 0xE9BCD341572A1208ULL, - 0x1411258643CCE58AULL, 0x9144C5FEA4C6E0A4ULL, 0x0D33D06565CF620FULL, - 0x54A48D489F219CA1ULL, 0xC43E5EAC6D63C821ULL, 0xA9728B3A72770DAFULL, - 0xD7934E7B20DF87EFULL, 0xE35503B61A3E86E5ULL, 0xCAE321FBC819D504ULL, - 0x129A50B3AC60BFA6ULL, 0xCD5E68EA7E9FB6C3ULL, 0xB01C90199483B1C7ULL, - 0x3DE93CD5C295376CULL, 0xAED52EDF2AB9AD13ULL, 0x2E60F512C0A07884ULL, - 0xBC3D86A3E36210C9ULL, 0x35269D9B163951CEULL, 0x0C7D6E2AD0CDB5FAULL, - 0x59E86297D87F5733ULL, 0x298EF221898DB0E7ULL, 0x55000029D1A5AA7EULL, - 0x8BC08AE1B5061B45ULL, 0xC2C31C2B6C92703AULL, 0x94CC596BAF25EF42ULL, - 0x0A1D73DB22540456ULL, 0x04B6A0F9D9C4179AULL, 0xEFFDAFA2AE3D3C60ULL, - 0xF7C8075BB49496C4ULL, 0x9CC5C7141D1CD4E3ULL, 0x78BD1638218E5534ULL, - 0xB2F11568F850246AULL, 0xEDFABCFA9502BC29ULL, 0x796CE5F2DA23051BULL, - 0xAAE128B0DC93537CULL, 0x3A493DA0EE4B29AEULL, 0xB5DF6B2C416895D7ULL, - 0xFCABBD25122D7F37ULL, 0x70810B58105DC4B1ULL, 0xE10FDD37F7882A90ULL, - 0x524DCAB5518A3F5CULL, 0x3C9E85878451255BULL, 0x4029828119BD34E2ULL, - 0x74A05B6F5D3CECCBULL, 0xB610021542E13ECAULL, 0x0FF979D12F59E2ACULL, - 0x6037DA27E4F9CC50ULL, 0x5E92975A0DF1847DULL, 0xD66DE190D3E623FEULL, - 0x5032D6B87B568048ULL, 0x9A36B7CE8235216EULL, 0x80272A7A24F64B4AULL, - 0x93EFED8B8C6916F7ULL, 0x37DDBFF44CCE1555ULL, 0x4B95DB5D4B99BD25ULL, - 0x92D3FDA169812FC0ULL, 0xFB1A4A9A90660BB6ULL, 0x730C196946A4B9B2ULL, - 0x81E289AA7F49DA68ULL, 0x64669A0F83B1A05FULL, 0x27B3FF7D9644F48BULL, - 0xCC6B615C8DB675B3ULL, 0x674F20B9BCEBBE95ULL, 0x6F31238275655982ULL, - 0x5AE488713E45CF05ULL, 0xBF619F9954C21157ULL, 0xEABAC46040A8EAE9ULL, - 0x454C6FE9F2C0C1CDULL, 0x419CF6496412691CULL, 0xD3DC3BEF265B0F70ULL, - 0x6D0E60F5C3578A9EULL }; - -const u64bit Tiger::SBOX4[256] = { - 0x5B0E608526323C55ULL, 0x1A46C1A9FA1B59F5ULL, 0xA9E245A17C4C8FFAULL, - 0x65CA5159DB2955D7ULL, 0x05DB0A76CE35AFC2ULL, 0x81EAC77EA9113D45ULL, - 0x528EF88AB6AC0A0DULL, 0xA09EA253597BE3FFULL, 0x430DDFB3AC48CD56ULL, - 0xC4B3A67AF45CE46FULL, 0x4ECECFD8FBE2D05EULL, 0x3EF56F10B39935F0ULL, - 0x0B22D6829CD619C6ULL, 0x17FD460A74DF2069ULL, 0x6CF8CC8E8510ED40ULL, - 0xD6C824BF3A6ECAA7ULL, 0x61243D581A817049ULL, 0x048BACB6BBC163A2ULL, - 0xD9A38AC27D44CC32ULL, 0x7FDDFF5BAAF410ABULL, 0xAD6D495AA804824BULL, - 0xE1A6A74F2D8C9F94ULL, 0xD4F7851235DEE8E3ULL, 0xFD4B7F886540D893ULL, - 0x247C20042AA4BFDAULL, 0x096EA1C517D1327CULL, 0xD56966B4361A6685ULL, - 0x277DA5C31221057DULL, 0x94D59893A43ACFF7ULL, 0x64F0C51CCDC02281ULL, - 0x3D33BCC4FF6189DBULL, 0xE005CB184CE66AF1ULL, 0xFF5CCD1D1DB99BEAULL, - 0xB0B854A7FE42980FULL, 0x7BD46A6A718D4B9FULL, 0xD10FA8CC22A5FD8CULL, - 0xD31484952BE4BD31ULL, 0xC7FA975FCB243847ULL, 0x4886ED1E5846C407ULL, - 0x28CDDB791EB70B04ULL, 0xC2B00BE2F573417FULL, 0x5C9590452180F877ULL, - 0x7A6BDDFFF370EB00ULL, 0xCE509E38D6D9D6A4ULL, 0xEBEB0F00647FA702ULL, - 0x1DCC06CF76606F06ULL, 0xE4D9F28BA286FF0AULL, 0xD85A305DC918C262ULL, - 0x475B1D8732225F54ULL, 0x2D4FB51668CCB5FEULL, 0xA679B9D9D72BBA20ULL, - 0x53841C0D912D43A5ULL, 0x3B7EAA48BF12A4E8ULL, 0x781E0E47F22F1DDFULL, - 0xEFF20CE60AB50973ULL, 0x20D261D19DFFB742ULL, 0x16A12B03062A2E39ULL, - 0x1960EB2239650495ULL, 0x251C16FED50EB8B8ULL, 0x9AC0C330F826016EULL, - 0xED152665953E7671ULL, 0x02D63194A6369570ULL, 0x5074F08394B1C987ULL, - 0x70BA598C90B25CE1ULL, 0x794A15810B9742F6ULL, 0x0D5925E9FCAF8C6CULL, - 0x3067716CD868744EULL, 0x910AB077E8D7731BULL, 0x6A61BBDB5AC42F61ULL, - 0x93513EFBF0851567ULL, 0xF494724B9E83E9D5ULL, 0xE887E1985C09648DULL, - 0x34B1D3C675370CFDULL, 0xDC35E433BC0D255DULL, 0xD0AAB84234131BE0ULL, - 0x08042A50B48B7EAFULL, 0x9997C4EE44A3AB35ULL, 0x829A7B49201799D0ULL, - 0x263B8307B7C54441ULL, 0x752F95F4FD6A6CA6ULL, 0x927217402C08C6E5ULL, - 0x2A8AB754A795D9EEULL, 0xA442F7552F72943DULL, 0x2C31334E19781208ULL, - 0x4FA98D7CEAEE6291ULL, 0x55C3862F665DB309ULL, 0xBD0610175D53B1F3ULL, - 0x46FE6CB840413F27ULL, 0x3FE03792DF0CFA59ULL, 0xCFE700372EB85E8FULL, - 0xA7BE29E7ADBCE118ULL, 0xE544EE5CDE8431DDULL, 0x8A781B1B41F1873EULL, - 0xA5C94C78A0D2F0E7ULL, 0x39412E2877B60728ULL, 0xA1265EF3AFC9A62CULL, - 0xBCC2770C6A2506C5ULL, 0x3AB66DD5DCE1CE12ULL, 0xE65499D04A675B37ULL, - 0x7D8F523481BFD216ULL, 0x0F6F64FCEC15F389ULL, 0x74EFBE618B5B13C8ULL, - 0xACDC82B714273E1DULL, 0xDD40BFE003199D17ULL, 0x37E99257E7E061F8ULL, - 0xFA52626904775AAAULL, 0x8BBBF63A463D56F9ULL, 0xF0013F1543A26E64ULL, - 0xA8307E9F879EC898ULL, 0xCC4C27A4150177CCULL, 0x1B432F2CCA1D3348ULL, - 0xDE1D1F8F9F6FA013ULL, 0x606602A047A7DDD6ULL, 0xD237AB64CC1CB2C7ULL, - 0x9B938E7225FCD1D3ULL, 0xEC4E03708E0FF476ULL, 0xFEB2FBDA3D03C12DULL, - 0xAE0BCED2EE43889AULL, 0x22CB8923EBFB4F43ULL, 0x69360D013CF7396DULL, - 0x855E3602D2D4E022ULL, 0x073805BAD01F784CULL, 0x33E17A133852F546ULL, - 0xDF4874058AC7B638ULL, 0xBA92B29C678AA14AULL, 0x0CE89FC76CFAADCDULL, - 0x5F9D4E0908339E34ULL, 0xF1AFE9291F5923B9ULL, 0x6E3480F60F4A265FULL, - 0xEEBF3A2AB29B841CULL, 0xE21938A88F91B4ADULL, 0x57DFEFF845C6D3C3ULL, - 0x2F006B0BF62CAAF2ULL, 0x62F479EF6F75EE78ULL, 0x11A55AD41C8916A9ULL, - 0xF229D29084FED453ULL, 0x42F1C27B16B000E6ULL, 0x2B1F76749823C074ULL, - 0x4B76ECA3C2745360ULL, 0x8C98F463B91691BDULL, 0x14BCC93CF1ADE66AULL, - 0x8885213E6D458397ULL, 0x8E177DF0274D4711ULL, 0xB49B73B5503F2951ULL, - 0x10168168C3F96B6BULL, 0x0E3D963B63CAB0AEULL, 0x8DFC4B5655A1DB14ULL, - 0xF789F1356E14DE5CULL, 0x683E68AF4E51DAC1ULL, 0xC9A84F9D8D4B0FD9ULL, - 0x3691E03F52A0F9D1ULL, 0x5ED86E46E1878E80ULL, 0x3C711A0E99D07150ULL, - 0x5A0865B20C4E9310ULL, 0x56FBFC1FE4F0682EULL, 0xEA8D5DE3105EDF9BULL, - 0x71ABFDB12379187AULL, 0x2EB99DE1BEE77B9CULL, 0x21ECC0EA33CF4523ULL, - 0x59A4D7521805C7A1ULL, 0x3896F5EB56AE7C72ULL, 0xAA638F3DB18F75DCULL, - 0x9F39358DABE9808EULL, 0xB7DEFA91C00B72ACULL, 0x6B5541FD62492D92ULL, - 0x6DC6DEE8F92E4D5BULL, 0x353F57ABC4BEEA7EULL, 0x735769D6DA5690CEULL, - 0x0A234AA642391484ULL, 0xF6F9508028F80D9DULL, 0xB8E319A27AB3F215ULL, - 0x31AD9C1151341A4DULL, 0x773C22A57BEF5805ULL, 0x45C7561A07968633ULL, - 0xF913DA9E249DBE36ULL, 0xDA652D9B78A64C68ULL, 0x4C27A97F3BC334EFULL, - 0x76621220E66B17F4ULL, 0x967743899ACD7D0BULL, 0xF3EE5BCAE0ED6782ULL, - 0x409F753600C879FCULL, 0x06D09A39B5926DB6ULL, 0x6F83AEB0317AC588ULL, - 0x01E6CA4A86381F21ULL, 0x66FF3462D19F3025ULL, 0x72207C24DDFD3BFBULL, - 0x4AF6B6D3E2ECE2EBULL, 0x9C994DBEC7EA08DEULL, 0x49ACE597B09A8BC4ULL, - 0xB38C4766CF0797BAULL, 0x131B9373C57C2A75ULL, 0xB1822CCE61931E58ULL, - 0x9D7555B909BA1C0CULL, 0x127FAFDD937D11D2ULL, 0x29DA3BADC66D92E4ULL, - 0xA2C1D57154C2ECBCULL, 0x58C5134D82F6FE24ULL, 0x1C3AE3515B62274FULL, - 0xE907C82E01CB8126ULL, 0xF8ED091913E37FCBULL, 0x3249D8F9C80046C9ULL, - 0x80CF9BEDE388FB63ULL, 0x1881539A116CF19EULL, 0x5103F3F76BD52457ULL, - 0x15B7E6F5AE47F7A8ULL, 0xDBD7C6DED47E9CCFULL, 0x44E55C410228BB1AULL, - 0xB647D4255EDB4E99ULL, 0x5D11882BB8AAFC30ULL, 0xF5098BBB29D3212AULL, - 0x8FB5EA14E90296B3ULL, 0x677B942157DD025AULL, 0xFB58E7C0A390ACB5ULL, - 0x89D3674C83BD4A01ULL, 0x9E2DA4DF4BF3B93BULL, 0xFCC41E328CAB4829ULL, - 0x03F38C96BA582C52ULL, 0xCAD1BDBD7FD85DB2ULL, 0xBBB442C16082AE83ULL, - 0xB95FE86BA5DA9AB0ULL, 0xB22E04673771A93FULL, 0x845358C9493152D8ULL, - 0xBE2A488697B4541EULL, 0x95A2DC2DD38E6966ULL, 0xC02C11AC923C852BULL, - 0x2388B1990DF2A87BULL, 0x7C8008FA1B4F37BEULL, 0x1F70D0C84D54E503ULL, - 0x5490ADEC7ECE57D4ULL, 0x002B3C27D9063A3AULL, 0x7EAEA3848030A2BFULL, - 0xC602326DED2003C0ULL, 0x83A7287D69A94086ULL, 0xC57A5FCB30F57A8AULL, - 0xB56844E479EBE779ULL, 0xA373B40F05DCBCE9ULL, 0xD71A786E88570EE2ULL, - 0x879CBACDBDE8F6A0ULL, 0x976AD1BCC164A32FULL, 0xAB21E25E9666D78BULL, - 0x901063AAE5E5C33CULL, 0x9818B34448698D90ULL, 0xE36487AE3E1E8ABBULL, - 0xAFBDF931893BDCB4ULL, 0x6345A0DC5FBBD519ULL, 0x8628FE269B9465CAULL, - 0x1E5D01603F9C51ECULL, 0x4DE44006A15049B7ULL, 0xBF6C70E5F776CBB1ULL, - 0x411218F2EF552BEDULL, 0xCB0C0708705A36A3ULL, 0xE74D14754F986044ULL, - 0xCD56D9430EA8280EULL, 0xC12591D7535F5065ULL, 0xC83223F1720AEF96ULL, - 0xC3A0396F7363A51FULL }; - -} -/* -* Tiger -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -namespace { - -/* -* Tiger Mixing Function -*/ -inline void mix(MemoryRegion& X) - { - X[0] -= X[7] ^ 0xA5A5A5A5A5A5A5A5ULL; - X[1] ^= X[0]; - X[2] += X[1]; - X[3] -= X[2] ^ ((~X[1]) << 19); - X[4] ^= X[3]; - X[5] += X[4]; - X[6] -= X[5] ^ ((~X[4]) >> 23); - X[7] ^= X[6]; - - X[0] += X[7]; - X[1] -= X[0] ^ ((~X[7]) << 19); - X[2] ^= X[1]; - X[3] += X[2]; - X[4] -= X[3] ^ ((~X[2]) >> 23); - X[5] ^= X[4]; - X[6] += X[5]; - X[7] -= X[6] ^ 0x0123456789ABCDEFULL; - } - -} - -/* -* Tiger Compression Function -*/ -void Tiger::compress_n(const byte input[], size_t blocks) - { - u64bit A = digest[0], B = digest[1], C = digest[2]; - - for(size_t i = 0; i != blocks; ++i) - { - load_le(&X[0], input, X.size()); - - pass(A, B, C, X, 5); mix(X); - pass(C, A, B, X, 7); mix(X); - pass(B, C, A, X, 9); - - for(size_t j = 3; j != passes; ++j) - { - mix(X); - pass(A, B, C, X, 9); - u64bit T = A; A = C; C = B; B = T; - } - - A = (digest[0] ^= A); - B = digest[1] = B - digest[1]; - C = (digest[2] += C); - - input += hash_block_size(); - } - } - -/* -* Copy out the digest -*/ -void Tiger::copy_out(byte output[]) - { - for(size_t i = 0; i != output_length(); ++i) - output[i] = get_byte(7 - (i % 8), digest[i/8]); - } - -/* -* Tiger Pass -*/ -void Tiger::pass(u64bit& A, u64bit& B, u64bit& C, - const MemoryRegion& X, - byte mul) - { - C ^= X[0]; - A -= SBOX1[get_byte(7, C)] ^ SBOX2[get_byte(5, C)] ^ - SBOX3[get_byte(3, C)] ^ SBOX4[get_byte(1, C)]; - B += SBOX1[get_byte(0, C)] ^ SBOX2[get_byte(2, C)] ^ - SBOX3[get_byte(4, C)] ^ SBOX4[get_byte(6, C)]; - B *= mul; - - A ^= X[1]; - B -= SBOX1[get_byte(7, A)] ^ SBOX2[get_byte(5, A)] ^ - SBOX3[get_byte(3, A)] ^ SBOX4[get_byte(1, A)]; - C += SBOX1[get_byte(0, A)] ^ SBOX2[get_byte(2, A)] ^ - SBOX3[get_byte(4, A)] ^ SBOX4[get_byte(6, A)]; - C *= mul; - - B ^= X[2]; - C -= SBOX1[get_byte(7, B)] ^ SBOX2[get_byte(5, B)] ^ - SBOX3[get_byte(3, B)] ^ SBOX4[get_byte(1, B)]; - A += SBOX1[get_byte(0, B)] ^ SBOX2[get_byte(2, B)] ^ - SBOX3[get_byte(4, B)] ^ SBOX4[get_byte(6, B)]; - A *= mul; - - C ^= X[3]; - A -= SBOX1[get_byte(7, C)] ^ SBOX2[get_byte(5, C)] ^ - SBOX3[get_byte(3, C)] ^ SBOX4[get_byte(1, C)]; - B += SBOX1[get_byte(0, C)] ^ SBOX2[get_byte(2, C)] ^ - SBOX3[get_byte(4, C)] ^ SBOX4[get_byte(6, C)]; - B *= mul; - - A ^= X[4]; - B -= SBOX1[get_byte(7, A)] ^ SBOX2[get_byte(5, A)] ^ - SBOX3[get_byte(3, A)] ^ SBOX4[get_byte(1, A)]; - C += SBOX1[get_byte(0, A)] ^ SBOX2[get_byte(2, A)] ^ - SBOX3[get_byte(4, A)] ^ SBOX4[get_byte(6, A)]; - C *= mul; - - B ^= X[5]; - C -= SBOX1[get_byte(7, B)] ^ SBOX2[get_byte(5, B)] ^ - SBOX3[get_byte(3, B)] ^ SBOX4[get_byte(1, B)]; - A += SBOX1[get_byte(0, B)] ^ SBOX2[get_byte(2, B)] ^ - SBOX3[get_byte(4, B)] ^ SBOX4[get_byte(6, B)]; - A *= mul; - - C ^= X[6]; - A -= SBOX1[get_byte(7, C)] ^ SBOX2[get_byte(5, C)] ^ - SBOX3[get_byte(3, C)] ^ SBOX4[get_byte(1, C)]; - B += SBOX1[get_byte(0, C)] ^ SBOX2[get_byte(2, C)] ^ - SBOX3[get_byte(4, C)] ^ SBOX4[get_byte(6, C)]; - B *= mul; - - A ^= X[7]; - B -= SBOX1[get_byte(7, A)] ^ SBOX2[get_byte(5, A)] ^ - SBOX3[get_byte(3, A)] ^ SBOX4[get_byte(1, A)]; - C += SBOX1[get_byte(0, A)] ^ SBOX2[get_byte(2, A)] ^ - SBOX3[get_byte(4, A)] ^ SBOX4[get_byte(6, A)]; - C *= mul; - } - -/* -* Clear memory of sensitive data -*/ -void Tiger::clear() - { - MDx_HashFunction::clear(); - zeroise(X); - digest[0] = 0x0123456789ABCDEFULL; - digest[1] = 0xFEDCBA9876543210ULL; - digest[2] = 0xF096A5B4C3B2E187ULL; - } - -/* -* Return the name of this type -*/ -std::string Tiger::name() const - { - return "Tiger(" + to_string(output_length()) + "," + to_string(passes) + ")"; - } - -/* -* Tiger Constructor -*/ -Tiger::Tiger(size_t hash_len, size_t passes) : - MDx_HashFunction(64, false, false), - X(8), - digest(3), - hash_len(hash_len), - passes(passes) - { - if(output_length() != 16 && output_length() != 20 && output_length() != 24) - throw Invalid_Argument("Tiger: Illegal hash output size: " + - to_string(output_length())); - - if(passes < 3) - throw Invalid_Argument("Tiger: Invalid number of passes: " - + to_string(passes)); - clear(); - } - -} -/* -* Diffusion Tables for Whirlpool -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -const u64bit Whirlpool::C0[256] = { -0x18186018C07830D8ULL, 0x23238C2305AF4626ULL, 0xC6C63FC67EF991B8ULL, 0xE8E887E8136FCDFBULL, -0x878726874CA113CBULL, 0xB8B8DAB8A9626D11ULL, 0x0101040108050209ULL, 0x4F4F214F426E9E0DULL, -0x3636D836ADEE6C9BULL, 0xA6A6A2A6590451FFULL, 0xD2D26FD2DEBDB90CULL, 0xF5F5F3F5FB06F70EULL, -0x7979F979EF80F296ULL, 0x6F6FA16F5FCEDE30ULL, 0x91917E91FCEF3F6DULL, 0x52525552AA07A4F8ULL, -0x60609D6027FDC047ULL, 0xBCBCCABC89766535ULL, 0x9B9B569BACCD2B37ULL, 0x8E8E028E048C018AULL, -0xA3A3B6A371155BD2ULL, 0x0C0C300C603C186CULL, 0x7B7BF17BFF8AF684ULL, 0x3535D435B5E16A80ULL, -0x1D1D741DE8693AF5ULL, 0xE0E0A7E05347DDB3ULL, 0xD7D77BD7F6ACB321ULL, 0xC2C22FC25EED999CULL, -0x2E2EB82E6D965C43ULL, 0x4B4B314B627A9629ULL, 0xFEFEDFFEA321E15DULL, 0x575741578216AED5ULL, -0x15155415A8412ABDULL, 0x7777C1779FB6EEE8ULL, 0x3737DC37A5EB6E92ULL, 0xE5E5B3E57B56D79EULL, -0x9F9F469F8CD92313ULL, 0xF0F0E7F0D317FD23ULL, 0x4A4A354A6A7F9420ULL, 0xDADA4FDA9E95A944ULL, -0x58587D58FA25B0A2ULL, 0xC9C903C906CA8FCFULL, 0x2929A429558D527CULL, 0x0A0A280A5022145AULL, -0xB1B1FEB1E14F7F50ULL, 0xA0A0BAA0691A5DC9ULL, 0x6B6BB16B7FDAD614ULL, 0x85852E855CAB17D9ULL, -0xBDBDCEBD8173673CULL, 0x5D5D695DD234BA8FULL, 0x1010401080502090ULL, 0xF4F4F7F4F303F507ULL, -0xCBCB0BCB16C08BDDULL, 0x3E3EF83EEDC67CD3ULL, 0x0505140528110A2DULL, 0x676781671FE6CE78ULL, -0xE4E4B7E47353D597ULL, 0x27279C2725BB4E02ULL, 0x4141194132588273ULL, 0x8B8B168B2C9D0BA7ULL, -0xA7A7A6A7510153F6ULL, 0x7D7DE97DCF94FAB2ULL, 0x95956E95DCFB3749ULL, 0xD8D847D88E9FAD56ULL, -0xFBFBCBFB8B30EB70ULL, 0xEEEE9FEE2371C1CDULL, 0x7C7CED7CC791F8BBULL, 0x6666856617E3CC71ULL, -0xDDDD53DDA68EA77BULL, 0x17175C17B84B2EAFULL, 0x4747014702468E45ULL, 0x9E9E429E84DC211AULL, -0xCACA0FCA1EC589D4ULL, 0x2D2DB42D75995A58ULL, 0xBFBFC6BF9179632EULL, 0x07071C07381B0E3FULL, -0xADAD8EAD012347ACULL, 0x5A5A755AEA2FB4B0ULL, 0x838336836CB51BEFULL, 0x3333CC3385FF66B6ULL, -0x636391633FF2C65CULL, 0x02020802100A0412ULL, 0xAAAA92AA39384993ULL, 0x7171D971AFA8E2DEULL, -0xC8C807C80ECF8DC6ULL, 0x19196419C87D32D1ULL, 0x494939497270923BULL, 0xD9D943D9869AAF5FULL, -0xF2F2EFF2C31DF931ULL, 0xE3E3ABE34B48DBA8ULL, 0x5B5B715BE22AB6B9ULL, 0x88881A8834920DBCULL, -0x9A9A529AA4C8293EULL, 0x262698262DBE4C0BULL, 0x3232C8328DFA64BFULL, 0xB0B0FAB0E94A7D59ULL, -0xE9E983E91B6ACFF2ULL, 0x0F0F3C0F78331E77ULL, 0xD5D573D5E6A6B733ULL, 0x80803A8074BA1DF4ULL, -0xBEBEC2BE997C6127ULL, 0xCDCD13CD26DE87EBULL, 0x3434D034BDE46889ULL, 0x48483D487A759032ULL, -0xFFFFDBFFAB24E354ULL, 0x7A7AF57AF78FF48DULL, 0x90907A90F4EA3D64ULL, 0x5F5F615FC23EBE9DULL, -0x202080201DA0403DULL, 0x6868BD6867D5D00FULL, 0x1A1A681AD07234CAULL, 0xAEAE82AE192C41B7ULL, -0xB4B4EAB4C95E757DULL, 0x54544D549A19A8CEULL, 0x93937693ECE53B7FULL, 0x222288220DAA442FULL, -0x64648D6407E9C863ULL, 0xF1F1E3F1DB12FF2AULL, 0x7373D173BFA2E6CCULL, 0x12124812905A2482ULL, -0x40401D403A5D807AULL, 0x0808200840281048ULL, 0xC3C32BC356E89B95ULL, 0xECEC97EC337BC5DFULL, -0xDBDB4BDB9690AB4DULL, 0xA1A1BEA1611F5FC0ULL, 0x8D8D0E8D1C830791ULL, 0x3D3DF43DF5C97AC8ULL, -0x97976697CCF1335BULL, 0x0000000000000000ULL, 0xCFCF1BCF36D483F9ULL, 0x2B2BAC2B4587566EULL, -0x7676C57697B3ECE1ULL, 0x8282328264B019E6ULL, 0xD6D67FD6FEA9B128ULL, 0x1B1B6C1BD87736C3ULL, -0xB5B5EEB5C15B7774ULL, 0xAFAF86AF112943BEULL, 0x6A6AB56A77DFD41DULL, 0x50505D50BA0DA0EAULL, -0x45450945124C8A57ULL, 0xF3F3EBF3CB18FB38ULL, 0x3030C0309DF060ADULL, 0xEFEF9BEF2B74C3C4ULL, -0x3F3FFC3FE5C37EDAULL, 0x55554955921CAAC7ULL, 0xA2A2B2A2791059DBULL, 0xEAEA8FEA0365C9E9ULL, -0x656589650FECCA6AULL, 0xBABAD2BAB9686903ULL, 0x2F2FBC2F65935E4AULL, 0xC0C027C04EE79D8EULL, -0xDEDE5FDEBE81A160ULL, 0x1C1C701CE06C38FCULL, 0xFDFDD3FDBB2EE746ULL, 0x4D4D294D52649A1FULL, -0x92927292E4E03976ULL, 0x7575C9758FBCEAFAULL, 0x06061806301E0C36ULL, 0x8A8A128A249809AEULL, -0xB2B2F2B2F940794BULL, 0xE6E6BFE66359D185ULL, 0x0E0E380E70361C7EULL, 0x1F1F7C1FF8633EE7ULL, -0x6262956237F7C455ULL, 0xD4D477D4EEA3B53AULL, 0xA8A89AA829324D81ULL, 0x96966296C4F43152ULL, -0xF9F9C3F99B3AEF62ULL, 0xC5C533C566F697A3ULL, 0x2525942535B14A10ULL, 0x59597959F220B2ABULL, -0x84842A8454AE15D0ULL, 0x7272D572B7A7E4C5ULL, 0x3939E439D5DD72ECULL, 0x4C4C2D4C5A619816ULL, -0x5E5E655ECA3BBC94ULL, 0x7878FD78E785F09FULL, 0x3838E038DDD870E5ULL, 0x8C8C0A8C14860598ULL, -0xD1D163D1C6B2BF17ULL, 0xA5A5AEA5410B57E4ULL, 0xE2E2AFE2434DD9A1ULL, 0x616199612FF8C24EULL, -0xB3B3F6B3F1457B42ULL, 0x2121842115A54234ULL, 0x9C9C4A9C94D62508ULL, 0x1E1E781EF0663CEEULL, -0x4343114322528661ULL, 0xC7C73BC776FC93B1ULL, 0xFCFCD7FCB32BE54FULL, 0x0404100420140824ULL, -0x51515951B208A2E3ULL, 0x99995E99BCC72F25ULL, 0x6D6DA96D4FC4DA22ULL, 0x0D0D340D68391A65ULL, -0xFAFACFFA8335E979ULL, 0xDFDF5BDFB684A369ULL, 0x7E7EE57ED79BFCA9ULL, 0x242490243DB44819ULL, -0x3B3BEC3BC5D776FEULL, 0xABAB96AB313D4B9AULL, 0xCECE1FCE3ED181F0ULL, 0x1111441188552299ULL, -0x8F8F068F0C890383ULL, 0x4E4E254E4A6B9C04ULL, 0xB7B7E6B7D1517366ULL, 0xEBEB8BEB0B60CBE0ULL, -0x3C3CF03CFDCC78C1ULL, 0x81813E817CBF1FFDULL, 0x94946A94D4FE3540ULL, 0xF7F7FBF7EB0CF31CULL, -0xB9B9DEB9A1676F18ULL, 0x13134C13985F268BULL, 0x2C2CB02C7D9C5851ULL, 0xD3D36BD3D6B8BB05ULL, -0xE7E7BBE76B5CD38CULL, 0x6E6EA56E57CBDC39ULL, 0xC4C437C46EF395AAULL, 0x03030C03180F061BULL, -0x565645568A13ACDCULL, 0x44440D441A49885EULL, 0x7F7FE17FDF9EFEA0ULL, 0xA9A99EA921374F88ULL, -0x2A2AA82A4D825467ULL, 0xBBBBD6BBB16D6B0AULL, 0xC1C123C146E29F87ULL, 0x53535153A202A6F1ULL, -0xDCDC57DCAE8BA572ULL, 0x0B0B2C0B58271653ULL, 0x9D9D4E9D9CD32701ULL, 0x6C6CAD6C47C1D82BULL, -0x3131C43195F562A4ULL, 0x7474CD7487B9E8F3ULL, 0xF6F6FFF6E309F115ULL, 0x464605460A438C4CULL, -0xACAC8AAC092645A5ULL, 0x89891E893C970FB5ULL, 0x14145014A04428B4ULL, 0xE1E1A3E15B42DFBAULL, -0x16165816B04E2CA6ULL, 0x3A3AE83ACDD274F7ULL, 0x6969B9696FD0D206ULL, 0x09092409482D1241ULL, -0x7070DD70A7ADE0D7ULL, 0xB6B6E2B6D954716FULL, 0xD0D067D0CEB7BD1EULL, 0xEDED93ED3B7EC7D6ULL, -0xCCCC17CC2EDB85E2ULL, 0x424215422A578468ULL, 0x98985A98B4C22D2CULL, 0xA4A4AAA4490E55EDULL, -0x2828A0285D885075ULL, 0x5C5C6D5CDA31B886ULL, 0xF8F8C7F8933FED6BULL, 0x8686228644A411C2ULL }; - -const u64bit Whirlpool::C1[256] = { -0xD818186018C07830ULL, 0x2623238C2305AF46ULL, 0xB8C6C63FC67EF991ULL, 0xFBE8E887E8136FCDULL, -0xCB878726874CA113ULL, 0x11B8B8DAB8A9626DULL, 0x0901010401080502ULL, 0x0D4F4F214F426E9EULL, -0x9B3636D836ADEE6CULL, 0xFFA6A6A2A6590451ULL, 0x0CD2D26FD2DEBDB9ULL, 0x0EF5F5F3F5FB06F7ULL, -0x967979F979EF80F2ULL, 0x306F6FA16F5FCEDEULL, 0x6D91917E91FCEF3FULL, 0xF852525552AA07A4ULL, -0x4760609D6027FDC0ULL, 0x35BCBCCABC897665ULL, 0x379B9B569BACCD2BULL, 0x8A8E8E028E048C01ULL, -0xD2A3A3B6A371155BULL, 0x6C0C0C300C603C18ULL, 0x847B7BF17BFF8AF6ULL, 0x803535D435B5E16AULL, -0xF51D1D741DE8693AULL, 0xB3E0E0A7E05347DDULL, 0x21D7D77BD7F6ACB3ULL, 0x9CC2C22FC25EED99ULL, -0x432E2EB82E6D965CULL, 0x294B4B314B627A96ULL, 0x5DFEFEDFFEA321E1ULL, 0xD5575741578216AEULL, -0xBD15155415A8412AULL, 0xE87777C1779FB6EEULL, 0x923737DC37A5EB6EULL, 0x9EE5E5B3E57B56D7ULL, -0x139F9F469F8CD923ULL, 0x23F0F0E7F0D317FDULL, 0x204A4A354A6A7F94ULL, 0x44DADA4FDA9E95A9ULL, -0xA258587D58FA25B0ULL, 0xCFC9C903C906CA8FULL, 0x7C2929A429558D52ULL, 0x5A0A0A280A502214ULL, -0x50B1B1FEB1E14F7FULL, 0xC9A0A0BAA0691A5DULL, 0x146B6BB16B7FDAD6ULL, 0xD985852E855CAB17ULL, -0x3CBDBDCEBD817367ULL, 0x8F5D5D695DD234BAULL, 0x9010104010805020ULL, 0x07F4F4F7F4F303F5ULL, -0xDDCBCB0BCB16C08BULL, 0xD33E3EF83EEDC67CULL, 0x2D0505140528110AULL, 0x78676781671FE6CEULL, -0x97E4E4B7E47353D5ULL, 0x0227279C2725BB4EULL, 0x7341411941325882ULL, 0xA78B8B168B2C9D0BULL, -0xF6A7A7A6A7510153ULL, 0xB27D7DE97DCF94FAULL, 0x4995956E95DCFB37ULL, 0x56D8D847D88E9FADULL, -0x70FBFBCBFB8B30EBULL, 0xCDEEEE9FEE2371C1ULL, 0xBB7C7CED7CC791F8ULL, 0x716666856617E3CCULL, -0x7BDDDD53DDA68EA7ULL, 0xAF17175C17B84B2EULL, 0x454747014702468EULL, 0x1A9E9E429E84DC21ULL, -0xD4CACA0FCA1EC589ULL, 0x582D2DB42D75995AULL, 0x2EBFBFC6BF917963ULL, 0x3F07071C07381B0EULL, -0xACADAD8EAD012347ULL, 0xB05A5A755AEA2FB4ULL, 0xEF838336836CB51BULL, 0xB63333CC3385FF66ULL, -0x5C636391633FF2C6ULL, 0x1202020802100A04ULL, 0x93AAAA92AA393849ULL, 0xDE7171D971AFA8E2ULL, -0xC6C8C807C80ECF8DULL, 0xD119196419C87D32ULL, 0x3B49493949727092ULL, 0x5FD9D943D9869AAFULL, -0x31F2F2EFF2C31DF9ULL, 0xA8E3E3ABE34B48DBULL, 0xB95B5B715BE22AB6ULL, 0xBC88881A8834920DULL, -0x3E9A9A529AA4C829ULL, 0x0B262698262DBE4CULL, 0xBF3232C8328DFA64ULL, 0x59B0B0FAB0E94A7DULL, -0xF2E9E983E91B6ACFULL, 0x770F0F3C0F78331EULL, 0x33D5D573D5E6A6B7ULL, 0xF480803A8074BA1DULL, -0x27BEBEC2BE997C61ULL, 0xEBCDCD13CD26DE87ULL, 0x893434D034BDE468ULL, 0x3248483D487A7590ULL, -0x54FFFFDBFFAB24E3ULL, 0x8D7A7AF57AF78FF4ULL, 0x6490907A90F4EA3DULL, 0x9D5F5F615FC23EBEULL, -0x3D202080201DA040ULL, 0x0F6868BD6867D5D0ULL, 0xCA1A1A681AD07234ULL, 0xB7AEAE82AE192C41ULL, -0x7DB4B4EAB4C95E75ULL, 0xCE54544D549A19A8ULL, 0x7F93937693ECE53BULL, 0x2F222288220DAA44ULL, -0x6364648D6407E9C8ULL, 0x2AF1F1E3F1DB12FFULL, 0xCC7373D173BFA2E6ULL, 0x8212124812905A24ULL, -0x7A40401D403A5D80ULL, 0x4808082008402810ULL, 0x95C3C32BC356E89BULL, 0xDFECEC97EC337BC5ULL, -0x4DDBDB4BDB9690ABULL, 0xC0A1A1BEA1611F5FULL, 0x918D8D0E8D1C8307ULL, 0xC83D3DF43DF5C97AULL, -0x5B97976697CCF133ULL, 0x0000000000000000ULL, 0xF9CFCF1BCF36D483ULL, 0x6E2B2BAC2B458756ULL, -0xE17676C57697B3ECULL, 0xE68282328264B019ULL, 0x28D6D67FD6FEA9B1ULL, 0xC31B1B6C1BD87736ULL, -0x74B5B5EEB5C15B77ULL, 0xBEAFAF86AF112943ULL, 0x1D6A6AB56A77DFD4ULL, 0xEA50505D50BA0DA0ULL, -0x5745450945124C8AULL, 0x38F3F3EBF3CB18FBULL, 0xAD3030C0309DF060ULL, 0xC4EFEF9BEF2B74C3ULL, -0xDA3F3FFC3FE5C37EULL, 0xC755554955921CAAULL, 0xDBA2A2B2A2791059ULL, 0xE9EAEA8FEA0365C9ULL, -0x6A656589650FECCAULL, 0x03BABAD2BAB96869ULL, 0x4A2F2FBC2F65935EULL, 0x8EC0C027C04EE79DULL, -0x60DEDE5FDEBE81A1ULL, 0xFC1C1C701CE06C38ULL, 0x46FDFDD3FDBB2EE7ULL, 0x1F4D4D294D52649AULL, -0x7692927292E4E039ULL, 0xFA7575C9758FBCEAULL, 0x3606061806301E0CULL, 0xAE8A8A128A249809ULL, -0x4BB2B2F2B2F94079ULL, 0x85E6E6BFE66359D1ULL, 0x7E0E0E380E70361CULL, 0xE71F1F7C1FF8633EULL, -0x556262956237F7C4ULL, 0x3AD4D477D4EEA3B5ULL, 0x81A8A89AA829324DULL, 0x5296966296C4F431ULL, -0x62F9F9C3F99B3AEFULL, 0xA3C5C533C566F697ULL, 0x102525942535B14AULL, 0xAB59597959F220B2ULL, -0xD084842A8454AE15ULL, 0xC57272D572B7A7E4ULL, 0xEC3939E439D5DD72ULL, 0x164C4C2D4C5A6198ULL, -0x945E5E655ECA3BBCULL, 0x9F7878FD78E785F0ULL, 0xE53838E038DDD870ULL, 0x988C8C0A8C148605ULL, -0x17D1D163D1C6B2BFULL, 0xE4A5A5AEA5410B57ULL, 0xA1E2E2AFE2434DD9ULL, 0x4E616199612FF8C2ULL, -0x42B3B3F6B3F1457BULL, 0x342121842115A542ULL, 0x089C9C4A9C94D625ULL, 0xEE1E1E781EF0663CULL, -0x6143431143225286ULL, 0xB1C7C73BC776FC93ULL, 0x4FFCFCD7FCB32BE5ULL, 0x2404041004201408ULL, -0xE351515951B208A2ULL, 0x2599995E99BCC72FULL, 0x226D6DA96D4FC4DAULL, 0x650D0D340D68391AULL, -0x79FAFACFFA8335E9ULL, 0x69DFDF5BDFB684A3ULL, 0xA97E7EE57ED79BFCULL, 0x19242490243DB448ULL, -0xFE3B3BEC3BC5D776ULL, 0x9AABAB96AB313D4BULL, 0xF0CECE1FCE3ED181ULL, 0x9911114411885522ULL, -0x838F8F068F0C8903ULL, 0x044E4E254E4A6B9CULL, 0x66B7B7E6B7D15173ULL, 0xE0EBEB8BEB0B60CBULL, -0xC13C3CF03CFDCC78ULL, 0xFD81813E817CBF1FULL, 0x4094946A94D4FE35ULL, 0x1CF7F7FBF7EB0CF3ULL, -0x18B9B9DEB9A1676FULL, 0x8B13134C13985F26ULL, 0x512C2CB02C7D9C58ULL, 0x05D3D36BD3D6B8BBULL, -0x8CE7E7BBE76B5CD3ULL, 0x396E6EA56E57CBDCULL, 0xAAC4C437C46EF395ULL, 0x1B03030C03180F06ULL, -0xDC565645568A13ACULL, 0x5E44440D441A4988ULL, 0xA07F7FE17FDF9EFEULL, 0x88A9A99EA921374FULL, -0x672A2AA82A4D8254ULL, 0x0ABBBBD6BBB16D6BULL, 0x87C1C123C146E29FULL, 0xF153535153A202A6ULL, -0x72DCDC57DCAE8BA5ULL, 0x530B0B2C0B582716ULL, 0x019D9D4E9D9CD327ULL, 0x2B6C6CAD6C47C1D8ULL, -0xA43131C43195F562ULL, 0xF37474CD7487B9E8ULL, 0x15F6F6FFF6E309F1ULL, 0x4C464605460A438CULL, -0xA5ACAC8AAC092645ULL, 0xB589891E893C970FULL, 0xB414145014A04428ULL, 0xBAE1E1A3E15B42DFULL, -0xA616165816B04E2CULL, 0xF73A3AE83ACDD274ULL, 0x066969B9696FD0D2ULL, 0x4109092409482D12ULL, -0xD77070DD70A7ADE0ULL, 0x6FB6B6E2B6D95471ULL, 0x1ED0D067D0CEB7BDULL, 0xD6EDED93ED3B7EC7ULL, -0xE2CCCC17CC2EDB85ULL, 0x68424215422A5784ULL, 0x2C98985A98B4C22DULL, 0xEDA4A4AAA4490E55ULL, -0x752828A0285D8850ULL, 0x865C5C6D5CDA31B8ULL, 0x6BF8F8C7F8933FEDULL, 0xC28686228644A411ULL }; - -const u64bit Whirlpool::C2[256] = { -0x30D818186018C078ULL, 0x462623238C2305AFULL, 0x91B8C6C63FC67EF9ULL, 0xCDFBE8E887E8136FULL, -0x13CB878726874CA1ULL, 0x6D11B8B8DAB8A962ULL, 0x0209010104010805ULL, 0x9E0D4F4F214F426EULL, -0x6C9B3636D836ADEEULL, 0x51FFA6A6A2A65904ULL, 0xB90CD2D26FD2DEBDULL, 0xF70EF5F5F3F5FB06ULL, -0xF2967979F979EF80ULL, 0xDE306F6FA16F5FCEULL, 0x3F6D91917E91FCEFULL, 0xA4F852525552AA07ULL, -0xC04760609D6027FDULL, 0x6535BCBCCABC8976ULL, 0x2B379B9B569BACCDULL, 0x018A8E8E028E048CULL, -0x5BD2A3A3B6A37115ULL, 0x186C0C0C300C603CULL, 0xF6847B7BF17BFF8AULL, 0x6A803535D435B5E1ULL, -0x3AF51D1D741DE869ULL, 0xDDB3E0E0A7E05347ULL, 0xB321D7D77BD7F6ACULL, 0x999CC2C22FC25EEDULL, -0x5C432E2EB82E6D96ULL, 0x96294B4B314B627AULL, 0xE15DFEFEDFFEA321ULL, 0xAED5575741578216ULL, -0x2ABD15155415A841ULL, 0xEEE87777C1779FB6ULL, 0x6E923737DC37A5EBULL, 0xD79EE5E5B3E57B56ULL, -0x23139F9F469F8CD9ULL, 0xFD23F0F0E7F0D317ULL, 0x94204A4A354A6A7FULL, 0xA944DADA4FDA9E95ULL, -0xB0A258587D58FA25ULL, 0x8FCFC9C903C906CAULL, 0x527C2929A429558DULL, 0x145A0A0A280A5022ULL, -0x7F50B1B1FEB1E14FULL, 0x5DC9A0A0BAA0691AULL, 0xD6146B6BB16B7FDAULL, 0x17D985852E855CABULL, -0x673CBDBDCEBD8173ULL, 0xBA8F5D5D695DD234ULL, 0x2090101040108050ULL, 0xF507F4F4F7F4F303ULL, -0x8BDDCBCB0BCB16C0ULL, 0x7CD33E3EF83EEDC6ULL, 0x0A2D050514052811ULL, 0xCE78676781671FE6ULL, -0xD597E4E4B7E47353ULL, 0x4E0227279C2725BBULL, 0x8273414119413258ULL, 0x0BA78B8B168B2C9DULL, -0x53F6A7A7A6A75101ULL, 0xFAB27D7DE97DCF94ULL, 0x374995956E95DCFBULL, 0xAD56D8D847D88E9FULL, -0xEB70FBFBCBFB8B30ULL, 0xC1CDEEEE9FEE2371ULL, 0xF8BB7C7CED7CC791ULL, 0xCC716666856617E3ULL, -0xA77BDDDD53DDA68EULL, 0x2EAF17175C17B84BULL, 0x8E45474701470246ULL, 0x211A9E9E429E84DCULL, -0x89D4CACA0FCA1EC5ULL, 0x5A582D2DB42D7599ULL, 0x632EBFBFC6BF9179ULL, 0x0E3F07071C07381BULL, -0x47ACADAD8EAD0123ULL, 0xB4B05A5A755AEA2FULL, 0x1BEF838336836CB5ULL, 0x66B63333CC3385FFULL, -0xC65C636391633FF2ULL, 0x041202020802100AULL, 0x4993AAAA92AA3938ULL, 0xE2DE7171D971AFA8ULL, -0x8DC6C8C807C80ECFULL, 0x32D119196419C87DULL, 0x923B494939497270ULL, 0xAF5FD9D943D9869AULL, -0xF931F2F2EFF2C31DULL, 0xDBA8E3E3ABE34B48ULL, 0xB6B95B5B715BE22AULL, 0x0DBC88881A883492ULL, -0x293E9A9A529AA4C8ULL, 0x4C0B262698262DBEULL, 0x64BF3232C8328DFAULL, 0x7D59B0B0FAB0E94AULL, -0xCFF2E9E983E91B6AULL, 0x1E770F0F3C0F7833ULL, 0xB733D5D573D5E6A6ULL, 0x1DF480803A8074BAULL, -0x6127BEBEC2BE997CULL, 0x87EBCDCD13CD26DEULL, 0x68893434D034BDE4ULL, 0x903248483D487A75ULL, -0xE354FFFFDBFFAB24ULL, 0xF48D7A7AF57AF78FULL, 0x3D6490907A90F4EAULL, 0xBE9D5F5F615FC23EULL, -0x403D202080201DA0ULL, 0xD00F6868BD6867D5ULL, 0x34CA1A1A681AD072ULL, 0x41B7AEAE82AE192CULL, -0x757DB4B4EAB4C95EULL, 0xA8CE54544D549A19ULL, 0x3B7F93937693ECE5ULL, 0x442F222288220DAAULL, -0xC86364648D6407E9ULL, 0xFF2AF1F1E3F1DB12ULL, 0xE6CC7373D173BFA2ULL, 0x248212124812905AULL, -0x807A40401D403A5DULL, 0x1048080820084028ULL, 0x9B95C3C32BC356E8ULL, 0xC5DFECEC97EC337BULL, -0xAB4DDBDB4BDB9690ULL, 0x5FC0A1A1BEA1611FULL, 0x07918D8D0E8D1C83ULL, 0x7AC83D3DF43DF5C9ULL, -0x335B97976697CCF1ULL, 0x0000000000000000ULL, 0x83F9CFCF1BCF36D4ULL, 0x566E2B2BAC2B4587ULL, -0xECE17676C57697B3ULL, 0x19E68282328264B0ULL, 0xB128D6D67FD6FEA9ULL, 0x36C31B1B6C1BD877ULL, -0x7774B5B5EEB5C15BULL, 0x43BEAFAF86AF1129ULL, 0xD41D6A6AB56A77DFULL, 0xA0EA50505D50BA0DULL, -0x8A5745450945124CULL, 0xFB38F3F3EBF3CB18ULL, 0x60AD3030C0309DF0ULL, 0xC3C4EFEF9BEF2B74ULL, -0x7EDA3F3FFC3FE5C3ULL, 0xAAC755554955921CULL, 0x59DBA2A2B2A27910ULL, 0xC9E9EAEA8FEA0365ULL, -0xCA6A656589650FECULL, 0x6903BABAD2BAB968ULL, 0x5E4A2F2FBC2F6593ULL, 0x9D8EC0C027C04EE7ULL, -0xA160DEDE5FDEBE81ULL, 0x38FC1C1C701CE06CULL, 0xE746FDFDD3FDBB2EULL, 0x9A1F4D4D294D5264ULL, -0x397692927292E4E0ULL, 0xEAFA7575C9758FBCULL, 0x0C3606061806301EULL, 0x09AE8A8A128A2498ULL, -0x794BB2B2F2B2F940ULL, 0xD185E6E6BFE66359ULL, 0x1C7E0E0E380E7036ULL, 0x3EE71F1F7C1FF863ULL, -0xC4556262956237F7ULL, 0xB53AD4D477D4EEA3ULL, 0x4D81A8A89AA82932ULL, 0x315296966296C4F4ULL, -0xEF62F9F9C3F99B3AULL, 0x97A3C5C533C566F6ULL, 0x4A102525942535B1ULL, 0xB2AB59597959F220ULL, -0x15D084842A8454AEULL, 0xE4C57272D572B7A7ULL, 0x72EC3939E439D5DDULL, 0x98164C4C2D4C5A61ULL, -0xBC945E5E655ECA3BULL, 0xF09F7878FD78E785ULL, 0x70E53838E038DDD8ULL, 0x05988C8C0A8C1486ULL, -0xBF17D1D163D1C6B2ULL, 0x57E4A5A5AEA5410BULL, 0xD9A1E2E2AFE2434DULL, 0xC24E616199612FF8ULL, -0x7B42B3B3F6B3F145ULL, 0x42342121842115A5ULL, 0x25089C9C4A9C94D6ULL, 0x3CEE1E1E781EF066ULL, -0x8661434311432252ULL, 0x93B1C7C73BC776FCULL, 0xE54FFCFCD7FCB32BULL, 0x0824040410042014ULL, -0xA2E351515951B208ULL, 0x2F2599995E99BCC7ULL, 0xDA226D6DA96D4FC4ULL, 0x1A650D0D340D6839ULL, -0xE979FAFACFFA8335ULL, 0xA369DFDF5BDFB684ULL, 0xFCA97E7EE57ED79BULL, 0x4819242490243DB4ULL, -0x76FE3B3BEC3BC5D7ULL, 0x4B9AABAB96AB313DULL, 0x81F0CECE1FCE3ED1ULL, 0x2299111144118855ULL, -0x03838F8F068F0C89ULL, 0x9C044E4E254E4A6BULL, 0x7366B7B7E6B7D151ULL, 0xCBE0EBEB8BEB0B60ULL, -0x78C13C3CF03CFDCCULL, 0x1FFD81813E817CBFULL, 0x354094946A94D4FEULL, 0xF31CF7F7FBF7EB0CULL, -0x6F18B9B9DEB9A167ULL, 0x268B13134C13985FULL, 0x58512C2CB02C7D9CULL, 0xBB05D3D36BD3D6B8ULL, -0xD38CE7E7BBE76B5CULL, 0xDC396E6EA56E57CBULL, 0x95AAC4C437C46EF3ULL, 0x061B03030C03180FULL, -0xACDC565645568A13ULL, 0x885E44440D441A49ULL, 0xFEA07F7FE17FDF9EULL, 0x4F88A9A99EA92137ULL, -0x54672A2AA82A4D82ULL, 0x6B0ABBBBD6BBB16DULL, 0x9F87C1C123C146E2ULL, 0xA6F153535153A202ULL, -0xA572DCDC57DCAE8BULL, 0x16530B0B2C0B5827ULL, 0x27019D9D4E9D9CD3ULL, 0xD82B6C6CAD6C47C1ULL, -0x62A43131C43195F5ULL, 0xE8F37474CD7487B9ULL, 0xF115F6F6FFF6E309ULL, 0x8C4C464605460A43ULL, -0x45A5ACAC8AAC0926ULL, 0x0FB589891E893C97ULL, 0x28B414145014A044ULL, 0xDFBAE1E1A3E15B42ULL, -0x2CA616165816B04EULL, 0x74F73A3AE83ACDD2ULL, 0xD2066969B9696FD0ULL, 0x124109092409482DULL, -0xE0D77070DD70A7ADULL, 0x716FB6B6E2B6D954ULL, 0xBD1ED0D067D0CEB7ULL, 0xC7D6EDED93ED3B7EULL, -0x85E2CCCC17CC2EDBULL, 0x8468424215422A57ULL, 0x2D2C98985A98B4C2ULL, 0x55EDA4A4AAA4490EULL, -0x50752828A0285D88ULL, 0xB8865C5C6D5CDA31ULL, 0xED6BF8F8C7F8933FULL, 0x11C28686228644A4ULL }; - -const u64bit Whirlpool::C3[256] = { -0x7830D818186018C0ULL, 0xAF462623238C2305ULL, 0xF991B8C6C63FC67EULL, 0x6FCDFBE8E887E813ULL, -0xA113CB878726874CULL, 0x626D11B8B8DAB8A9ULL, 0x0502090101040108ULL, 0x6E9E0D4F4F214F42ULL, -0xEE6C9B3636D836ADULL, 0x0451FFA6A6A2A659ULL, 0xBDB90CD2D26FD2DEULL, 0x06F70EF5F5F3F5FBULL, -0x80F2967979F979EFULL, 0xCEDE306F6FA16F5FULL, 0xEF3F6D91917E91FCULL, 0x07A4F852525552AAULL, -0xFDC04760609D6027ULL, 0x766535BCBCCABC89ULL, 0xCD2B379B9B569BACULL, 0x8C018A8E8E028E04ULL, -0x155BD2A3A3B6A371ULL, 0x3C186C0C0C300C60ULL, 0x8AF6847B7BF17BFFULL, 0xE16A803535D435B5ULL, -0x693AF51D1D741DE8ULL, 0x47DDB3E0E0A7E053ULL, 0xACB321D7D77BD7F6ULL, 0xED999CC2C22FC25EULL, -0x965C432E2EB82E6DULL, 0x7A96294B4B314B62ULL, 0x21E15DFEFEDFFEA3ULL, 0x16AED55757415782ULL, -0x412ABD15155415A8ULL, 0xB6EEE87777C1779FULL, 0xEB6E923737DC37A5ULL, 0x56D79EE5E5B3E57BULL, -0xD923139F9F469F8CULL, 0x17FD23F0F0E7F0D3ULL, 0x7F94204A4A354A6AULL, 0x95A944DADA4FDA9EULL, -0x25B0A258587D58FAULL, 0xCA8FCFC9C903C906ULL, 0x8D527C2929A42955ULL, 0x22145A0A0A280A50ULL, -0x4F7F50B1B1FEB1E1ULL, 0x1A5DC9A0A0BAA069ULL, 0xDAD6146B6BB16B7FULL, 0xAB17D985852E855CULL, -0x73673CBDBDCEBD81ULL, 0x34BA8F5D5D695DD2ULL, 0x5020901010401080ULL, 0x03F507F4F4F7F4F3ULL, -0xC08BDDCBCB0BCB16ULL, 0xC67CD33E3EF83EEDULL, 0x110A2D0505140528ULL, 0xE6CE78676781671FULL, -0x53D597E4E4B7E473ULL, 0xBB4E0227279C2725ULL, 0x5882734141194132ULL, 0x9D0BA78B8B168B2CULL, -0x0153F6A7A7A6A751ULL, 0x94FAB27D7DE97DCFULL, 0xFB374995956E95DCULL, 0x9FAD56D8D847D88EULL, -0x30EB70FBFBCBFB8BULL, 0x71C1CDEEEE9FEE23ULL, 0x91F8BB7C7CED7CC7ULL, 0xE3CC716666856617ULL, -0x8EA77BDDDD53DDA6ULL, 0x4B2EAF17175C17B8ULL, 0x468E454747014702ULL, 0xDC211A9E9E429E84ULL, -0xC589D4CACA0FCA1EULL, 0x995A582D2DB42D75ULL, 0x79632EBFBFC6BF91ULL, 0x1B0E3F07071C0738ULL, -0x2347ACADAD8EAD01ULL, 0x2FB4B05A5A755AEAULL, 0xB51BEF838336836CULL, 0xFF66B63333CC3385ULL, -0xF2C65C636391633FULL, 0x0A04120202080210ULL, 0x384993AAAA92AA39ULL, 0xA8E2DE7171D971AFULL, -0xCF8DC6C8C807C80EULL, 0x7D32D119196419C8ULL, 0x70923B4949394972ULL, 0x9AAF5FD9D943D986ULL, -0x1DF931F2F2EFF2C3ULL, 0x48DBA8E3E3ABE34BULL, 0x2AB6B95B5B715BE2ULL, 0x920DBC88881A8834ULL, -0xC8293E9A9A529AA4ULL, 0xBE4C0B262698262DULL, 0xFA64BF3232C8328DULL, 0x4A7D59B0B0FAB0E9ULL, -0x6ACFF2E9E983E91BULL, 0x331E770F0F3C0F78ULL, 0xA6B733D5D573D5E6ULL, 0xBA1DF480803A8074ULL, -0x7C6127BEBEC2BE99ULL, 0xDE87EBCDCD13CD26ULL, 0xE468893434D034BDULL, 0x75903248483D487AULL, -0x24E354FFFFDBFFABULL, 0x8FF48D7A7AF57AF7ULL, 0xEA3D6490907A90F4ULL, 0x3EBE9D5F5F615FC2ULL, -0xA0403D202080201DULL, 0xD5D00F6868BD6867ULL, 0x7234CA1A1A681AD0ULL, 0x2C41B7AEAE82AE19ULL, -0x5E757DB4B4EAB4C9ULL, 0x19A8CE54544D549AULL, 0xE53B7F93937693ECULL, 0xAA442F222288220DULL, -0xE9C86364648D6407ULL, 0x12FF2AF1F1E3F1DBULL, 0xA2E6CC7373D173BFULL, 0x5A24821212481290ULL, -0x5D807A40401D403AULL, 0x2810480808200840ULL, 0xE89B95C3C32BC356ULL, 0x7BC5DFECEC97EC33ULL, -0x90AB4DDBDB4BDB96ULL, 0x1F5FC0A1A1BEA161ULL, 0x8307918D8D0E8D1CULL, 0xC97AC83D3DF43DF5ULL, -0xF1335B97976697CCULL, 0x0000000000000000ULL, 0xD483F9CFCF1BCF36ULL, 0x87566E2B2BAC2B45ULL, -0xB3ECE17676C57697ULL, 0xB019E68282328264ULL, 0xA9B128D6D67FD6FEULL, 0x7736C31B1B6C1BD8ULL, -0x5B7774B5B5EEB5C1ULL, 0x2943BEAFAF86AF11ULL, 0xDFD41D6A6AB56A77ULL, 0x0DA0EA50505D50BAULL, -0x4C8A574545094512ULL, 0x18FB38F3F3EBF3CBULL, 0xF060AD3030C0309DULL, 0x74C3C4EFEF9BEF2BULL, -0xC37EDA3F3FFC3FE5ULL, 0x1CAAC75555495592ULL, 0x1059DBA2A2B2A279ULL, 0x65C9E9EAEA8FEA03ULL, -0xECCA6A656589650FULL, 0x686903BABAD2BAB9ULL, 0x935E4A2F2FBC2F65ULL, 0xE79D8EC0C027C04EULL, -0x81A160DEDE5FDEBEULL, 0x6C38FC1C1C701CE0ULL, 0x2EE746FDFDD3FDBBULL, 0x649A1F4D4D294D52ULL, -0xE0397692927292E4ULL, 0xBCEAFA7575C9758FULL, 0x1E0C360606180630ULL, 0x9809AE8A8A128A24ULL, -0x40794BB2B2F2B2F9ULL, 0x59D185E6E6BFE663ULL, 0x361C7E0E0E380E70ULL, 0x633EE71F1F7C1FF8ULL, -0xF7C4556262956237ULL, 0xA3B53AD4D477D4EEULL, 0x324D81A8A89AA829ULL, 0xF4315296966296C4ULL, -0x3AEF62F9F9C3F99BULL, 0xF697A3C5C533C566ULL, 0xB14A102525942535ULL, 0x20B2AB59597959F2ULL, -0xAE15D084842A8454ULL, 0xA7E4C57272D572B7ULL, 0xDD72EC3939E439D5ULL, 0x6198164C4C2D4C5AULL, -0x3BBC945E5E655ECAULL, 0x85F09F7878FD78E7ULL, 0xD870E53838E038DDULL, 0x8605988C8C0A8C14ULL, -0xB2BF17D1D163D1C6ULL, 0x0B57E4A5A5AEA541ULL, 0x4DD9A1E2E2AFE243ULL, 0xF8C24E616199612FULL, -0x457B42B3B3F6B3F1ULL, 0xA542342121842115ULL, 0xD625089C9C4A9C94ULL, 0x663CEE1E1E781EF0ULL, -0x5286614343114322ULL, 0xFC93B1C7C73BC776ULL, 0x2BE54FFCFCD7FCB3ULL, 0x1408240404100420ULL, -0x08A2E351515951B2ULL, 0xC72F2599995E99BCULL, 0xC4DA226D6DA96D4FULL, 0x391A650D0D340D68ULL, -0x35E979FAFACFFA83ULL, 0x84A369DFDF5BDFB6ULL, 0x9BFCA97E7EE57ED7ULL, 0xB44819242490243DULL, -0xD776FE3B3BEC3BC5ULL, 0x3D4B9AABAB96AB31ULL, 0xD181F0CECE1FCE3EULL, 0x5522991111441188ULL, -0x8903838F8F068F0CULL, 0x6B9C044E4E254E4AULL, 0x517366B7B7E6B7D1ULL, 0x60CBE0EBEB8BEB0BULL, -0xCC78C13C3CF03CFDULL, 0xBF1FFD81813E817CULL, 0xFE354094946A94D4ULL, 0x0CF31CF7F7FBF7EBULL, -0x676F18B9B9DEB9A1ULL, 0x5F268B13134C1398ULL, 0x9C58512C2CB02C7DULL, 0xB8BB05D3D36BD3D6ULL, -0x5CD38CE7E7BBE76BULL, 0xCBDC396E6EA56E57ULL, 0xF395AAC4C437C46EULL, 0x0F061B03030C0318ULL, -0x13ACDC565645568AULL, 0x49885E44440D441AULL, 0x9EFEA07F7FE17FDFULL, 0x374F88A9A99EA921ULL, -0x8254672A2AA82A4DULL, 0x6D6B0ABBBBD6BBB1ULL, 0xE29F87C1C123C146ULL, 0x02A6F153535153A2ULL, -0x8BA572DCDC57DCAEULL, 0x2716530B0B2C0B58ULL, 0xD327019D9D4E9D9CULL, 0xC1D82B6C6CAD6C47ULL, -0xF562A43131C43195ULL, 0xB9E8F37474CD7487ULL, 0x09F115F6F6FFF6E3ULL, 0x438C4C464605460AULL, -0x2645A5ACAC8AAC09ULL, 0x970FB589891E893CULL, 0x4428B414145014A0ULL, 0x42DFBAE1E1A3E15BULL, -0x4E2CA616165816B0ULL, 0xD274F73A3AE83ACDULL, 0xD0D2066969B9696FULL, 0x2D12410909240948ULL, -0xADE0D77070DD70A7ULL, 0x54716FB6B6E2B6D9ULL, 0xB7BD1ED0D067D0CEULL, 0x7EC7D6EDED93ED3BULL, -0xDB85E2CCCC17CC2EULL, 0x578468424215422AULL, 0xC22D2C98985A98B4ULL, 0x0E55EDA4A4AAA449ULL, -0x8850752828A0285DULL, 0x31B8865C5C6D5CDAULL, 0x3FED6BF8F8C7F893ULL, 0xA411C28686228644ULL }; - -const u64bit Whirlpool::C4[256] = { -0xC07830D818186018ULL, 0x05AF462623238C23ULL, 0x7EF991B8C6C63FC6ULL, 0x136FCDFBE8E887E8ULL, -0x4CA113CB87872687ULL, 0xA9626D11B8B8DAB8ULL, 0x0805020901010401ULL, 0x426E9E0D4F4F214FULL, -0xADEE6C9B3636D836ULL, 0x590451FFA6A6A2A6ULL, 0xDEBDB90CD2D26FD2ULL, 0xFB06F70EF5F5F3F5ULL, -0xEF80F2967979F979ULL, 0x5FCEDE306F6FA16FULL, 0xFCEF3F6D91917E91ULL, 0xAA07A4F852525552ULL, -0x27FDC04760609D60ULL, 0x89766535BCBCCABCULL, 0xACCD2B379B9B569BULL, 0x048C018A8E8E028EULL, -0x71155BD2A3A3B6A3ULL, 0x603C186C0C0C300CULL, 0xFF8AF6847B7BF17BULL, 0xB5E16A803535D435ULL, -0xE8693AF51D1D741DULL, 0x5347DDB3E0E0A7E0ULL, 0xF6ACB321D7D77BD7ULL, 0x5EED999CC2C22FC2ULL, -0x6D965C432E2EB82EULL, 0x627A96294B4B314BULL, 0xA321E15DFEFEDFFEULL, 0x8216AED557574157ULL, -0xA8412ABD15155415ULL, 0x9FB6EEE87777C177ULL, 0xA5EB6E923737DC37ULL, 0x7B56D79EE5E5B3E5ULL, -0x8CD923139F9F469FULL, 0xD317FD23F0F0E7F0ULL, 0x6A7F94204A4A354AULL, 0x9E95A944DADA4FDAULL, -0xFA25B0A258587D58ULL, 0x06CA8FCFC9C903C9ULL, 0x558D527C2929A429ULL, 0x5022145A0A0A280AULL, -0xE14F7F50B1B1FEB1ULL, 0x691A5DC9A0A0BAA0ULL, 0x7FDAD6146B6BB16BULL, 0x5CAB17D985852E85ULL, -0x8173673CBDBDCEBDULL, 0xD234BA8F5D5D695DULL, 0x8050209010104010ULL, 0xF303F507F4F4F7F4ULL, -0x16C08BDDCBCB0BCBULL, 0xEDC67CD33E3EF83EULL, 0x28110A2D05051405ULL, 0x1FE6CE7867678167ULL, -0x7353D597E4E4B7E4ULL, 0x25BB4E0227279C27ULL, 0x3258827341411941ULL, 0x2C9D0BA78B8B168BULL, -0x510153F6A7A7A6A7ULL, 0xCF94FAB27D7DE97DULL, 0xDCFB374995956E95ULL, 0x8E9FAD56D8D847D8ULL, -0x8B30EB70FBFBCBFBULL, 0x2371C1CDEEEE9FEEULL, 0xC791F8BB7C7CED7CULL, 0x17E3CC7166668566ULL, -0xA68EA77BDDDD53DDULL, 0xB84B2EAF17175C17ULL, 0x02468E4547470147ULL, 0x84DC211A9E9E429EULL, -0x1EC589D4CACA0FCAULL, 0x75995A582D2DB42DULL, 0x9179632EBFBFC6BFULL, 0x381B0E3F07071C07ULL, -0x012347ACADAD8EADULL, 0xEA2FB4B05A5A755AULL, 0x6CB51BEF83833683ULL, 0x85FF66B63333CC33ULL, -0x3FF2C65C63639163ULL, 0x100A041202020802ULL, 0x39384993AAAA92AAULL, 0xAFA8E2DE7171D971ULL, -0x0ECF8DC6C8C807C8ULL, 0xC87D32D119196419ULL, 0x7270923B49493949ULL, 0x869AAF5FD9D943D9ULL, -0xC31DF931F2F2EFF2ULL, 0x4B48DBA8E3E3ABE3ULL, 0xE22AB6B95B5B715BULL, 0x34920DBC88881A88ULL, -0xA4C8293E9A9A529AULL, 0x2DBE4C0B26269826ULL, 0x8DFA64BF3232C832ULL, 0xE94A7D59B0B0FAB0ULL, -0x1B6ACFF2E9E983E9ULL, 0x78331E770F0F3C0FULL, 0xE6A6B733D5D573D5ULL, 0x74BA1DF480803A80ULL, -0x997C6127BEBEC2BEULL, 0x26DE87EBCDCD13CDULL, 0xBDE468893434D034ULL, 0x7A75903248483D48ULL, -0xAB24E354FFFFDBFFULL, 0xF78FF48D7A7AF57AULL, 0xF4EA3D6490907A90ULL, 0xC23EBE9D5F5F615FULL, -0x1DA0403D20208020ULL, 0x67D5D00F6868BD68ULL, 0xD07234CA1A1A681AULL, 0x192C41B7AEAE82AEULL, -0xC95E757DB4B4EAB4ULL, 0x9A19A8CE54544D54ULL, 0xECE53B7F93937693ULL, 0x0DAA442F22228822ULL, -0x07E9C86364648D64ULL, 0xDB12FF2AF1F1E3F1ULL, 0xBFA2E6CC7373D173ULL, 0x905A248212124812ULL, -0x3A5D807A40401D40ULL, 0x4028104808082008ULL, 0x56E89B95C3C32BC3ULL, 0x337BC5DFECEC97ECULL, -0x9690AB4DDBDB4BDBULL, 0x611F5FC0A1A1BEA1ULL, 0x1C8307918D8D0E8DULL, 0xF5C97AC83D3DF43DULL, -0xCCF1335B97976697ULL, 0x0000000000000000ULL, 0x36D483F9CFCF1BCFULL, 0x4587566E2B2BAC2BULL, -0x97B3ECE17676C576ULL, 0x64B019E682823282ULL, 0xFEA9B128D6D67FD6ULL, 0xD87736C31B1B6C1BULL, -0xC15B7774B5B5EEB5ULL, 0x112943BEAFAF86AFULL, 0x77DFD41D6A6AB56AULL, 0xBA0DA0EA50505D50ULL, -0x124C8A5745450945ULL, 0xCB18FB38F3F3EBF3ULL, 0x9DF060AD3030C030ULL, 0x2B74C3C4EFEF9BEFULL, -0xE5C37EDA3F3FFC3FULL, 0x921CAAC755554955ULL, 0x791059DBA2A2B2A2ULL, 0x0365C9E9EAEA8FEAULL, -0x0FECCA6A65658965ULL, 0xB9686903BABAD2BAULL, 0x65935E4A2F2FBC2FULL, 0x4EE79D8EC0C027C0ULL, -0xBE81A160DEDE5FDEULL, 0xE06C38FC1C1C701CULL, 0xBB2EE746FDFDD3FDULL, 0x52649A1F4D4D294DULL, -0xE4E0397692927292ULL, 0x8FBCEAFA7575C975ULL, 0x301E0C3606061806ULL, 0x249809AE8A8A128AULL, -0xF940794BB2B2F2B2ULL, 0x6359D185E6E6BFE6ULL, 0x70361C7E0E0E380EULL, 0xF8633EE71F1F7C1FULL, -0x37F7C45562629562ULL, 0xEEA3B53AD4D477D4ULL, 0x29324D81A8A89AA8ULL, 0xC4F4315296966296ULL, -0x9B3AEF62F9F9C3F9ULL, 0x66F697A3C5C533C5ULL, 0x35B14A1025259425ULL, 0xF220B2AB59597959ULL, -0x54AE15D084842A84ULL, 0xB7A7E4C57272D572ULL, 0xD5DD72EC3939E439ULL, 0x5A6198164C4C2D4CULL, -0xCA3BBC945E5E655EULL, 0xE785F09F7878FD78ULL, 0xDDD870E53838E038ULL, 0x148605988C8C0A8CULL, -0xC6B2BF17D1D163D1ULL, 0x410B57E4A5A5AEA5ULL, 0x434DD9A1E2E2AFE2ULL, 0x2FF8C24E61619961ULL, -0xF1457B42B3B3F6B3ULL, 0x15A5423421218421ULL, 0x94D625089C9C4A9CULL, 0xF0663CEE1E1E781EULL, -0x2252866143431143ULL, 0x76FC93B1C7C73BC7ULL, 0xB32BE54FFCFCD7FCULL, 0x2014082404041004ULL, -0xB208A2E351515951ULL, 0xBCC72F2599995E99ULL, 0x4FC4DA226D6DA96DULL, 0x68391A650D0D340DULL, -0x8335E979FAFACFFAULL, 0xB684A369DFDF5BDFULL, 0xD79BFCA97E7EE57EULL, 0x3DB4481924249024ULL, -0xC5D776FE3B3BEC3BULL, 0x313D4B9AABAB96ABULL, 0x3ED181F0CECE1FCEULL, 0x8855229911114411ULL, -0x0C8903838F8F068FULL, 0x4A6B9C044E4E254EULL, 0xD1517366B7B7E6B7ULL, 0x0B60CBE0EBEB8BEBULL, -0xFDCC78C13C3CF03CULL, 0x7CBF1FFD81813E81ULL, 0xD4FE354094946A94ULL, 0xEB0CF31CF7F7FBF7ULL, -0xA1676F18B9B9DEB9ULL, 0x985F268B13134C13ULL, 0x7D9C58512C2CB02CULL, 0xD6B8BB05D3D36BD3ULL, -0x6B5CD38CE7E7BBE7ULL, 0x57CBDC396E6EA56EULL, 0x6EF395AAC4C437C4ULL, 0x180F061B03030C03ULL, -0x8A13ACDC56564556ULL, 0x1A49885E44440D44ULL, 0xDF9EFEA07F7FE17FULL, 0x21374F88A9A99EA9ULL, -0x4D8254672A2AA82AULL, 0xB16D6B0ABBBBD6BBULL, 0x46E29F87C1C123C1ULL, 0xA202A6F153535153ULL, -0xAE8BA572DCDC57DCULL, 0x582716530B0B2C0BULL, 0x9CD327019D9D4E9DULL, 0x47C1D82B6C6CAD6CULL, -0x95F562A43131C431ULL, 0x87B9E8F37474CD74ULL, 0xE309F115F6F6FFF6ULL, 0x0A438C4C46460546ULL, -0x092645A5ACAC8AACULL, 0x3C970FB589891E89ULL, 0xA04428B414145014ULL, 0x5B42DFBAE1E1A3E1ULL, -0xB04E2CA616165816ULL, 0xCDD274F73A3AE83AULL, 0x6FD0D2066969B969ULL, 0x482D124109092409ULL, -0xA7ADE0D77070DD70ULL, 0xD954716FB6B6E2B6ULL, 0xCEB7BD1ED0D067D0ULL, 0x3B7EC7D6EDED93EDULL, -0x2EDB85E2CCCC17CCULL, 0x2A57846842421542ULL, 0xB4C22D2C98985A98ULL, 0x490E55EDA4A4AAA4ULL, -0x5D8850752828A028ULL, 0xDA31B8865C5C6D5CULL, 0x933FED6BF8F8C7F8ULL, 0x44A411C286862286ULL }; - -const u64bit Whirlpool::C5[256] = { -0x18C07830D8181860ULL, 0x2305AF462623238CULL, 0xC67EF991B8C6C63FULL, 0xE8136FCDFBE8E887ULL, -0x874CA113CB878726ULL, 0xB8A9626D11B8B8DAULL, 0x0108050209010104ULL, 0x4F426E9E0D4F4F21ULL, -0x36ADEE6C9B3636D8ULL, 0xA6590451FFA6A6A2ULL, 0xD2DEBDB90CD2D26FULL, 0xF5FB06F70EF5F5F3ULL, -0x79EF80F2967979F9ULL, 0x6F5FCEDE306F6FA1ULL, 0x91FCEF3F6D91917EULL, 0x52AA07A4F8525255ULL, -0x6027FDC04760609DULL, 0xBC89766535BCBCCAULL, 0x9BACCD2B379B9B56ULL, 0x8E048C018A8E8E02ULL, -0xA371155BD2A3A3B6ULL, 0x0C603C186C0C0C30ULL, 0x7BFF8AF6847B7BF1ULL, 0x35B5E16A803535D4ULL, -0x1DE8693AF51D1D74ULL, 0xE05347DDB3E0E0A7ULL, 0xD7F6ACB321D7D77BULL, 0xC25EED999CC2C22FULL, -0x2E6D965C432E2EB8ULL, 0x4B627A96294B4B31ULL, 0xFEA321E15DFEFEDFULL, 0x578216AED5575741ULL, -0x15A8412ABD151554ULL, 0x779FB6EEE87777C1ULL, 0x37A5EB6E923737DCULL, 0xE57B56D79EE5E5B3ULL, -0x9F8CD923139F9F46ULL, 0xF0D317FD23F0F0E7ULL, 0x4A6A7F94204A4A35ULL, 0xDA9E95A944DADA4FULL, -0x58FA25B0A258587DULL, 0xC906CA8FCFC9C903ULL, 0x29558D527C2929A4ULL, 0x0A5022145A0A0A28ULL, -0xB1E14F7F50B1B1FEULL, 0xA0691A5DC9A0A0BAULL, 0x6B7FDAD6146B6BB1ULL, 0x855CAB17D985852EULL, -0xBD8173673CBDBDCEULL, 0x5DD234BA8F5D5D69ULL, 0x1080502090101040ULL, 0xF4F303F507F4F4F7ULL, -0xCB16C08BDDCBCB0BULL, 0x3EEDC67CD33E3EF8ULL, 0x0528110A2D050514ULL, 0x671FE6CE78676781ULL, -0xE47353D597E4E4B7ULL, 0x2725BB4E0227279CULL, 0x4132588273414119ULL, 0x8B2C9D0BA78B8B16ULL, -0xA7510153F6A7A7A6ULL, 0x7DCF94FAB27D7DE9ULL, 0x95DCFB374995956EULL, 0xD88E9FAD56D8D847ULL, -0xFB8B30EB70FBFBCBULL, 0xEE2371C1CDEEEE9FULL, 0x7CC791F8BB7C7CEDULL, 0x6617E3CC71666685ULL, -0xDDA68EA77BDDDD53ULL, 0x17B84B2EAF17175CULL, 0x4702468E45474701ULL, 0x9E84DC211A9E9E42ULL, -0xCA1EC589D4CACA0FULL, 0x2D75995A582D2DB4ULL, 0xBF9179632EBFBFC6ULL, 0x07381B0E3F07071CULL, -0xAD012347ACADAD8EULL, 0x5AEA2FB4B05A5A75ULL, 0x836CB51BEF838336ULL, 0x3385FF66B63333CCULL, -0x633FF2C65C636391ULL, 0x02100A0412020208ULL, 0xAA39384993AAAA92ULL, 0x71AFA8E2DE7171D9ULL, -0xC80ECF8DC6C8C807ULL, 0x19C87D32D1191964ULL, 0x497270923B494939ULL, 0xD9869AAF5FD9D943ULL, -0xF2C31DF931F2F2EFULL, 0xE34B48DBA8E3E3ABULL, 0x5BE22AB6B95B5B71ULL, 0x8834920DBC88881AULL, -0x9AA4C8293E9A9A52ULL, 0x262DBE4C0B262698ULL, 0x328DFA64BF3232C8ULL, 0xB0E94A7D59B0B0FAULL, -0xE91B6ACFF2E9E983ULL, 0x0F78331E770F0F3CULL, 0xD5E6A6B733D5D573ULL, 0x8074BA1DF480803AULL, -0xBE997C6127BEBEC2ULL, 0xCD26DE87EBCDCD13ULL, 0x34BDE468893434D0ULL, 0x487A75903248483DULL, -0xFFAB24E354FFFFDBULL, 0x7AF78FF48D7A7AF5ULL, 0x90F4EA3D6490907AULL, 0x5FC23EBE9D5F5F61ULL, -0x201DA0403D202080ULL, 0x6867D5D00F6868BDULL, 0x1AD07234CA1A1A68ULL, 0xAE192C41B7AEAE82ULL, -0xB4C95E757DB4B4EAULL, 0x549A19A8CE54544DULL, 0x93ECE53B7F939376ULL, 0x220DAA442F222288ULL, -0x6407E9C86364648DULL, 0xF1DB12FF2AF1F1E3ULL, 0x73BFA2E6CC7373D1ULL, 0x12905A2482121248ULL, -0x403A5D807A40401DULL, 0x0840281048080820ULL, 0xC356E89B95C3C32BULL, 0xEC337BC5DFECEC97ULL, -0xDB9690AB4DDBDB4BULL, 0xA1611F5FC0A1A1BEULL, 0x8D1C8307918D8D0EULL, 0x3DF5C97AC83D3DF4ULL, -0x97CCF1335B979766ULL, 0x0000000000000000ULL, 0xCF36D483F9CFCF1BULL, 0x2B4587566E2B2BACULL, -0x7697B3ECE17676C5ULL, 0x8264B019E6828232ULL, 0xD6FEA9B128D6D67FULL, 0x1BD87736C31B1B6CULL, -0xB5C15B7774B5B5EEULL, 0xAF112943BEAFAF86ULL, 0x6A77DFD41D6A6AB5ULL, 0x50BA0DA0EA50505DULL, -0x45124C8A57454509ULL, 0xF3CB18FB38F3F3EBULL, 0x309DF060AD3030C0ULL, 0xEF2B74C3C4EFEF9BULL, -0x3FE5C37EDA3F3FFCULL, 0x55921CAAC7555549ULL, 0xA2791059DBA2A2B2ULL, 0xEA0365C9E9EAEA8FULL, -0x650FECCA6A656589ULL, 0xBAB9686903BABAD2ULL, 0x2F65935E4A2F2FBCULL, 0xC04EE79D8EC0C027ULL, -0xDEBE81A160DEDE5FULL, 0x1CE06C38FC1C1C70ULL, 0xFDBB2EE746FDFDD3ULL, 0x4D52649A1F4D4D29ULL, -0x92E4E03976929272ULL, 0x758FBCEAFA7575C9ULL, 0x06301E0C36060618ULL, 0x8A249809AE8A8A12ULL, -0xB2F940794BB2B2F2ULL, 0xE66359D185E6E6BFULL, 0x0E70361C7E0E0E38ULL, 0x1FF8633EE71F1F7CULL, -0x6237F7C455626295ULL, 0xD4EEA3B53AD4D477ULL, 0xA829324D81A8A89AULL, 0x96C4F43152969662ULL, -0xF99B3AEF62F9F9C3ULL, 0xC566F697A3C5C533ULL, 0x2535B14A10252594ULL, 0x59F220B2AB595979ULL, -0x8454AE15D084842AULL, 0x72B7A7E4C57272D5ULL, 0x39D5DD72EC3939E4ULL, 0x4C5A6198164C4C2DULL, -0x5ECA3BBC945E5E65ULL, 0x78E785F09F7878FDULL, 0x38DDD870E53838E0ULL, 0x8C148605988C8C0AULL, -0xD1C6B2BF17D1D163ULL, 0xA5410B57E4A5A5AEULL, 0xE2434DD9A1E2E2AFULL, 0x612FF8C24E616199ULL, -0xB3F1457B42B3B3F6ULL, 0x2115A54234212184ULL, 0x9C94D625089C9C4AULL, 0x1EF0663CEE1E1E78ULL, -0x4322528661434311ULL, 0xC776FC93B1C7C73BULL, 0xFCB32BE54FFCFCD7ULL, 0x0420140824040410ULL, -0x51B208A2E3515159ULL, 0x99BCC72F2599995EULL, 0x6D4FC4DA226D6DA9ULL, 0x0D68391A650D0D34ULL, -0xFA8335E979FAFACFULL, 0xDFB684A369DFDF5BULL, 0x7ED79BFCA97E7EE5ULL, 0x243DB44819242490ULL, -0x3BC5D776FE3B3BECULL, 0xAB313D4B9AABAB96ULL, 0xCE3ED181F0CECE1FULL, 0x1188552299111144ULL, -0x8F0C8903838F8F06ULL, 0x4E4A6B9C044E4E25ULL, 0xB7D1517366B7B7E6ULL, 0xEB0B60CBE0EBEB8BULL, -0x3CFDCC78C13C3CF0ULL, 0x817CBF1FFD81813EULL, 0x94D4FE354094946AULL, 0xF7EB0CF31CF7F7FBULL, -0xB9A1676F18B9B9DEULL, 0x13985F268B13134CULL, 0x2C7D9C58512C2CB0ULL, 0xD3D6B8BB05D3D36BULL, -0xE76B5CD38CE7E7BBULL, 0x6E57CBDC396E6EA5ULL, 0xC46EF395AAC4C437ULL, 0x03180F061B03030CULL, -0x568A13ACDC565645ULL, 0x441A49885E44440DULL, 0x7FDF9EFEA07F7FE1ULL, 0xA921374F88A9A99EULL, -0x2A4D8254672A2AA8ULL, 0xBBB16D6B0ABBBBD6ULL, 0xC146E29F87C1C123ULL, 0x53A202A6F1535351ULL, -0xDCAE8BA572DCDC57ULL, 0x0B582716530B0B2CULL, 0x9D9CD327019D9D4EULL, 0x6C47C1D82B6C6CADULL, -0x3195F562A43131C4ULL, 0x7487B9E8F37474CDULL, 0xF6E309F115F6F6FFULL, 0x460A438C4C464605ULL, -0xAC092645A5ACAC8AULL, 0x893C970FB589891EULL, 0x14A04428B4141450ULL, 0xE15B42DFBAE1E1A3ULL, -0x16B04E2CA6161658ULL, 0x3ACDD274F73A3AE8ULL, 0x696FD0D2066969B9ULL, 0x09482D1241090924ULL, -0x70A7ADE0D77070DDULL, 0xB6D954716FB6B6E2ULL, 0xD0CEB7BD1ED0D067ULL, 0xED3B7EC7D6EDED93ULL, -0xCC2EDB85E2CCCC17ULL, 0x422A578468424215ULL, 0x98B4C22D2C98985AULL, 0xA4490E55EDA4A4AAULL, -0x285D8850752828A0ULL, 0x5CDA31B8865C5C6DULL, 0xF8933FED6BF8F8C7ULL, 0x8644A411C2868622ULL }; - -const u64bit Whirlpool::C6[256] = { -0x6018C07830D81818ULL, 0x8C2305AF46262323ULL, 0x3FC67EF991B8C6C6ULL, 0x87E8136FCDFBE8E8ULL, -0x26874CA113CB8787ULL, 0xDAB8A9626D11B8B8ULL, 0x0401080502090101ULL, 0x214F426E9E0D4F4FULL, -0xD836ADEE6C9B3636ULL, 0xA2A6590451FFA6A6ULL, 0x6FD2DEBDB90CD2D2ULL, 0xF3F5FB06F70EF5F5ULL, -0xF979EF80F2967979ULL, 0xA16F5FCEDE306F6FULL, 0x7E91FCEF3F6D9191ULL, 0x5552AA07A4F85252ULL, -0x9D6027FDC0476060ULL, 0xCABC89766535BCBCULL, 0x569BACCD2B379B9BULL, 0x028E048C018A8E8EULL, -0xB6A371155BD2A3A3ULL, 0x300C603C186C0C0CULL, 0xF17BFF8AF6847B7BULL, 0xD435B5E16A803535ULL, -0x741DE8693AF51D1DULL, 0xA7E05347DDB3E0E0ULL, 0x7BD7F6ACB321D7D7ULL, 0x2FC25EED999CC2C2ULL, -0xB82E6D965C432E2EULL, 0x314B627A96294B4BULL, 0xDFFEA321E15DFEFEULL, 0x41578216AED55757ULL, -0x5415A8412ABD1515ULL, 0xC1779FB6EEE87777ULL, 0xDC37A5EB6E923737ULL, 0xB3E57B56D79EE5E5ULL, -0x469F8CD923139F9FULL, 0xE7F0D317FD23F0F0ULL, 0x354A6A7F94204A4AULL, 0x4FDA9E95A944DADAULL, -0x7D58FA25B0A25858ULL, 0x03C906CA8FCFC9C9ULL, 0xA429558D527C2929ULL, 0x280A5022145A0A0AULL, -0xFEB1E14F7F50B1B1ULL, 0xBAA0691A5DC9A0A0ULL, 0xB16B7FDAD6146B6BULL, 0x2E855CAB17D98585ULL, -0xCEBD8173673CBDBDULL, 0x695DD234BA8F5D5DULL, 0x4010805020901010ULL, 0xF7F4F303F507F4F4ULL, -0x0BCB16C08BDDCBCBULL, 0xF83EEDC67CD33E3EULL, 0x140528110A2D0505ULL, 0x81671FE6CE786767ULL, -0xB7E47353D597E4E4ULL, 0x9C2725BB4E022727ULL, 0x1941325882734141ULL, 0x168B2C9D0BA78B8BULL, -0xA6A7510153F6A7A7ULL, 0xE97DCF94FAB27D7DULL, 0x6E95DCFB37499595ULL, 0x47D88E9FAD56D8D8ULL, -0xCBFB8B30EB70FBFBULL, 0x9FEE2371C1CDEEEEULL, 0xED7CC791F8BB7C7CULL, 0x856617E3CC716666ULL, -0x53DDA68EA77BDDDDULL, 0x5C17B84B2EAF1717ULL, 0x014702468E454747ULL, 0x429E84DC211A9E9EULL, -0x0FCA1EC589D4CACAULL, 0xB42D75995A582D2DULL, 0xC6BF9179632EBFBFULL, 0x1C07381B0E3F0707ULL, -0x8EAD012347ACADADULL, 0x755AEA2FB4B05A5AULL, 0x36836CB51BEF8383ULL, 0xCC3385FF66B63333ULL, -0x91633FF2C65C6363ULL, 0x0802100A04120202ULL, 0x92AA39384993AAAAULL, 0xD971AFA8E2DE7171ULL, -0x07C80ECF8DC6C8C8ULL, 0x6419C87D32D11919ULL, 0x39497270923B4949ULL, 0x43D9869AAF5FD9D9ULL, -0xEFF2C31DF931F2F2ULL, 0xABE34B48DBA8E3E3ULL, 0x715BE22AB6B95B5BULL, 0x1A8834920DBC8888ULL, -0x529AA4C8293E9A9AULL, 0x98262DBE4C0B2626ULL, 0xC8328DFA64BF3232ULL, 0xFAB0E94A7D59B0B0ULL, -0x83E91B6ACFF2E9E9ULL, 0x3C0F78331E770F0FULL, 0x73D5E6A6B733D5D5ULL, 0x3A8074BA1DF48080ULL, -0xC2BE997C6127BEBEULL, 0x13CD26DE87EBCDCDULL, 0xD034BDE468893434ULL, 0x3D487A7590324848ULL, -0xDBFFAB24E354FFFFULL, 0xF57AF78FF48D7A7AULL, 0x7A90F4EA3D649090ULL, 0x615FC23EBE9D5F5FULL, -0x80201DA0403D2020ULL, 0xBD6867D5D00F6868ULL, 0x681AD07234CA1A1AULL, 0x82AE192C41B7AEAEULL, -0xEAB4C95E757DB4B4ULL, 0x4D549A19A8CE5454ULL, 0x7693ECE53B7F9393ULL, 0x88220DAA442F2222ULL, -0x8D6407E9C8636464ULL, 0xE3F1DB12FF2AF1F1ULL, 0xD173BFA2E6CC7373ULL, 0x4812905A24821212ULL, -0x1D403A5D807A4040ULL, 0x2008402810480808ULL, 0x2BC356E89B95C3C3ULL, 0x97EC337BC5DFECECULL, -0x4BDB9690AB4DDBDBULL, 0xBEA1611F5FC0A1A1ULL, 0x0E8D1C8307918D8DULL, 0xF43DF5C97AC83D3DULL, -0x6697CCF1335B9797ULL, 0x0000000000000000ULL, 0x1BCF36D483F9CFCFULL, 0xAC2B4587566E2B2BULL, -0xC57697B3ECE17676ULL, 0x328264B019E68282ULL, 0x7FD6FEA9B128D6D6ULL, 0x6C1BD87736C31B1BULL, -0xEEB5C15B7774B5B5ULL, 0x86AF112943BEAFAFULL, 0xB56A77DFD41D6A6AULL, 0x5D50BA0DA0EA5050ULL, -0x0945124C8A574545ULL, 0xEBF3CB18FB38F3F3ULL, 0xC0309DF060AD3030ULL, 0x9BEF2B74C3C4EFEFULL, -0xFC3FE5C37EDA3F3FULL, 0x4955921CAAC75555ULL, 0xB2A2791059DBA2A2ULL, 0x8FEA0365C9E9EAEAULL, -0x89650FECCA6A6565ULL, 0xD2BAB9686903BABAULL, 0xBC2F65935E4A2F2FULL, 0x27C04EE79D8EC0C0ULL, -0x5FDEBE81A160DEDEULL, 0x701CE06C38FC1C1CULL, 0xD3FDBB2EE746FDFDULL, 0x294D52649A1F4D4DULL, -0x7292E4E039769292ULL, 0xC9758FBCEAFA7575ULL, 0x1806301E0C360606ULL, 0x128A249809AE8A8AULL, -0xF2B2F940794BB2B2ULL, 0xBFE66359D185E6E6ULL, 0x380E70361C7E0E0EULL, 0x7C1FF8633EE71F1FULL, -0x956237F7C4556262ULL, 0x77D4EEA3B53AD4D4ULL, 0x9AA829324D81A8A8ULL, 0x6296C4F431529696ULL, -0xC3F99B3AEF62F9F9ULL, 0x33C566F697A3C5C5ULL, 0x942535B14A102525ULL, 0x7959F220B2AB5959ULL, -0x2A8454AE15D08484ULL, 0xD572B7A7E4C57272ULL, 0xE439D5DD72EC3939ULL, 0x2D4C5A6198164C4CULL, -0x655ECA3BBC945E5EULL, 0xFD78E785F09F7878ULL, 0xE038DDD870E53838ULL, 0x0A8C148605988C8CULL, -0x63D1C6B2BF17D1D1ULL, 0xAEA5410B57E4A5A5ULL, 0xAFE2434DD9A1E2E2ULL, 0x99612FF8C24E6161ULL, -0xF6B3F1457B42B3B3ULL, 0x842115A542342121ULL, 0x4A9C94D625089C9CULL, 0x781EF0663CEE1E1EULL, -0x1143225286614343ULL, 0x3BC776FC93B1C7C7ULL, 0xD7FCB32BE54FFCFCULL, 0x1004201408240404ULL, -0x5951B208A2E35151ULL, 0x5E99BCC72F259999ULL, 0xA96D4FC4DA226D6DULL, 0x340D68391A650D0DULL, -0xCFFA8335E979FAFAULL, 0x5BDFB684A369DFDFULL, 0xE57ED79BFCA97E7EULL, 0x90243DB448192424ULL, -0xEC3BC5D776FE3B3BULL, 0x96AB313D4B9AABABULL, 0x1FCE3ED181F0CECEULL, 0x4411885522991111ULL, -0x068F0C8903838F8FULL, 0x254E4A6B9C044E4EULL, 0xE6B7D1517366B7B7ULL, 0x8BEB0B60CBE0EBEBULL, -0xF03CFDCC78C13C3CULL, 0x3E817CBF1FFD8181ULL, 0x6A94D4FE35409494ULL, 0xFBF7EB0CF31CF7F7ULL, -0xDEB9A1676F18B9B9ULL, 0x4C13985F268B1313ULL, 0xB02C7D9C58512C2CULL, 0x6BD3D6B8BB05D3D3ULL, -0xBBE76B5CD38CE7E7ULL, 0xA56E57CBDC396E6EULL, 0x37C46EF395AAC4C4ULL, 0x0C03180F061B0303ULL, -0x45568A13ACDC5656ULL, 0x0D441A49885E4444ULL, 0xE17FDF9EFEA07F7FULL, 0x9EA921374F88A9A9ULL, -0xA82A4D8254672A2AULL, 0xD6BBB16D6B0ABBBBULL, 0x23C146E29F87C1C1ULL, 0x5153A202A6F15353ULL, -0x57DCAE8BA572DCDCULL, 0x2C0B582716530B0BULL, 0x4E9D9CD327019D9DULL, 0xAD6C47C1D82B6C6CULL, -0xC43195F562A43131ULL, 0xCD7487B9E8F37474ULL, 0xFFF6E309F115F6F6ULL, 0x05460A438C4C4646ULL, -0x8AAC092645A5ACACULL, 0x1E893C970FB58989ULL, 0x5014A04428B41414ULL, 0xA3E15B42DFBAE1E1ULL, -0x5816B04E2CA61616ULL, 0xE83ACDD274F73A3AULL, 0xB9696FD0D2066969ULL, 0x2409482D12410909ULL, -0xDD70A7ADE0D77070ULL, 0xE2B6D954716FB6B6ULL, 0x67D0CEB7BD1ED0D0ULL, 0x93ED3B7EC7D6EDEDULL, -0x17CC2EDB85E2CCCCULL, 0x15422A5784684242ULL, 0x5A98B4C22D2C9898ULL, 0xAAA4490E55EDA4A4ULL, -0xA0285D8850752828ULL, 0x6D5CDA31B8865C5CULL, 0xC7F8933FED6BF8F8ULL, 0x228644A411C28686ULL }; - -const u64bit Whirlpool::C7[256] = { -0x186018C07830D818ULL, 0x238C2305AF462623ULL, 0xC63FC67EF991B8C6ULL, 0xE887E8136FCDFBE8ULL, -0x8726874CA113CB87ULL, 0xB8DAB8A9626D11B8ULL, 0x0104010805020901ULL, 0x4F214F426E9E0D4FULL, -0x36D836ADEE6C9B36ULL, 0xA6A2A6590451FFA6ULL, 0xD26FD2DEBDB90CD2ULL, 0xF5F3F5FB06F70EF5ULL, -0x79F979EF80F29679ULL, 0x6FA16F5FCEDE306FULL, 0x917E91FCEF3F6D91ULL, 0x525552AA07A4F852ULL, -0x609D6027FDC04760ULL, 0xBCCABC89766535BCULL, 0x9B569BACCD2B379BULL, 0x8E028E048C018A8EULL, -0xA3B6A371155BD2A3ULL, 0x0C300C603C186C0CULL, 0x7BF17BFF8AF6847BULL, 0x35D435B5E16A8035ULL, -0x1D741DE8693AF51DULL, 0xE0A7E05347DDB3E0ULL, 0xD77BD7F6ACB321D7ULL, 0xC22FC25EED999CC2ULL, -0x2EB82E6D965C432EULL, 0x4B314B627A96294BULL, 0xFEDFFEA321E15DFEULL, 0x5741578216AED557ULL, -0x155415A8412ABD15ULL, 0x77C1779FB6EEE877ULL, 0x37DC37A5EB6E9237ULL, 0xE5B3E57B56D79EE5ULL, -0x9F469F8CD923139FULL, 0xF0E7F0D317FD23F0ULL, 0x4A354A6A7F94204AULL, 0xDA4FDA9E95A944DAULL, -0x587D58FA25B0A258ULL, 0xC903C906CA8FCFC9ULL, 0x29A429558D527C29ULL, 0x0A280A5022145A0AULL, -0xB1FEB1E14F7F50B1ULL, 0xA0BAA0691A5DC9A0ULL, 0x6BB16B7FDAD6146BULL, 0x852E855CAB17D985ULL, -0xBDCEBD8173673CBDULL, 0x5D695DD234BA8F5DULL, 0x1040108050209010ULL, 0xF4F7F4F303F507F4ULL, -0xCB0BCB16C08BDDCBULL, 0x3EF83EEDC67CD33EULL, 0x05140528110A2D05ULL, 0x6781671FE6CE7867ULL, -0xE4B7E47353D597E4ULL, 0x279C2725BB4E0227ULL, 0x4119413258827341ULL, 0x8B168B2C9D0BA78BULL, -0xA7A6A7510153F6A7ULL, 0x7DE97DCF94FAB27DULL, 0x956E95DCFB374995ULL, 0xD847D88E9FAD56D8ULL, -0xFBCBFB8B30EB70FBULL, 0xEE9FEE2371C1CDEEULL, 0x7CED7CC791F8BB7CULL, 0x66856617E3CC7166ULL, -0xDD53DDA68EA77BDDULL, 0x175C17B84B2EAF17ULL, 0x47014702468E4547ULL, 0x9E429E84DC211A9EULL, -0xCA0FCA1EC589D4CAULL, 0x2DB42D75995A582DULL, 0xBFC6BF9179632EBFULL, 0x071C07381B0E3F07ULL, -0xAD8EAD012347ACADULL, 0x5A755AEA2FB4B05AULL, 0x8336836CB51BEF83ULL, 0x33CC3385FF66B633ULL, -0x6391633FF2C65C63ULL, 0x020802100A041202ULL, 0xAA92AA39384993AAULL, 0x71D971AFA8E2DE71ULL, -0xC807C80ECF8DC6C8ULL, 0x196419C87D32D119ULL, 0x4939497270923B49ULL, 0xD943D9869AAF5FD9ULL, -0xF2EFF2C31DF931F2ULL, 0xE3ABE34B48DBA8E3ULL, 0x5B715BE22AB6B95BULL, 0x881A8834920DBC88ULL, -0x9A529AA4C8293E9AULL, 0x2698262DBE4C0B26ULL, 0x32C8328DFA64BF32ULL, 0xB0FAB0E94A7D59B0ULL, -0xE983E91B6ACFF2E9ULL, 0x0F3C0F78331E770FULL, 0xD573D5E6A6B733D5ULL, 0x803A8074BA1DF480ULL, -0xBEC2BE997C6127BEULL, 0xCD13CD26DE87EBCDULL, 0x34D034BDE4688934ULL, 0x483D487A75903248ULL, -0xFFDBFFAB24E354FFULL, 0x7AF57AF78FF48D7AULL, 0x907A90F4EA3D6490ULL, 0x5F615FC23EBE9D5FULL, -0x2080201DA0403D20ULL, 0x68BD6867D5D00F68ULL, 0x1A681AD07234CA1AULL, 0xAE82AE192C41B7AEULL, -0xB4EAB4C95E757DB4ULL, 0x544D549A19A8CE54ULL, 0x937693ECE53B7F93ULL, 0x2288220DAA442F22ULL, -0x648D6407E9C86364ULL, 0xF1E3F1DB12FF2AF1ULL, 0x73D173BFA2E6CC73ULL, 0x124812905A248212ULL, -0x401D403A5D807A40ULL, 0x0820084028104808ULL, 0xC32BC356E89B95C3ULL, 0xEC97EC337BC5DFECULL, -0xDB4BDB9690AB4DDBULL, 0xA1BEA1611F5FC0A1ULL, 0x8D0E8D1C8307918DULL, 0x3DF43DF5C97AC83DULL, -0x976697CCF1335B97ULL, 0x0000000000000000ULL, 0xCF1BCF36D483F9CFULL, 0x2BAC2B4587566E2BULL, -0x76C57697B3ECE176ULL, 0x82328264B019E682ULL, 0xD67FD6FEA9B128D6ULL, 0x1B6C1BD87736C31BULL, -0xB5EEB5C15B7774B5ULL, 0xAF86AF112943BEAFULL, 0x6AB56A77DFD41D6AULL, 0x505D50BA0DA0EA50ULL, -0x450945124C8A5745ULL, 0xF3EBF3CB18FB38F3ULL, 0x30C0309DF060AD30ULL, 0xEF9BEF2B74C3C4EFULL, -0x3FFC3FE5C37EDA3FULL, 0x554955921CAAC755ULL, 0xA2B2A2791059DBA2ULL, 0xEA8FEA0365C9E9EAULL, -0x6589650FECCA6A65ULL, 0xBAD2BAB9686903BAULL, 0x2FBC2F65935E4A2FULL, 0xC027C04EE79D8EC0ULL, -0xDE5FDEBE81A160DEULL, 0x1C701CE06C38FC1CULL, 0xFDD3FDBB2EE746FDULL, 0x4D294D52649A1F4DULL, -0x927292E4E0397692ULL, 0x75C9758FBCEAFA75ULL, 0x061806301E0C3606ULL, 0x8A128A249809AE8AULL, -0xB2F2B2F940794BB2ULL, 0xE6BFE66359D185E6ULL, 0x0E380E70361C7E0EULL, 0x1F7C1FF8633EE71FULL, -0x62956237F7C45562ULL, 0xD477D4EEA3B53AD4ULL, 0xA89AA829324D81A8ULL, 0x966296C4F4315296ULL, -0xF9C3F99B3AEF62F9ULL, 0xC533C566F697A3C5ULL, 0x25942535B14A1025ULL, 0x597959F220B2AB59ULL, -0x842A8454AE15D084ULL, 0x72D572B7A7E4C572ULL, 0x39E439D5DD72EC39ULL, 0x4C2D4C5A6198164CULL, -0x5E655ECA3BBC945EULL, 0x78FD78E785F09F78ULL, 0x38E038DDD870E538ULL, 0x8C0A8C148605988CULL, -0xD163D1C6B2BF17D1ULL, 0xA5AEA5410B57E4A5ULL, 0xE2AFE2434DD9A1E2ULL, 0x6199612FF8C24E61ULL, -0xB3F6B3F1457B42B3ULL, 0x21842115A5423421ULL, 0x9C4A9C94D625089CULL, 0x1E781EF0663CEE1EULL, -0x4311432252866143ULL, 0xC73BC776FC93B1C7ULL, 0xFCD7FCB32BE54FFCULL, 0x0410042014082404ULL, -0x515951B208A2E351ULL, 0x995E99BCC72F2599ULL, 0x6DA96D4FC4DA226DULL, 0x0D340D68391A650DULL, -0xFACFFA8335E979FAULL, 0xDF5BDFB684A369DFULL, 0x7EE57ED79BFCA97EULL, 0x2490243DB4481924ULL, -0x3BEC3BC5D776FE3BULL, 0xAB96AB313D4B9AABULL, 0xCE1FCE3ED181F0CEULL, 0x1144118855229911ULL, -0x8F068F0C8903838FULL, 0x4E254E4A6B9C044EULL, 0xB7E6B7D1517366B7ULL, 0xEB8BEB0B60CBE0EBULL, -0x3CF03CFDCC78C13CULL, 0x813E817CBF1FFD81ULL, 0x946A94D4FE354094ULL, 0xF7FBF7EB0CF31CF7ULL, -0xB9DEB9A1676F18B9ULL, 0x134C13985F268B13ULL, 0x2CB02C7D9C58512CULL, 0xD36BD3D6B8BB05D3ULL, -0xE7BBE76B5CD38CE7ULL, 0x6EA56E57CBDC396EULL, 0xC437C46EF395AAC4ULL, 0x030C03180F061B03ULL, -0x5645568A13ACDC56ULL, 0x440D441A49885E44ULL, 0x7FE17FDF9EFEA07FULL, 0xA99EA921374F88A9ULL, -0x2AA82A4D8254672AULL, 0xBBD6BBB16D6B0ABBULL, 0xC123C146E29F87C1ULL, 0x535153A202A6F153ULL, -0xDC57DCAE8BA572DCULL, 0x0B2C0B582716530BULL, 0x9D4E9D9CD327019DULL, 0x6CAD6C47C1D82B6CULL, -0x31C43195F562A431ULL, 0x74CD7487B9E8F374ULL, 0xF6FFF6E309F115F6ULL, 0x4605460A438C4C46ULL, -0xAC8AAC092645A5ACULL, 0x891E893C970FB589ULL, 0x145014A04428B414ULL, 0xE1A3E15B42DFBAE1ULL, -0x165816B04E2CA616ULL, 0x3AE83ACDD274F73AULL, 0x69B9696FD0D20669ULL, 0x092409482D124109ULL, -0x70DD70A7ADE0D770ULL, 0xB6E2B6D954716FB6ULL, 0xD067D0CEB7BD1ED0ULL, 0xED93ED3B7EC7D6EDULL, -0xCC17CC2EDB85E2CCULL, 0x4215422A57846842ULL, 0x985A98B4C22D2C98ULL, 0xA4AAA4490E55EDA4ULL, -0x28A0285D88507528ULL, 0x5C6D5CDA31B8865CULL, 0xF8C7F8933FED6BF8ULL, 0x86228644A411C286ULL }; - -} -/* -* Whirlpool -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -/* -* Whirlpool Compression Function -*/ -void Whirlpool::compress_n(const byte in[], size_t blocks) - { - static const u64bit RC[10] = { - 0x1823C6E887B8014FULL, 0x36A6D2F5796F9152ULL, - 0x60BC9B8EA30C7B35ULL, 0x1DE0D7C22E4BFE57ULL, - 0x157737E59FF04ADAULL, 0x58C9290AB1A06B85ULL, - 0xBD5D10F4CB3E0567ULL, 0xE427418BA77D95D8ULL, - 0xFBEE7C66DD17479EULL, 0xCA2DBF07AD5A8333ULL - }; - - for(size_t i = 0; i != blocks; ++i) - { - load_be(&M[0], in, M.size()); - - u64bit K0, K1, K2, K3, K4, K5, K6, K7; - K0 = digest[0]; K1 = digest[1]; K2 = digest[2]; K3 = digest[3]; - K4 = digest[4]; K5 = digest[5]; K6 = digest[6]; K7 = digest[7]; - - u64bit B0, B1, B2, B3, B4, B5, B6, B7; - B0 = K0 ^ M[0]; B1 = K1 ^ M[1]; B2 = K2 ^ M[2]; B3 = K3 ^ M[3]; - B4 = K4 ^ M[4]; B5 = K5 ^ M[5]; B6 = K6 ^ M[6]; B7 = K7 ^ M[7]; - - for(size_t j = 0; j != 10; ++j) - { - u64bit T0, T1, T2, T3, T4, T5, T6, T7; - T0 = C0[get_byte(0, K0)] ^ C1[get_byte(1, K7)] ^ - C2[get_byte(2, K6)] ^ C3[get_byte(3, K5)] ^ - C4[get_byte(4, K4)] ^ C5[get_byte(5, K3)] ^ - C6[get_byte(6, K2)] ^ C7[get_byte(7, K1)] ^ RC[j]; - T1 = C0[get_byte(0, K1)] ^ C1[get_byte(1, K0)] ^ - C2[get_byte(2, K7)] ^ C3[get_byte(3, K6)] ^ - C4[get_byte(4, K5)] ^ C5[get_byte(5, K4)] ^ - C6[get_byte(6, K3)] ^ C7[get_byte(7, K2)]; - T2 = C0[get_byte(0, K2)] ^ C1[get_byte(1, K1)] ^ - C2[get_byte(2, K0)] ^ C3[get_byte(3, K7)] ^ - C4[get_byte(4, K6)] ^ C5[get_byte(5, K5)] ^ - C6[get_byte(6, K4)] ^ C7[get_byte(7, K3)]; - T3 = C0[get_byte(0, K3)] ^ C1[get_byte(1, K2)] ^ - C2[get_byte(2, K1)] ^ C3[get_byte(3, K0)] ^ - C4[get_byte(4, K7)] ^ C5[get_byte(5, K6)] ^ - C6[get_byte(6, K5)] ^ C7[get_byte(7, K4)]; - T4 = C0[get_byte(0, K4)] ^ C1[get_byte(1, K3)] ^ - C2[get_byte(2, K2)] ^ C3[get_byte(3, K1)] ^ - C4[get_byte(4, K0)] ^ C5[get_byte(5, K7)] ^ - C6[get_byte(6, K6)] ^ C7[get_byte(7, K5)]; - T5 = C0[get_byte(0, K5)] ^ C1[get_byte(1, K4)] ^ - C2[get_byte(2, K3)] ^ C3[get_byte(3, K2)] ^ - C4[get_byte(4, K1)] ^ C5[get_byte(5, K0)] ^ - C6[get_byte(6, K7)] ^ C7[get_byte(7, K6)]; - T6 = C0[get_byte(0, K6)] ^ C1[get_byte(1, K5)] ^ - C2[get_byte(2, K4)] ^ C3[get_byte(3, K3)] ^ - C4[get_byte(4, K2)] ^ C5[get_byte(5, K1)] ^ - C6[get_byte(6, K0)] ^ C7[get_byte(7, K7)]; - T7 = C0[get_byte(0, K7)] ^ C1[get_byte(1, K6)] ^ - C2[get_byte(2, K5)] ^ C3[get_byte(3, K4)] ^ - C4[get_byte(4, K3)] ^ C5[get_byte(5, K2)] ^ - C6[get_byte(6, K1)] ^ C7[get_byte(7, K0)]; - - K0 = T0; K1 = T1; K2 = T2; K3 = T3; - K4 = T4; K5 = T5; K6 = T6; K7 = T7; - - T0 = C0[get_byte(0, B0)] ^ C1[get_byte(1, B7)] ^ - C2[get_byte(2, B6)] ^ C3[get_byte(3, B5)] ^ - C4[get_byte(4, B4)] ^ C5[get_byte(5, B3)] ^ - C6[get_byte(6, B2)] ^ C7[get_byte(7, B1)] ^ K0; - T1 = C0[get_byte(0, B1)] ^ C1[get_byte(1, B0)] ^ - C2[get_byte(2, B7)] ^ C3[get_byte(3, B6)] ^ - C4[get_byte(4, B5)] ^ C5[get_byte(5, B4)] ^ - C6[get_byte(6, B3)] ^ C7[get_byte(7, B2)] ^ K1; - T2 = C0[get_byte(0, B2)] ^ C1[get_byte(1, B1)] ^ - C2[get_byte(2, B0)] ^ C3[get_byte(3, B7)] ^ - C4[get_byte(4, B6)] ^ C5[get_byte(5, B5)] ^ - C6[get_byte(6, B4)] ^ C7[get_byte(7, B3)] ^ K2; - T3 = C0[get_byte(0, B3)] ^ C1[get_byte(1, B2)] ^ - C2[get_byte(2, B1)] ^ C3[get_byte(3, B0)] ^ - C4[get_byte(4, B7)] ^ C5[get_byte(5, B6)] ^ - C6[get_byte(6, B5)] ^ C7[get_byte(7, B4)] ^ K3; - T4 = C0[get_byte(0, B4)] ^ C1[get_byte(1, B3)] ^ - C2[get_byte(2, B2)] ^ C3[get_byte(3, B1)] ^ - C4[get_byte(4, B0)] ^ C5[get_byte(5, B7)] ^ - C6[get_byte(6, B6)] ^ C7[get_byte(7, B5)] ^ K4; - T5 = C0[get_byte(0, B5)] ^ C1[get_byte(1, B4)] ^ - C2[get_byte(2, B3)] ^ C3[get_byte(3, B2)] ^ - C4[get_byte(4, B1)] ^ C5[get_byte(5, B0)] ^ - C6[get_byte(6, B7)] ^ C7[get_byte(7, B6)] ^ K5; - T6 = C0[get_byte(0, B6)] ^ C1[get_byte(1, B5)] ^ - C2[get_byte(2, B4)] ^ C3[get_byte(3, B3)] ^ - C4[get_byte(4, B2)] ^ C5[get_byte(5, B1)] ^ - C6[get_byte(6, B0)] ^ C7[get_byte(7, B7)] ^ K6; - T7 = C0[get_byte(0, B7)] ^ C1[get_byte(1, B6)] ^ - C2[get_byte(2, B5)] ^ C3[get_byte(3, B4)] ^ - C4[get_byte(4, B3)] ^ C5[get_byte(5, B2)] ^ - C6[get_byte(6, B1)] ^ C7[get_byte(7, B0)] ^ K7; - - B0 = T0; B1 = T1; B2 = T2; B3 = T3; - B4 = T4; B5 = T5; B6 = T6; B7 = T7; - } - - digest[0] ^= B0 ^ M[0]; - digest[1] ^= B1 ^ M[1]; - digest[2] ^= B2 ^ M[2]; - digest[3] ^= B3 ^ M[3]; - digest[4] ^= B4 ^ M[4]; - digest[5] ^= B5 ^ M[5]; - digest[6] ^= B6 ^ M[6]; - digest[7] ^= B7 ^ M[7]; - - in += hash_block_size(); - } - } - -/* -* Copy out the digest -*/ -void Whirlpool::copy_out(byte output[]) - { - for(size_t i = 0; i != output_length(); i += 8) - store_be(digest[i/8], output + i); - } - -/* -* Clear memory of sensitive data -*/ -void Whirlpool::clear() - { - MDx_HashFunction::clear(); - zeroise(M); - zeroise(digest); - } - -} -/* -* KDF Base Class -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -/* -* Derive a key -*/ -SecureVector KDF::derive_key(size_t key_len, - const MemoryRegion& secret, - const std::string& salt) const - { - return derive_key(key_len, &secret[0], secret.size(), - reinterpret_cast(salt.data()), - salt.length()); - } - -/* -* Derive a key -*/ -SecureVector KDF::derive_key(size_t key_len, - const MemoryRegion& secret, - const byte salt[], size_t salt_len) const - { - return derive_key(key_len, &secret[0], secret.size(), - salt, salt_len); - } - -/* -* Derive a key -*/ -SecureVector KDF::derive_key(size_t key_len, - const MemoryRegion& secret, - const MemoryRegion& salt) const - { - return derive_key(key_len, &secret[0], secret.size(), - &salt[0], salt.size()); - } - -/* -* Derive a key -*/ -SecureVector KDF::derive_key(size_t key_len, - const byte secret[], size_t secret_len, - const std::string& salt) const - { - return derive_key(key_len, secret, secret_len, - reinterpret_cast(salt.data()), - salt.length()); - } - -/* -* Derive a key -*/ -SecureVector KDF::derive_key(size_t key_len, - const byte secret[], size_t secret_len, - const byte salt[], size_t salt_len) const - { - return derive(key_len, secret, secret_len, salt, salt_len); - } - -} -/* -* KDF1 -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -/* -* KDF1 Key Derivation Mechanism -*/ -SecureVector KDF1::derive(size_t, - const byte secret[], size_t secret_len, - const byte P[], size_t P_len) const - { - hash->update(secret, secret_len); - hash->update(P, P_len); - return hash->final(); - } - -} -/* -* KDF2 -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -/* -* KDF2 Key Derivation Mechanism -*/ -SecureVector KDF2::derive(size_t out_len, - const byte secret[], size_t secret_len, - const byte P[], size_t P_len) const - { - SecureVector output; - u32bit counter = 1; - - while(out_len && counter) - { - hash->update(secret, secret_len); - hash->update_be(counter); - hash->update(P, P_len); - - SecureVector hash_result = hash->final(); - - size_t added = std::min(hash_result.size(), out_len); - output += std::make_pair(&hash_result[0], added); - out_len -= added; - - ++counter; - } - - return output; - } - -} -/* -* MGF1 -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include -#include - -namespace Botan { - -/* -* MGF1 Mask Generation Function -*/ -void MGF1::mask(const byte in[], size_t in_len, byte out[], - size_t out_len) const - { - u32bit counter = 0; - - while(out_len) - { - hash->update(in, in_len); - hash->update_be(counter); - SecureVector buffer = hash->final(); - - size_t xored = std::min(buffer.size(), out_len); - xor_buf(out, &buffer[0], xored); - out += xored; - out_len -= xored; - - ++counter; - } - } - -/* -* MGF1 Constructor -*/ -MGF1::MGF1(HashFunction* h) : hash(h) - { - if(!hash) - throw Invalid_Argument("MGF1 given null hash object"); - } - -/* -* MGF1 Destructor -*/ -MGF1::~MGF1() - { - delete hash; - } - -} -/* -* SSLv3 PRF -* (C) 2004-2006 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include - -namespace Botan { - -namespace { - -/* -* Return the next inner hash -*/ -OctetString next_hash(size_t where, size_t want, - HashFunction& md5, HashFunction& sha1, - const byte secret[], size_t secret_len, - const byte seed[], size_t seed_len) - { - BOTAN_ASSERT(want <= md5.output_length(), "Desired output too large"); - - const byte ASCII_A_CHAR = 0x41; - - for(size_t j = 0; j != where + 1; j++) - sha1.update(static_cast(ASCII_A_CHAR + where)); - sha1.update(secret, secret_len); - sha1.update(seed, seed_len); - SecureVector sha1_hash = sha1.final(); - - md5.update(secret, secret_len); - md5.update(sha1_hash); - SecureVector md5_hash = md5.final(); - - return OctetString(&md5_hash[0], want); - } - -} - -/* -* SSL3 PRF -*/ -SecureVector SSL3_PRF::derive(size_t key_len, - const byte secret[], size_t secret_len, - const byte seed[], size_t seed_len) const - { - if(key_len > 416) - throw Invalid_Argument("SSL3_PRF: Requested key length is too large"); - - MD5 md5; - SHA_160 sha1; - - OctetString output; - - int counter = 0; - while(key_len) - { - const size_t produce = std::min(key_len, md5.output_length()); - - output = output + next_hash(counter++, produce, md5, sha1, - secret, secret_len, seed, seed_len); - - key_len -= produce; - } - - return output.bits_of(); - } - -} -/* -* TLS v1.0 and v1.2 PRFs -* (C) 2004-2010 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -namespace { - -/* -* TLS PRF P_hash function -*/ -void P_hash(MemoryRegion& output, - MessageAuthenticationCode* mac, - const byte secret[], size_t secret_len, - const byte seed[], size_t seed_len) - { - mac->set_key(secret, secret_len); - - SecureVector A(seed, seed_len); - - size_t offset = 0; - - while(offset != output.size()) - { - const size_t this_block_len = - std::min(mac->output_length(), output.size() - offset); - - A = mac->process(A); - - mac->update(A); - mac->update(seed, seed_len); - SecureVector block = mac->final(); - - xor_buf(&output[offset], &block[0], this_block_len); - offset += this_block_len; - } - } - -} - -/* -* TLS PRF Constructor and Destructor -*/ -TLS_PRF::TLS_PRF() - { - hmac_md5 = new HMAC(new MD5); - hmac_sha1 = new HMAC(new SHA_160); - } - -TLS_PRF::~TLS_PRF() - { - delete hmac_md5; - delete hmac_sha1; - } - -/* -* TLS PRF -*/ -SecureVector TLS_PRF::derive(size_t key_len, - const byte secret[], size_t secret_len, - const byte seed[], size_t seed_len) const - { - SecureVector output(key_len); - - size_t S1_len = (secret_len + 1) / 2, - S2_len = (secret_len + 1) / 2; - const byte* S1 = secret; - const byte* S2 = secret + (secret_len - S2_len); - - P_hash(output, hmac_md5, S1, S1_len, seed, seed_len); - P_hash(output, hmac_sha1, S2, S2_len, seed, seed_len); - - return output; - } - -/* -* TLS v1.2 PRF Constructor and Destructor -*/ -TLS_12_PRF::TLS_12_PRF(MessageAuthenticationCode* mac) : hmac(mac) - { - } - -TLS_12_PRF::~TLS_12_PRF() - { - delete hmac; - } - -SecureVector TLS_12_PRF::derive(size_t key_len, - const byte secret[], size_t secret_len, - const byte seed[], size_t seed_len) const - { - SecureVector output(key_len); - - P_hash(output, hmac, secret, secret_len, seed, seed_len); - - return output; - } - -} -/* -* X9.42 PRF -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include -#include - -namespace Botan { - -namespace { - -/* -* Encode an integer as an OCTET STRING -*/ -MemoryVector encode_x942_int(u32bit n) - { - byte n_buf[4] = { 0 }; - store_be(n, n_buf); - return DER_Encoder().encode(n_buf, 4, OCTET_STRING).get_contents(); - } - -} - -/* -* X9.42 PRF -*/ -SecureVector X942_PRF::derive(size_t key_len, - const byte secret[], size_t secret_len, - const byte salt[], size_t salt_len) const - { - SHA_160 hash; - const OID kek_algo(key_wrap_oid); - - SecureVector key; - u32bit counter = 1; - - while(key.size() != key_len && counter) - { - hash.update(secret, secret_len); - - hash.update( - DER_Encoder().start_cons(SEQUENCE) - - .start_cons(SEQUENCE) - .encode(kek_algo) - .raw_bytes(encode_x942_int(counter)) - .end_cons() - - .encode_if(salt_len != 0, - DER_Encoder() - .start_explicit(0) - .encode(salt, salt_len, OCTET_STRING) - .end_explicit() - ) - - .start_explicit(2) - .raw_bytes(encode_x942_int(static_cast(8 * key_len))) - .end_explicit() - - .end_cons().get_contents() - ); - - SecureVector digest = hash.final(); - const size_t needed = std::min(digest.size(), key_len - key.size()); - key += std::make_pair(&digest[0], needed); - - ++counter; - } - - return key; - } - -/* -* X9.42 Constructor -*/ -X942_PRF::X942_PRF(const std::string& oid) - { - if(OIDS::have_oid(oid)) - key_wrap_oid = OIDS::lookup(oid).as_string(); - else - key_wrap_oid = oid; - } - -} -/* -* PBKDF/EMSA/EME/KDF/MGF Retrieval -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -#if defined(BOTAN_HAS_MGF1) -#endif - -#if defined(BOTAN_HAS_EMSA1) -#endif - -#if defined(BOTAN_HAS_EMSA1_BSI) -#endif - -#if defined(BOTAN_HAS_EMSA2) -#endif - -#if defined(BOTAN_HAS_EMSA3) -#endif - -#if defined(BOTAN_HAS_EMSA4) -#endif - -#if defined(BOTAN_HAS_EMSA_RAW) -#endif - -#if defined(BOTAN_HAS_EME1) -#endif - -#if defined(BOTAN_HAS_EME_PKCS1v15) -#endif - -#if defined(BOTAN_HAS_KDF1) -#endif - -#if defined(BOTAN_HAS_KDF2) -#endif - -#if defined(BOTAN_HAS_X942_PRF) -#endif - -#if defined(BOTAN_HAS_SSL_V3_PRF) -#endif - -#if defined(BOTAN_HAS_TLS_V10_PRF) -#endif - -namespace Botan { - -/* -* Get a PBKDF algorithm by name -*/ -PBKDF* get_pbkdf(const std::string& algo_spec) - { - Algorithm_Factory& af = global_state().algorithm_factory(); - - if(PBKDF* pbkdf = af.make_pbkdf(algo_spec)) - return pbkdf; - - throw Algorithm_Not_Found(algo_spec); - } - -/* -* Get an EMSA by name -*/ -EMSA* get_emsa(const std::string& algo_spec) - { - SCAN_Name request(algo_spec); - - Algorithm_Factory& af = global_state().algorithm_factory(); - -#if defined(BOTAN_HAS_EMSA_RAW) - if(request.algo_name() == "Raw" && request.arg_count() == 0) - return new EMSA_Raw; -#endif - -#if defined(BOTAN_HAS_EMSA1) - if(request.algo_name() == "EMSA1" && request.arg_count() == 1) - return new EMSA1(af.make_hash_function(request.arg(0))); -#endif - -#if defined(BOTAN_HAS_EMSA1_BSI) - if(request.algo_name() == "EMSA1_BSI" && request.arg_count() == 1) - return new EMSA1_BSI(af.make_hash_function(request.arg(0))); -#endif - -#if defined(BOTAN_HAS_EMSA2) - if(request.algo_name() == "EMSA2" && request.arg_count() == 1) - return new EMSA2(af.make_hash_function(request.arg(0))); -#endif - -#if defined(BOTAN_HAS_EMSA3) - if(request.algo_name() == "EMSA3" && request.arg_count() == 1) - { - if(request.arg(0) == "Raw") - return new EMSA3_Raw; - return new EMSA3(af.make_hash_function(request.arg(0))); - } -#endif - -#if defined(BOTAN_HAS_EMSA4) - if(request.algo_name() == "EMSA4" && request.arg_count_between(1, 3)) - { - // 3 args: Hash, MGF, salt size (MGF is hardcoded MGF1 in Botan) - if(request.arg_count() == 1) - return new EMSA4(af.make_hash_function(request.arg(0))); - - if(request.arg_count() == 2 && request.arg(1) != "MGF1") - return new EMSA4(af.make_hash_function(request.arg(0))); - - if(request.arg_count() == 3) - return new EMSA4(af.make_hash_function(request.arg(0)), - request.arg_as_integer(2, 0)); - } -#endif - - throw Algorithm_Not_Found(algo_spec); - } - -/* -* Get an EME by name -*/ -EME* get_eme(const std::string& algo_spec) - { - SCAN_Name request(algo_spec); - - Algorithm_Factory& af = global_state().algorithm_factory(); - - if(request.algo_name() == "Raw") - return 0; // No padding - -#if defined(BOTAN_HAS_EME_PKCS1v15) - if(request.algo_name() == "PKCS1v15" && request.arg_count() == 0) - return new EME_PKCS1v15; -#endif - -#if defined(BOTAN_HAS_EME1) - if(request.algo_name() == "EME1" && request.arg_count_between(1, 2)) - { - if(request.arg_count() == 1 || - (request.arg_count() == 2 && request.arg(1) == "MGF1")) - { - return new EME1(af.make_hash_function(request.arg(0))); - } - } -#endif - - throw Algorithm_Not_Found(algo_spec); - } - -/* -* Get an KDF by name -*/ -KDF* get_kdf(const std::string& algo_spec) - { - SCAN_Name request(algo_spec); - - Algorithm_Factory& af = global_state().algorithm_factory(); - - if(request.algo_name() == "Raw") - return 0; // No KDF - -#if defined(BOTAN_HAS_KDF1) - if(request.algo_name() == "KDF1" && request.arg_count() == 1) - return new KDF1(af.make_hash_function(request.arg(0))); -#endif - -#if defined(BOTAN_HAS_KDF2) - if(request.algo_name() == "KDF2" && request.arg_count() == 1) - return new KDF2(af.make_hash_function(request.arg(0))); -#endif - -#if defined(BOTAN_HAS_X942_PRF) - if(request.algo_name() == "X9.42-PRF" && request.arg_count() == 1) - return new X942_PRF(request.arg(0)); // OID -#endif - -#if defined(BOTAN_HAS_TLS_V10_PRF) - if(request.algo_name() == "TLS-PRF" && request.arg_count() == 0) - return new TLS_PRF; -#endif - -#if defined(BOTAN_HAS_SSL_V3_PRF) - if(request.algo_name() == "SSL3-PRF" && request.arg_count() == 0) - return new SSL3_PRF; -#endif - - throw Algorithm_Not_Found(algo_spec); - } - -} -/* -* Global PRNG -* (C) 2008-2010 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -#if defined(BOTAN_HAS_RANDPOOL) -#endif - -#if defined(BOTAN_HAS_HMAC_RNG) -#endif - -#if defined(BOTAN_HAS_X931_RNG) -#endif - -#if defined(BOTAN_HAS_ENTROPY_SRC_HIGH_RESOLUTION_TIMER) -#endif - -#if defined(BOTAN_HAS_ENTROPY_SRC_RDRAND) -#endif - -#if defined(BOTAN_HAS_ENTROPY_SRC_DEV_RANDOM) -#endif - -#if defined(BOTAN_HAS_ENTROPY_SRC_EGD) -#endif - -#if defined(BOTAN_HAS_ENTROPY_SRC_UNIX) -#endif - -#if defined(BOTAN_HAS_ENTROPY_SRC_BEOS) -#endif - -#if defined(BOTAN_HAS_ENTROPY_SRC_CAPI) -#endif - -#if defined(BOTAN_HAS_ENTROPY_SRC_WIN32) -#endif - -#if defined(BOTAN_HAS_ENTROPY_SRC_FTW) -#endif - -namespace Botan { - -namespace { - -/** -* Add any known entropy sources to this RNG -*/ -void add_entropy_sources(RandomNumberGenerator* rng) - { -#if defined(BOTAN_HAS_ENTROPY_SRC_HIGH_RESOLUTION_TIMER) - rng->add_entropy_source(new High_Resolution_Timestamp); -#endif - -#if defined(BOTAN_HAS_ENTROPY_SRC_RDRAND) - rng->add_entropy_source(new Intel_Rdrand); -#endif - -#if defined(BOTAN_HAS_ENTROPY_SRC_DEV_RANDOM) - rng->add_entropy_source( - new Device_EntropySource( - split_on("/dev/random:/dev/srandom:/dev/urandom", ':') - ) - ); -#endif - -#if defined(BOTAN_HAS_ENTROPY_SRC_EGD) - rng->add_entropy_source( - new EGD_EntropySource(split_on("/var/run/egd-pool:/dev/egd-pool", ':')) - ); -#endif - -#if defined(BOTAN_HAS_ENTROPY_SRC_CAPI) - rng->add_entropy_source(new Win32_CAPI_EntropySource); -#endif - -#if defined(BOTAN_HAS_ENTROPY_SRC_FTW) - rng->add_entropy_source(new FTW_EntropySource("/proc")); -#endif - -#if defined(BOTAN_HAS_ENTROPY_SRC_WIN32) - rng->add_entropy_source(new Win32_EntropySource); -#endif - -#if defined(BOTAN_HAS_ENTROPY_SRC_BEOS) - rng->add_entropy_source(new BeOS_EntropySource); -#endif - -#if defined(BOTAN_HAS_ENTROPY_SRC_UNIX) - rng->add_entropy_source( - new Unix_EntropySource(split_on("/bin:/sbin:/usr/bin:/usr/sbin", ':')) - ); -#endif - } - -class Serialized_PRNG : public RandomNumberGenerator - { - public: - void randomize(byte out[], size_t len) - { - Mutex_Holder lock(mutex); - rng->randomize(out, len); - } - - bool is_seeded() const - { - Mutex_Holder lock(mutex); - return rng->is_seeded(); - } - - void clear() - { - Mutex_Holder lock(mutex); - rng->clear(); - } - - std::string name() const - { - Mutex_Holder lock(mutex); - return rng->name(); - } - - void reseed(size_t poll_bits) - { - Mutex_Holder lock(mutex); - rng->reseed(poll_bits); - } - - void add_entropy_source(EntropySource* es) - { - Mutex_Holder lock(mutex); - rng->add_entropy_source(es); - } - - void add_entropy(const byte in[], size_t len) - { - Mutex_Holder lock(mutex); - rng->add_entropy(in, len); - } - - // We do not own the mutex; Library_State does - Serialized_PRNG(RandomNumberGenerator* r, Mutex* m) : - mutex(m), rng(r) {} - - ~Serialized_PRNG() { delete rng; } - private: - Mutex* mutex; - RandomNumberGenerator* rng; - }; - -} - -RandomNumberGenerator* Library_State::make_global_rng(Algorithm_Factory& af, - Mutex* mutex) - { - RandomNumberGenerator* rng = 0; - -#if defined(BOTAN_HAS_HMAC_RNG) - - rng = new HMAC_RNG(af.make_mac("HMAC(SHA-512)"), - af.make_mac("HMAC(SHA-256)")); - -#elif defined(BOTAN_HAS_RANDPOOL) - - rng = new Randpool(af.make_block_cipher("AES-256"), - af.make_mac("HMAC(SHA-256)")); - -#endif - - if(!rng) - throw Internal_Error("No usable RNG found enabled in build"); - - /* If X9.31 is available, use it to wrap the other RNG as a failsafe */ -#if defined(BOTAN_HAS_X931_RNG) - - rng = new ANSI_X931_RNG(af.make_block_cipher("AES-256"), rng); - -#endif - - add_entropy_sources(rng); - - rng->reseed(256); - - return new Serialized_PRNG(rng, mutex); - } - -} -/* -* Global State Management -* (C) 2010 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -/* -* @todo There should probably be a lock to avoid racy manipulation -* of the state among different threads -*/ - -namespace Global_State_Management { - -/* -* Botan's global state -*/ -namespace { - -Library_State* global_lib_state = 0; - -} - -/* -* Access the global state object -*/ -Library_State& global_state() - { - /* Lazy initialization. Botan still needs to be deinitialized later - on or memory might leak. - */ - if(!global_lib_state) - { - global_lib_state = new Library_State; - global_lib_state->initialize(true); - } - - return (*global_lib_state); - } - -/* -* Set a new global state object -*/ -void set_global_state(Library_State* new_state) - { - delete swap_global_state(new_state); - } - -/* -* Set a new global state object unless one already existed -*/ -bool set_global_state_unless_set(Library_State* new_state) - { - if(global_lib_state) - { - delete new_state; - return false; - } - else - { - delete swap_global_state(new_state); - return true; - } - } - -/* -* Swap two global state objects -*/ -Library_State* swap_global_state(Library_State* new_state) - { - Library_State* old_state = global_lib_state; - global_lib_state = new_state; - return old_state; - } - -/* -* Query if library is initialized -*/ -bool global_state_exists() - { - return (global_lib_state != 0); - } - -} - -} -/* -* Default Initialization Function -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -/* -* Library Initialization -*/ -void LibraryInitializer::initialize(const std::string& arg_string) - { - bool thread_safe = false; - - const std::vector arg_list = split_on(arg_string, ' '); - for(size_t i = 0; i != arg_list.size(); ++i) - { - if(arg_list[i].size() == 0) - continue; - - std::string name, value; - - if(arg_list[i].find('=') == std::string::npos) - { - name = arg_list[i]; - value = "true"; - } - else - { - std::vector name_and_value = split_on(arg_list[i], '='); - name = name_and_value[0]; - value = name_and_value[1]; - } - - bool is_on = - (value == "1" || value == "true" || value == "yes" || value == "on"); - - if(name == "thread_safe") - thread_safe = is_on; - } - - try - { - /* - This two stage initialization process is because Library_State's - constructor will implicitly refer to global state through the - allocators and so forth, so global_state() has to be a valid - reference before initialize() can be called. Yeah, gross. - */ - Global_State_Management::set_global_state(new Library_State); - - global_state().initialize(thread_safe); - } - catch(...) - { - deinitialize(); - throw; - } - } - -/* -* Library Shutdown -*/ -void LibraryInitializer::deinitialize() - { - Global_State_Management::set_global_state(0); - } - -} -/* -* Library Internal/Global State -* (C) 1999-2010 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include - -#if defined(BOTAN_HAS_SELFTESTS) -#endif - -#if defined(BOTAN_HAS_MUTEX_PTHREAD) -#elif defined(BOTAN_HAS_MUTEX_WIN32) -#endif - -#if defined(BOTAN_HAS_ALLOC_MMAP) -#endif - -#if defined(BOTAN_HAS_ENGINE_ASSEMBLER) -#endif - -#if defined(BOTAN_HAS_ENGINE_AES_ISA) -#endif - -#if defined(BOTAN_HAS_ENGINE_SIMD) -#endif - -#if defined(BOTAN_HAS_ENGINE_GNU_MP) -#endif - -#if defined(BOTAN_HAS_ENGINE_OPENSSL) -#endif - -namespace Botan { - -/* -* Get a new mutex object -*/ -Mutex* Library_State::get_mutex() const - { - return mutex_factory->make(); - } - -/* -* Get an allocator by its name -*/ -Allocator* Library_State::get_allocator(const std::string& type) const - { - Mutex_Holder lock(allocator_lock); - - if(type != "") - return search_map(alloc_factory, type, 0); - - if(!cached_default_allocator) - { - cached_default_allocator = - search_map(alloc_factory, - default_allocator_name, 0); - } - - return cached_default_allocator; - } - -/* -* Create a new name to object mapping -*/ -void Library_State::add_allocator(Allocator* allocator) - { - Mutex_Holder lock(allocator_lock); - - allocator->init(); - - allocators.push_back(allocator); - alloc_factory[allocator->type()] = allocator; - } - -/* -* Set the default allocator type -*/ -void Library_State::set_default_allocator(const std::string& type) - { - Mutex_Holder lock(allocator_lock); - - if(type == "") - return; - - default_allocator_name = type; - cached_default_allocator = 0; - } - -/* -* Get a configuration value -*/ -std::string Library_State::get(const std::string& section, - const std::string& key) const - { - Mutex_Holder lock(config_lock); - - return search_map(config, - section + "/" + key, ""); - } - -/* -* See if a particular option has been set -*/ -bool Library_State::is_set(const std::string& section, - const std::string& key) const - { - Mutex_Holder lock(config_lock); - - return config.count(section + "/" + key) != 0; - } - -/* -* Set a configuration value -*/ -void Library_State::set(const std::string& section, const std::string& key, - const std::string& value, bool overwrite) - { - Mutex_Holder lock(config_lock); - - std::string full_key = section + "/" + key; - - std::map::const_iterator i = - config.find(full_key); - - if(overwrite || i == config.end() || i->second == "") - config[full_key] = value; - } - -/* -* Add an alias -*/ -void Library_State::add_alias(const std::string& key, const std::string& value) - { - set("alias", key, value); - } - -/* -* Dereference an alias to a fixed name -*/ -std::string Library_State::deref_alias(const std::string& key) const - { - std::string result = key; - while(is_set("alias", result)) - result = get("alias", result); - return result; - } - -/* -* Return a reference to the Algorithm_Factory -*/ -Algorithm_Factory& Library_State::algorithm_factory() const - { - if(!m_algorithm_factory) - throw Invalid_State("Uninitialized in Library_State::algorithm_factory"); - return *m_algorithm_factory; - } - -/* -* Return a reference to the global PRNG -*/ -RandomNumberGenerator& Library_State::global_rng() - { - Mutex_Holder lock(global_rng_lock); - - if(!global_rng_ptr) - global_rng_ptr = make_global_rng(algorithm_factory(), - global_rng_lock); - - return *global_rng_ptr; - } - -/* -* Load a set of modules -*/ -void Library_State::initialize(bool thread_safe) - { - CPUID::initialize(); - - if(mutex_factory) - throw Invalid_State("Library_State has already been initialized"); - - if(!thread_safe) - { - mutex_factory = new Noop_Mutex_Factory; - } - else - { -#if defined(BOTAN_HAS_MUTEX_PTHREAD) - mutex_factory = new Pthread_Mutex_Factory; -#elif defined(BOTAN_HAS_MUTEX_WIN32) - mutex_factory = new Win32_Mutex_Factory; -#else - throw Invalid_State("Could not find a thread-safe mutex object to use"); -#endif - } - - allocator_lock = get_mutex(); - config_lock = get_mutex(); - global_rng_lock = get_mutex(); - - default_allocator_name = has_mlock() ? "locking" : "malloc"; - - add_allocator(new Malloc_Allocator); - add_allocator(new Locking_Allocator(get_mutex())); - -#if defined(BOTAN_HAS_ALLOC_MMAP) - add_allocator(new MemoryMapping_Allocator(get_mutex())); -#endif - - load_default_config(); - - m_algorithm_factory = new Algorithm_Factory(*mutex_factory); - -#if defined(BOTAN_HAS_ENGINE_GNU_MP) - algorithm_factory().add_engine(new GMP_Engine); -#endif - -#if defined(BOTAN_HAS_ENGINE_OPENSSL) - algorithm_factory().add_engine(new OpenSSL_Engine); -#endif - -#if defined(BOTAN_HAS_ENGINE_AES_ISA) - algorithm_factory().add_engine(new AES_ISA_Engine); -#endif - -#if defined(BOTAN_HAS_ENGINE_SIMD) - algorithm_factory().add_engine(new SIMD_Engine); -#endif - -#if defined(BOTAN_HAS_ENGINE_ASSEMBLER) - algorithm_factory().add_engine(new Assembler_Engine); -#endif - - algorithm_factory().add_engine(new Core_Engine); - -#if defined(BOTAN_HAS_SELFTESTS) - confirm_startup_self_tests(algorithm_factory()); -#endif - } - -/* -* Library_State Constructor -*/ -Library_State::Library_State() - { - mutex_factory = 0; - allocator_lock = config_lock = 0; - cached_default_allocator = 0; - m_algorithm_factory = 0; - - global_rng_lock = 0; - global_rng_ptr = 0; - } - -/* -* Library_State Destructor -*/ -Library_State::~Library_State() - { - delete m_algorithm_factory; - delete global_rng_ptr; - - cached_default_allocator = 0; - - for(size_t i = 0; i != allocators.size(); ++i) - { - allocators[i]->destroy(); - delete allocators[i]; - } - - delete global_rng_lock; - delete allocator_lock; - delete mutex_factory; - delete config_lock; - } - -} -/* -* Algorithm Retrieval -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -/* -* Query if an algorithm exists -*/ -bool have_algorithm(const std::string& name) - { - Algorithm_Factory& af = global_state().algorithm_factory(); - - if(af.prototype_block_cipher(name)) - return true; - if(af.prototype_stream_cipher(name)) - return true; - if(af.prototype_hash_function(name)) - return true; - if(af.prototype_mac(name)) - return true; - return false; - } - -/* -* Query the block size of a cipher or hash -*/ -size_t block_size_of(const std::string& name) - { - Algorithm_Factory& af = global_state().algorithm_factory(); - - if(const BlockCipher* cipher = af.prototype_block_cipher(name)) - return cipher->block_size(); - - if(const HashFunction* hash = af.prototype_hash_function(name)) - return hash->hash_block_size(); - - throw Algorithm_Not_Found(name); - } - -/* -* Query the output_length() of a hash or MAC -*/ -size_t output_length_of(const std::string& name) - { - Algorithm_Factory& af = global_state().algorithm_factory(); - - if(const HashFunction* hash = af.prototype_hash_function(name)) - return hash->output_length(); - - if(const MessageAuthenticationCode* mac = af.prototype_mac(name)) - return mac->output_length(); - - throw Algorithm_Not_Found(name); - } - -/* -* Query the minimum allowed key length of an algorithm implementation -*/ -size_t min_keylength_of(const std::string& name) - { - Algorithm_Factory& af = global_state().algorithm_factory(); - - if(const BlockCipher* bc = af.prototype_block_cipher(name)) - return bc->key_spec().minimum_keylength(); - - if(const StreamCipher* sc = af.prototype_stream_cipher(name)) - return sc->key_spec().minimum_keylength(); - - if(const MessageAuthenticationCode* mac = af.prototype_mac(name)) - return mac->key_spec().minimum_keylength(); - - throw Algorithm_Not_Found(name); - } - -/* -* Query the maximum allowed keylength of an algorithm implementation -*/ -size_t max_keylength_of(const std::string& name) - { - Algorithm_Factory& af = global_state().algorithm_factory(); - - if(const BlockCipher* bc = af.prototype_block_cipher(name)) - return bc->key_spec().maximum_keylength(); - - if(const StreamCipher* sc = af.prototype_stream_cipher(name)) - return sc->key_spec().maximum_keylength(); - - if(const MessageAuthenticationCode* mac = af.prototype_mac(name)) - return mac->key_spec().maximum_keylength(); - - throw Algorithm_Not_Found(name); - } - -/* -* Query the number of byte a valid key must be a multiple of -*/ -size_t keylength_multiple_of(const std::string& name) - { - Algorithm_Factory& af = global_state().algorithm_factory(); - - if(const BlockCipher* bc = af.prototype_block_cipher(name)) - return bc->key_spec().keylength_multiple(); - - if(const StreamCipher* sc = af.prototype_stream_cipher(name)) - return sc->key_spec().keylength_multiple(); - - if(const MessageAuthenticationCode* mac = af.prototype_mac(name)) - return mac->key_spec().keylength_multiple(); - - throw Algorithm_Not_Found(name); - } - -/* -* Get a cipher object -*/ -Keyed_Filter* get_cipher(const std::string& algo_spec, - Cipher_Dir direction) - { - Algorithm_Factory& af = global_state().algorithm_factory(); - - Algorithm_Factory::Engine_Iterator i(af); - - while(Engine* engine = i.next()) - { - if(Keyed_Filter* algo = engine->get_cipher(algo_spec, direction, af)) - return algo; - } - - throw Algorithm_Not_Found(algo_spec); - } - -/* -* Get a cipher object -*/ -Keyed_Filter* get_cipher(const std::string& algo_spec, - const SymmetricKey& key, - const InitializationVector& iv, - Cipher_Dir direction) - { - Keyed_Filter* cipher = get_cipher(algo_spec, direction); - cipher->set_key(key); - - if(iv.length()) - cipher->set_iv(iv); - - return cipher; - } - -/* -* Get a cipher object -*/ -Keyed_Filter* get_cipher(const std::string& algo_spec, - const SymmetricKey& key, - Cipher_Dir direction) - { - return get_cipher(algo_spec, - key, InitializationVector(), direction); - } - -} -/* -* OID Registry -* (C) 1999-2008 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -namespace OIDS { - -/* -* Register an OID to string mapping -*/ -void add_oid(const OID& oid, const std::string& name) - { - const std::string oid_str = oid.as_string(); - - if(!global_state().is_set("oid2str", oid_str)) - global_state().set("oid2str", oid_str, name); - if(!global_state().is_set("str2oid", name)) - global_state().set("str2oid", name, oid_str); - } - -/* -* Do an OID to string lookup -*/ -std::string lookup(const OID& oid) - { - std::string name = global_state().get("oid2str", oid.as_string()); - if(name == "") - return oid.as_string(); - return name; - } - -/* -* Do a string to OID lookup -*/ -OID lookup(const std::string& name) - { - std::string value = global_state().get("str2oid", name); - if(value != "") - return OID(value); - - try - { - return OID(name); - } - catch(...) - { - throw Lookup_Error("No object identifier found for " + name); - } - } - -/* -* Check to see if an OID exists in the table -*/ -bool have_oid(const std::string& name) - { - return global_state().is_set("str2oid", name); - } - -/* -* Check to see if an OID exists in the table -*/ -bool name_of(const OID& oid, const std::string& name) - { - return (oid == lookup(name)); - } - -} - -} -/* -* Default Policy -* (C) 1999-2010 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -namespace { - -/* -* OID loading helper function -*/ -void add_oid(Library_State& config, - const std::string& oid_str, - const std::string& name) - { - if(!config.is_set("oid2str", oid_str)) - config.set("oid2str", oid_str, name); - if(!config.is_set("str2oid", name)) - config.set("str2oid", name, oid_str); - } - -/* -* Load all of the default OIDs -*/ -void set_default_oids(Library_State& config) - { - /* Public key types */ - add_oid(config, "1.2.840.113549.1.1.1", "RSA"); - add_oid(config, "2.5.8.1.1", "RSA"); // RSA alternate - add_oid(config, "1.2.840.10040.4.1", "DSA"); - add_oid(config, "1.2.840.10046.2.1", "DH"); - add_oid(config, "1.3.6.1.4.1.3029.1.2.1", "ElGamal"); - add_oid(config, "1.3.6.1.4.1.25258.1.1", "RW"); - add_oid(config, "1.3.6.1.4.1.25258.1.2", "NR"); - - // X9.62 ecPublicKey, valid for ECDSA and ECDH (RFC 3279 sec 2.3.5) - add_oid(config, "1.2.840.10045.2.1", "ECDSA"); - - /* - * This is an OID defined for ECDH keys though rarely used for such. - * In this configuration it is accepted on decoding, but not used for - * encoding. You can enable it for encoding by calling - * global_state().set("str2oid", "ECDH", "1.3.132.1.12") - * from your application code. - */ - config.set("oid2str", "1.3.132.1.12", "ECDH"); - - add_oid(config, "1.2.643.2.2.19", "GOST-34.10"); // RFC 4491 - - /* Ciphers */ - add_oid(config, "1.3.14.3.2.7", "DES/CBC"); - add_oid(config, "1.2.840.113549.3.7", "TripleDES/CBC"); - add_oid(config, "1.2.840.113549.3.2", "RC2/CBC"); - add_oid(config, "1.2.840.113533.7.66.10", "CAST-128/CBC"); - add_oid(config, "2.16.840.1.101.3.4.1.2", "AES-128/CBC"); - add_oid(config, "2.16.840.1.101.3.4.1.22", "AES-192/CBC"); - add_oid(config, "2.16.840.1.101.3.4.1.42", "AES-256/CBC"); - add_oid(config, "1.2.410.200004.1.4", "SEED/CBC"); // RFC 4010 - add_oid(config, "1.3.6.1.4.1.25258.3.1", "Serpent/CBC"); - - /* Hash Functions */ - add_oid(config, "1.2.840.113549.2.5", "MD5"); - add_oid(config, "1.3.6.1.4.1.11591.12.2", "Tiger(24,3)"); - - add_oid(config, "1.3.14.3.2.26", "SHA-160"); - add_oid(config, "2.16.840.1.101.3.4.2.4", "SHA-224"); - add_oid(config, "2.16.840.1.101.3.4.2.1", "SHA-256"); - add_oid(config, "2.16.840.1.101.3.4.2.2", "SHA-384"); - add_oid(config, "2.16.840.1.101.3.4.2.3", "SHA-512"); - - /* MACs */ - add_oid(config, "1.2.840.113549.2.7", "HMAC(SHA-1)"); - add_oid(config, "1.2.840.113549.2.8", "HMAC(SHA-224)"); - add_oid(config, "1.2.840.113549.2.9", "HMAC(SHA-256)"); - add_oid(config, "1.2.840.113549.2.10", "HMAC(SHA-384)"); - add_oid(config, "1.2.840.113549.2.11", "HMAC(SHA-512)"); - - /* Key Wrap */ - add_oid(config, "1.2.840.113549.1.9.16.3.6", "KeyWrap.TripleDES"); - add_oid(config, "1.2.840.113549.1.9.16.3.7", "KeyWrap.RC2"); - add_oid(config, "1.2.840.113533.7.66.15", "KeyWrap.CAST-128"); - add_oid(config, "2.16.840.1.101.3.4.1.5", "KeyWrap.AES-128"); - add_oid(config, "2.16.840.1.101.3.4.1.25", "KeyWrap.AES-192"); - add_oid(config, "2.16.840.1.101.3.4.1.45", "KeyWrap.AES-256"); - - /* Compression */ - add_oid(config, "1.2.840.113549.1.9.16.3.8", "Compression.Zlib"); - - /* Public key signature schemes */ - add_oid(config, "1.2.840.113549.1.1.1", "RSA/EME-PKCS1-v1_5"); - add_oid(config, "1.2.840.113549.1.1.2", "RSA/EMSA3(MD2)"); - add_oid(config, "1.2.840.113549.1.1.4", "RSA/EMSA3(MD5)"); - add_oid(config, "1.2.840.113549.1.1.5", "RSA/EMSA3(SHA-160)"); - add_oid(config, "1.2.840.113549.1.1.11", "RSA/EMSA3(SHA-256)"); - add_oid(config, "1.2.840.113549.1.1.12", "RSA/EMSA3(SHA-384)"); - add_oid(config, "1.2.840.113549.1.1.13", "RSA/EMSA3(SHA-512)"); - add_oid(config, "1.3.36.3.3.1.2", "RSA/EMSA3(RIPEMD-160)"); - - add_oid(config, "1.2.840.10040.4.3", "DSA/EMSA1(SHA-160)"); - add_oid(config, "2.16.840.1.101.3.4.3.1", "DSA/EMSA1(SHA-224)"); - add_oid(config, "2.16.840.1.101.3.4.3.2", "DSA/EMSA1(SHA-256)"); - - add_oid(config, "0.4.0.127.0.7.1.1.4.1.1", "ECDSA/EMSA1_BSI(SHA-160)"); - add_oid(config, "0.4.0.127.0.7.1.1.4.1.2", "ECDSA/EMSA1_BSI(SHA-224)"); - add_oid(config, "0.4.0.127.0.7.1.1.4.1.3", "ECDSA/EMSA1_BSI(SHA-256)"); - add_oid(config, "0.4.0.127.0.7.1.1.4.1.4", "ECDSA/EMSA1_BSI(SHA-384)"); - add_oid(config, "0.4.0.127.0.7.1.1.4.1.5", "ECDSA/EMSA1_BSI(SHA-512)"); - add_oid(config, "0.4.0.127.0.7.1.1.4.1.6", "ECDSA/EMSA1_BSI(RIPEMD-160)"); - - add_oid(config, "1.2.840.10045.4.1", "ECDSA/EMSA1(SHA-160)"); - add_oid(config, "1.2.840.10045.4.3.1", "ECDSA/EMSA1(SHA-224)"); - add_oid(config, "1.2.840.10045.4.3.2", "ECDSA/EMSA1(SHA-256)"); - add_oid(config, "1.2.840.10045.4.3.3", "ECDSA/EMSA1(SHA-384)"); - add_oid(config, "1.2.840.10045.4.3.4", "ECDSA/EMSA1(SHA-512)"); - - add_oid(config, "1.2.643.2.2.3", "GOST-34.10/EMSA1(GOST-R-34.11-94)"); - - add_oid(config, "1.3.6.1.4.1.25258.2.1.1.1", "RW/EMSA2(RIPEMD-160)"); - add_oid(config, "1.3.6.1.4.1.25258.2.1.1.2", "RW/EMSA2(SHA-160)"); - add_oid(config, "1.3.6.1.4.1.25258.2.1.1.3", "RW/EMSA2(SHA-224)"); - add_oid(config, "1.3.6.1.4.1.25258.2.1.1.4", "RW/EMSA2(SHA-256)"); - add_oid(config, "1.3.6.1.4.1.25258.2.1.1.5", "RW/EMSA2(SHA-384)"); - add_oid(config, "1.3.6.1.4.1.25258.2.1.1.6", "RW/EMSA2(SHA-512)"); - - add_oid(config, "1.3.6.1.4.1.25258.2.1.2.1", "RW/EMSA4(RIPEMD-160)"); - add_oid(config, "1.3.6.1.4.1.25258.2.1.2.2", "RW/EMSA4(SHA-160)"); - add_oid(config, "1.3.6.1.4.1.25258.2.1.2.3", "RW/EMSA4(SHA-224)"); - add_oid(config, "1.3.6.1.4.1.25258.2.1.2.4", "RW/EMSA4(SHA-256)"); - add_oid(config, "1.3.6.1.4.1.25258.2.1.2.5", "RW/EMSA4(SHA-384)"); - add_oid(config, "1.3.6.1.4.1.25258.2.1.2.6", "RW/EMSA4(SHA-512)"); - - add_oid(config, "1.3.6.1.4.1.25258.2.2.1.1", "NR/EMSA2(RIPEMD-160)"); - add_oid(config, "1.3.6.1.4.1.25258.2.2.1.2", "NR/EMSA2(SHA-160)"); - add_oid(config, "1.3.6.1.4.1.25258.2.2.1.3", "NR/EMSA2(SHA-224)"); - add_oid(config, "1.3.6.1.4.1.25258.2.2.1.4", "NR/EMSA2(SHA-256)"); - add_oid(config, "1.3.6.1.4.1.25258.2.2.1.5", "NR/EMSA2(SHA-384)"); - add_oid(config, "1.3.6.1.4.1.25258.2.2.1.6", "NR/EMSA2(SHA-512)"); - - add_oid(config, "2.5.4.3", "X520.CommonName"); - add_oid(config, "2.5.4.4", "X520.Surname"); - add_oid(config, "2.5.4.5", "X520.SerialNumber"); - add_oid(config, "2.5.4.6", "X520.Country"); - add_oid(config, "2.5.4.7", "X520.Locality"); - add_oid(config, "2.5.4.8", "X520.State"); - add_oid(config, "2.5.4.10", "X520.Organization"); - add_oid(config, "2.5.4.11", "X520.OrganizationalUnit"); - add_oid(config, "2.5.4.12", "X520.Title"); - add_oid(config, "2.5.4.42", "X520.GivenName"); - add_oid(config, "2.5.4.43", "X520.Initials"); - add_oid(config, "2.5.4.44", "X520.GenerationalQualifier"); - add_oid(config, "2.5.4.46", "X520.DNQualifier"); - add_oid(config, "2.5.4.65", "X520.Pseudonym"); - - add_oid(config, "1.2.840.113549.1.5.12", "PKCS5.PBKDF2"); - add_oid(config, "1.2.840.113549.1.5.1", "PBE-PKCS5v15(MD2,DES/CBC)"); - add_oid(config, "1.2.840.113549.1.5.4", "PBE-PKCS5v15(MD2,RC2/CBC)"); - add_oid(config, "1.2.840.113549.1.5.3", "PBE-PKCS5v15(MD5,DES/CBC)"); - add_oid(config, "1.2.840.113549.1.5.6", "PBE-PKCS5v15(MD5,RC2/CBC)"); - add_oid(config, "1.2.840.113549.1.5.10", "PBE-PKCS5v15(SHA-160,DES/CBC)"); - add_oid(config, "1.2.840.113549.1.5.11", "PBE-PKCS5v15(SHA-160,RC2/CBC)"); - add_oid(config, "1.2.840.113549.1.5.13", "PBE-PKCS5v20"); - - add_oid(config, "1.2.840.113549.1.9.1", "PKCS9.EmailAddress"); - add_oid(config, "1.2.840.113549.1.9.2", "PKCS9.UnstructuredName"); - add_oid(config, "1.2.840.113549.1.9.3", "PKCS9.ContentType"); - add_oid(config, "1.2.840.113549.1.9.4", "PKCS9.MessageDigest"); - add_oid(config, "1.2.840.113549.1.9.7", "PKCS9.ChallengePassword"); - add_oid(config, "1.2.840.113549.1.9.14", "PKCS9.ExtensionRequest"); - - add_oid(config, "1.2.840.113549.1.7.1", "CMS.DataContent"); - add_oid(config, "1.2.840.113549.1.7.2", "CMS.SignedData"); - add_oid(config, "1.2.840.113549.1.7.3", "CMS.EnvelopedData"); - add_oid(config, "1.2.840.113549.1.7.5", "CMS.DigestedData"); - add_oid(config, "1.2.840.113549.1.7.6", "CMS.EncryptedData"); - add_oid(config, "1.2.840.113549.1.9.16.1.2", "CMS.AuthenticatedData"); - add_oid(config, "1.2.840.113549.1.9.16.1.9", "CMS.CompressedData"); - - add_oid(config, "2.5.29.14", "X509v3.SubjectKeyIdentifier"); - add_oid(config, "2.5.29.15", "X509v3.KeyUsage"); - add_oid(config, "2.5.29.17", "X509v3.SubjectAlternativeName"); - add_oid(config, "2.5.29.18", "X509v3.IssuerAlternativeName"); - add_oid(config, "2.5.29.19", "X509v3.BasicConstraints"); - add_oid(config, "2.5.29.20", "X509v3.CRLNumber"); - add_oid(config, "2.5.29.21", "X509v3.ReasonCode"); - add_oid(config, "2.5.29.23", "X509v3.HoldInstructionCode"); - add_oid(config, "2.5.29.24", "X509v3.InvalidityDate"); - add_oid(config, "2.5.29.32", "X509v3.CertificatePolicies"); - add_oid(config, "2.5.29.35", "X509v3.AuthorityKeyIdentifier"); - add_oid(config, "2.5.29.36", "X509v3.PolicyConstraints"); - add_oid(config, "2.5.29.37", "X509v3.ExtendedKeyUsage"); - - add_oid(config, "2.5.29.32.0", "X509v3.AnyPolicy"); - - add_oid(config, "1.3.6.1.5.5.7.3.1", "PKIX.ServerAuth"); - add_oid(config, "1.3.6.1.5.5.7.3.2", "PKIX.ClientAuth"); - add_oid(config, "1.3.6.1.5.5.7.3.3", "PKIX.CodeSigning"); - add_oid(config, "1.3.6.1.5.5.7.3.4", "PKIX.EmailProtection"); - add_oid(config, "1.3.6.1.5.5.7.3.5", "PKIX.IPsecEndSystem"); - add_oid(config, "1.3.6.1.5.5.7.3.6", "PKIX.IPsecTunnel"); - add_oid(config, "1.3.6.1.5.5.7.3.7", "PKIX.IPsecUser"); - add_oid(config, "1.3.6.1.5.5.7.3.8", "PKIX.TimeStamping"); - add_oid(config, "1.3.6.1.5.5.7.3.9", "PKIX.OCSPSigning"); - - add_oid(config, "1.3.6.1.5.5.7.8.5", "PKIX.XMPPAddr"); - - /* ECC domain parameters */ - - add_oid(config, "1.3.132.0.6", "secp112r1"); - add_oid(config, "1.3.132.0.7", "secp112r2"); - add_oid(config, "1.3.132.0.8", "secp160r1"); - add_oid(config, "1.3.132.0.9", "secp160k1"); - add_oid(config, "1.3.132.0.10", "secp256k1"); - add_oid(config, "1.3.132.0.28", "secp128r1"); - add_oid(config, "1.3.132.0.29", "secp128r2"); - add_oid(config, "1.3.132.0.30", "secp160r2"); - add_oid(config, "1.3.132.0.31", "secp192k1"); - add_oid(config, "1.3.132.0.32", "secp224k1"); - add_oid(config, "1.3.132.0.33", "secp224r1"); - add_oid(config, "1.3.132.0.34", "secp384r1"); - add_oid(config, "1.3.132.0.35", "secp521r1"); - - add_oid(config, "1.2.840.10045.3.1.1", "secp192r1"); - add_oid(config, "1.2.840.10045.3.1.2", "x962_p192v2"); - add_oid(config, "1.2.840.10045.3.1.3", "x962_p192v3"); - add_oid(config, "1.2.840.10045.3.1.4", "x962_p239v1"); - add_oid(config, "1.2.840.10045.3.1.5", "x962_p239v2"); - add_oid(config, "1.2.840.10045.3.1.6", "x962_p239v3"); - add_oid(config, "1.2.840.10045.3.1.7", "secp256r1"); - - add_oid(config, "1.3.36.3.3.2.8.1.1.1", "brainpool160r1"); - add_oid(config, "1.3.36.3.3.2.8.1.1.3", "brainpool192r1"); - add_oid(config, "1.3.36.3.3.2.8.1.1.5", "brainpool224r1"); - add_oid(config, "1.3.36.3.3.2.8.1.1.7", "brainpool256r1"); - add_oid(config, "1.3.36.3.3.2.8.1.1.9", "brainpool320r1"); - add_oid(config, "1.3.36.3.3.2.8.1.1.11", "brainpool384r1"); - add_oid(config, "1.3.36.3.3.2.8.1.1.13", "brainpool512r1"); - - add_oid(config, "1.2.643.2.2.35.1", "gost_256A"); - add_oid(config, "1.2.643.2.2.36.0", "gost_256A"); - - /* CVC */ - add_oid(config, "0.4.0.127.0.7.3.1.2.1", - "CertificateHolderAuthorizationTemplate"); - } - -/* -* Set the default algorithm aliases -*/ -void set_default_aliases(Library_State& config) - { - config.add_alias("OpenPGP.Cipher.1", "IDEA"); - config.add_alias("OpenPGP.Cipher.2", "TripleDES"); - config.add_alias("OpenPGP.Cipher.3", "CAST-128"); - config.add_alias("OpenPGP.Cipher.4", "Blowfish"); - config.add_alias("OpenPGP.Cipher.5", "SAFER-SK(13)"); - config.add_alias("OpenPGP.Cipher.7", "AES-128"); - config.add_alias("OpenPGP.Cipher.8", "AES-192"); - config.add_alias("OpenPGP.Cipher.9", "AES-256"); - config.add_alias("OpenPGP.Cipher.10", "Twofish"); - - config.add_alias("OpenPGP.Digest.1", "MD5"); - config.add_alias("OpenPGP.Digest.2", "SHA-1"); - config.add_alias("OpenPGP.Digest.3", "RIPEMD-160"); - config.add_alias("OpenPGP.Digest.5", "MD2"); - config.add_alias("OpenPGP.Digest.6", "Tiger(24,3)"); - config.add_alias("OpenPGP.Digest.8", "SHA-256"); - - config.add_alias("TLS.Digest.0", "Parallel(MD5,SHA-160)"); - - config.add_alias("EME-PKCS1-v1_5", "PKCS1v15"); - config.add_alias("OAEP-MGF1", "EME1"); - config.add_alias("EME-OAEP", "EME1"); - config.add_alias("X9.31", "EMSA2"); - config.add_alias("EMSA-PKCS1-v1_5", "EMSA3"); - config.add_alias("PSS-MGF1", "EMSA4"); - config.add_alias("EMSA-PSS", "EMSA4"); - - config.add_alias("3DES", "TripleDES"); - config.add_alias("DES-EDE", "TripleDES"); - config.add_alias("CAST5", "CAST-128"); - config.add_alias("SHA1", "SHA-160"); - config.add_alias("SHA-1", "SHA-160"); - config.add_alias("MARK-4", "ARC4(256)"); - config.add_alias("OMAC", "CMAC"); - config.add_alias("GOST", "GOST-28147-89"); - } - -/* -* Set the built-in discrete log groups -*/ -void set_default_dl_groups(Library_State& config) - { - config.set("dl", "modp/ietf/768", - "-----BEGIN X942 DH PARAMETERS-----" - "MIHIAmEA///////////JD9qiIWjCNMTGYouA3BzRKQJOCIpnzHQCC76mOxObIlFK" - "CHmONATd75UZs806QxswKwpt8l8UN0/hNW1tUcJF5IW1dmJefsb0TELppjo2IP//" - "////////AgECAmB//////////+SH7VEQtGEaYmMxRcBuDmiUgScERTPmOgEF31Md" - "ic2RKKUEPMcaAm73yozZ5p0hjZgVhTb5L4obp/Catrao4SLyQtq7MS8/Y3omIXTT" - "HRsQf/////////8=" - "-----END X942 DH PARAMETERS-----"); - - config.set("dl", "modp/ietf/1024", - "-----BEGIN X942 DH PARAMETERS-----" - "MIIBCgKBgQD//////////8kP2qIhaMI0xMZii4DcHNEpAk4IimfMdAILvqY7E5si" - "UUoIeY40BN3vlRmzzTpDGzArCm3yXxQ3T+E1bW1RwkXkhbV2Yl5+xvRMQummN+1r" - "C/9ctvQGt+3uOGv7Womfpa6fJBF8Sx/mSShmUezmU4H//////////wIBAgKBgH//" - "////////5IftURC0YRpiYzFFwG4OaJSBJwRFM+Y6AQXfUx2JzZEopQQ8xxoCbvfK" - "jNnmnSGNmBWFNvkvihun8Jq2tqjhIvJC2rsxLz9jeiYhdNMb9rWF/65begNb9vcc" - "Nf2tRM/S10+SCL4lj/MklDMo9nMpwP//////////" - "-----END X942 DH PARAMETERS-----"); - - config.set("dl", "modp/srp/1024", - "-----BEGIN X942 DH PARAMETERS-----" - "MIIBCgKBgQDurwq5rbON1pwz+Ar6j8XoYHJhh3X/PAueojFMnCVldtZ033SW6oHT" - "ODtIE9aSxuDg1djiULmL5I5JXB1gidrRXcfXtGFU1rbOjvStabFdSYJVmyl7zxiF" - "xSn1ZmYOV+xo7bw8BXJswC/Uy/SXbqqa/VE4/oN2Q1ufxh0vwOsG4wIBAgKBgHdX" - "hVzW2cbrThn8BX1H4vQwOTDDuv+eBc9RGKZOErK7azpvukt1QOmcHaQJ60ljcHBq" - "7HEoXMXyRySuDrBE7Wiu4+vaMKprW2dHela02K6kwSrNlL3njELilPqzMwcr9jR2" - "3h4CuTZgF+pl+ku3VU1+qJx/Qbshrc/jDpfgdYNx" - "-----END X942 DH PARAMETERS-----"); - - config.set("dl", "modp/ietf/1536", - "-----BEGIN X942 DH PARAMETERS-----" - "MIIBigKBwQD//////////8kP2qIhaMI0xMZii4DcHNEpAk4IimfMdAILvqY7E5si" - "UUoIeY40BN3vlRmzzTpDGzArCm3yXxQ3T+E1bW1RwkXkhbV2Yl5+xvRMQummN+1r" - "C/9ctvQGt+3uOGv7Womfpa6fJBF8Sx/mSShmUezkWz3CAHy4oWO/BZjaSDYcVdOa" - "aRY/qP0kz1+DZV0j3KOtlhxi81YghVK7ntUpB3CWlm1nDDVOSryYBPF0bAjKI3Mn" - "//////////8CAQICgcB//////////+SH7VEQtGEaYmMxRcBuDmiUgScERTPmOgEF" - "31Mdic2RKKUEPMcaAm73yozZ5p0hjZgVhTb5L4obp/Catrao4SLyQtq7MS8/Y3om" - "IXTTG/a1hf+uW3oDW/b3HDX9rUTP0tdPkgi+JY/zJJQzKPZyLZ7hAD5cULHfgsxt" - "JBsOKunNNIsf1H6SZ6/Bsq6R7lHWyw4xeasQQqldz2qUg7hLSzazhhqnJV5MAni6" - "NgRlEbmT//////////8=" - "-----END X942 DH PARAMETERS-----"); - - config.set("dl", "modp/srp/1536", - "-----BEGIN DH PARAMETERS-----" - "MIHHAoHBAJ3vPK+5OSd6sfEqhheke7vbpR30maxMgL7uqWFLGcxNX09fVW4ny95R" - "xqlL5GB6KRVYkDug0PhDgLZVu5oi6NzfAop87Gfw0IE0sci5eYkUm2CeC+O6tj1H" - "VIOB28Wx/HZOP0tT3Z2hFYv9PiucjPVu3wGVOTSWJ9sv1T0kt8SGZXcuQ31sf4zk" - "QnNK98y3roN8Jkrjqb64f4ov6bi1KS5aAh//XpFHnoznoowkQsbzFRgPk0maI03P" - "duP+0TX5uwIBAg==" - "-----END DH PARAMETERS-----"); - - config.set("dl", "modp/ietf/2048", - "-----BEGIN X942 DH PARAMETERS-----" - "MIICDAKCAQEA///////////JD9qiIWjCNMTGYouA3BzRKQJOCIpnzHQCC76mOxOb" - "IlFKCHmONATd75UZs806QxswKwpt8l8UN0/hNW1tUcJF5IW1dmJefsb0TELppjft" - "awv/XLb0Brft7jhr+1qJn6WunyQRfEsf5kkoZlHs5Fs9wgB8uKFjvwWY2kg2HFXT" - "mmkWP6j9JM9fg2VdI9yjrZYcYvNWIIVSu57VKQdwlpZtZww1Tkq8mATxdGwIyhgh" - "fDKQXkYuNs474553LBgOhgObJ4Oi7Aeij7XFXfBvTFLJ3ivL9pVYFxg5lUl86pVq" - "5RXSJhiY+gUQFXKOWoqsqmj//////////wIBAgKCAQB//////////+SH7VEQtGEa" - "YmMxRcBuDmiUgScERTPmOgEF31Mdic2RKKUEPMcaAm73yozZ5p0hjZgVhTb5L4ob" - "p/Catrao4SLyQtq7MS8/Y3omIXTTG/a1hf+uW3oDW/b3HDX9rUTP0tdPkgi+JY/z" - "JJQzKPZyLZ7hAD5cULHfgsxtJBsOKunNNIsf1H6SZ6/Bsq6R7lHWyw4xeasQQqld" - "z2qUg7hLSzazhhqnJV5MAni6NgRlDBC+GUgvIxcbZx3xzzuWDAdDAc2TwdF2A9FH" - "2uKu+DemKWTvFeX7SqwLjBzKpL51SrVyiukTDEx9AogKuUctRVZVNH//////////" - "-----END X942 DH PARAMETERS-----"); - - config.set("dl", "modp/srp/2048", - "-----BEGIN X942 DH PARAMETERS-----" - "MIICDAKCAQEArGvbQTJKmpvxZt5eE4lYL69ytmUZh+4H/DGSlD21YFCjcynLtKCZ" - "7YGT4HV3Z6E91SMSq0sDMQ3Nf0ip2gT9UOgIOWntt2ewz2CVF5oWOrNmGgX71fqq" - "6CkYqZYvC5O4Vfl5k+yXXuqoDXQK2/T/dHNZ0EHVwz6nHSgeRGsUdzvKl7Q6I/uA" - "Fna9IHpDbGSB8dK5B4cXRhpbnTLmiPh3SFRFI7UksNV9Xqd6J3XS7PoDLPvb9S+z" - "eGFgJ5AE5Xrmr4dOcwPOUymczAQce8MI2CpWmPOo0MOCca41+Onb+7aUtcgD2J96" - "5DXeI21SX1R1m2XjcvzWjvIPpxEfnkr/cwIBAgKCAQBWNe2gmSVNTfizby8JxKwX" - "17lbMozD9wP+GMlKHtqwKFG5lOXaUEz2wMnwOruz0J7qkYlVpYGYhua/pFTtAn6o" - "dAQctPbbs9hnsEqLzQsdWbMNAv3q/VV0FIxUyxeFydwq/LzJ9kuvdVQGugVt+n+6" - "OazoIOrhn1OOlA8iNYo7neVL2h0R/cALO16QPSG2MkD46VyDw4ujDS3OmXNEfDuk" - "KiKR2pJYar6vU70Tuul2fQGWfe36l9m8MLATyAJyvXNXw6c5gecplM5mAg494YRs" - "FStMedRoYcE41xr8dO3920pa5AHsT71yGu8RtqkvqjrNsvG5fmtHeQfTiI/PJX+5" - "-----END X942 DH PARAMETERS-----"); - - config.set("dl", "modp/ietf/3072", - "-----BEGIN X942 DH PARAMETERS-----" - "MIIDDAKCAYEA///////////JD9qiIWjCNMTGYouA3BzRKQJOCIpnzHQCC76mOxOb" - "IlFKCHmONATd75UZs806QxswKwpt8l8UN0/hNW1tUcJF5IW1dmJefsb0TELppjft" - "awv/XLb0Brft7jhr+1qJn6WunyQRfEsf5kkoZlHs5Fs9wgB8uKFjvwWY2kg2HFXT" - "mmkWP6j9JM9fg2VdI9yjrZYcYvNWIIVSu57VKQdwlpZtZww1Tkq8mATxdGwIyhgh" - "fDKQXkYuNs474553LBgOhgObJ4Oi7Aeij7XFXfBvTFLJ3ivL9pVYFxg5lUl86pVq" - "5RXSJhiY+gUQFXKOWoqqxC2tMxcNBFB6M6hVIavfHLpk7PuFBFjb7wqK6nFXXQYM" - "fbOXD4Wm4eTHq/WujNsJM9cejJTgSiVhnc7j0iYa0u5r8S/6BtmKCGTYdgJzPshq" - "ZFIfKxgXeyAMu+EXV3phXWx3CYjAutlG4gjiT6B05asxQ9tb/OD9EI5LgtEgqTrS" - "yv//////////AgECAoIBgH//////////5IftURC0YRpiYzFFwG4OaJSBJwRFM+Y6" - "AQXfUx2JzZEopQQ8xxoCbvfKjNnmnSGNmBWFNvkvihun8Jq2tqjhIvJC2rsxLz9j" - "eiYhdNMb9rWF/65begNb9vccNf2tRM/S10+SCL4lj/MklDMo9nItnuEAPlxQsd+C" - "zG0kGw4q6c00ix/UfpJnr8GyrpHuUdbLDjF5qxBCqV3PapSDuEtLNrOGGqclXkwC" - "eLo2BGUMEL4ZSC8jFxtnHfHPO5YMB0MBzZPB0XYD0Ufa4q74N6YpZO8V5ftKrAuM" - "HMqkvnVKtXKK6RMMTH0CiAq5Ry1FVWIW1pmLhoIoPRnUKpDV745dMnZ9woIsbfeF" - "RXU4q66DBj7Zy4fC03DyY9X610ZthJnrj0ZKcCUSsM7ncekTDWl3NfiX/QNsxQQy" - "bDsBOZ9kNTIpD5WMC72QBl3wi6u9MK62O4TEYF1so3EEcSfQOnLVmKHtrf5wfohH" - "JcFokFSdaWV//////////w==" - "-----END X942 DH PARAMETERS-----"); - - config.set("dl", "modp/srp/3072", - "-----BEGIN DH PARAMETERS-----" - "MIIBiAKCAYEA///////////JD9qiIWjCNMTGYouA3BzRKQJOCIpnzHQCC76mOxOb" - "IlFKCHmONATd75UZs806QxswKwpt8l8UN0/hNW1tUcJF5IW1dmJefsb0TELppjft" - "awv/XLb0Brft7jhr+1qJn6WunyQRfEsf5kkoZlHs5Fs9wgB8uKFjvwWY2kg2HFXT" - "mmkWP6j9JM9fg2VdI9yjrZYcYvNWIIVSu57VKQdwlpZtZww1Tkq8mATxdGwIyhgh" - "fDKQXkYuNs474553LBgOhgObJ4Oi7Aeij7XFXfBvTFLJ3ivL9pVYFxg5lUl86pVq" - "5RXSJhiY+gUQFXKOWoqqxC2tMxcNBFB6M6hVIavfHLpk7PuFBFjb7wqK6nFXXQYM" - "fbOXD4Wm4eTHq/WujNsJM9cejJTgSiVhnc7j0iYa0u5r8S/6BtmKCGTYdgJzPshq" - "ZFIfKxgXeyAMu+EXV3phXWx3CYjAutlG4gjiT6B05asxQ9tb/OD9EI5LgtEgqTrS" - "yv//////////AgEF" - "-----END DH PARAMETERS-----"); - - config.set("dl", "modp/ietf/4096", - "-----BEGIN X942 DH PARAMETERS-----" - "MIIEDAKCAgEA///////////JD9qiIWjCNMTGYouA3BzRKQJOCIpnzHQCC76mOxOb" - "IlFKCHmONATd75UZs806QxswKwpt8l8UN0/hNW1tUcJF5IW1dmJefsb0TELppjft" - "awv/XLb0Brft7jhr+1qJn6WunyQRfEsf5kkoZlHs5Fs9wgB8uKFjvwWY2kg2HFXT" - "mmkWP6j9JM9fg2VdI9yjrZYcYvNWIIVSu57VKQdwlpZtZww1Tkq8mATxdGwIyhgh" - "fDKQXkYuNs474553LBgOhgObJ4Oi7Aeij7XFXfBvTFLJ3ivL9pVYFxg5lUl86pVq" - "5RXSJhiY+gUQFXKOWoqqxC2tMxcNBFB6M6hVIavfHLpk7PuFBFjb7wqK6nFXXQYM" - "fbOXD4Wm4eTHq/WujNsJM9cejJTgSiVhnc7j0iYa0u5r8S/6BtmKCGTYdgJzPshq" - "ZFIfKxgXeyAMu+EXV3phXWx3CYjAutlG4gjiT6B05asxQ9tb/OD9EI5LgtEgqSEI" - "ARpyPBKnh+bXiHGaEL26WyaZwycYavTiPBqUaDS2FQvaJYPpyirUTOjbu8LbBN6O" - "+S6O/BQfvsqmKHxZR05rwF2ZspZPoJDDoiM7oYZRW+ftH2EpcM7i16+4G912IXBI" - "HNAGkSfVsFqpk7TqmI2P3cGG/7fckKbAj030Nck0BjGZ//////////8CAQICggIA" - "f//////////kh+1RELRhGmJjMUXAbg5olIEnBEUz5joBBd9THYnNkSilBDzHGgJu" - "98qM2eadIY2YFYU2+S+KG6fwmra2qOEi8kLauzEvP2N6JiF00xv2tYX/rlt6A1v2" - "9xw1/a1Ez9LXT5IIviWP8ySUMyj2ci2e4QA+XFCx34LMbSQbDirpzTSLH9R+kmev" - "wbKuke5R1ssOMXmrEEKpXc9qlIO4S0s2s4YapyVeTAJ4ujYEZQwQvhlILyMXG2cd" - "8c87lgwHQwHNk8HRdgPRR9rirvg3pilk7xXl+0qsC4wcyqS+dUq1corpEwxMfQKI" - "CrlHLUVVYhbWmYuGgig9GdQqkNXvjl0ydn3Cgixt94VFdTirroMGPtnLh8LTcPJj" - "1frXRm2EmeuPRkpwJRKwzudx6RMNaXc1+Jf9A2zFBDJsOwE5n2Q1MikPlYwLvZAG" - "XfCLq70wrrY7hMRgXWyjcQRxJ9A6ctWYoe2t/nB+iEclwWiQVJCEAI05HglTw/Nr" - "xDjNCF7dLZNM4ZOMNXpxHg1KNBpbCoXtEsH05RVqJnRt3eFtgm9HfJdHfgoP32VT" - "FD4so6c14C7M2Usn0Ehh0RGd0MMorfP2j7CUuGdxa9fcDe67ELgkDmgDSJPq2C1U" - "ydp1TEbH7uDDf9vuSFNgR6b6GuSaAxjM//////////8=" - "-----END X942 DH PARAMETERS-----"); - - config.set("dl", "modp/srp/4096", - "-----BEGIN DH PARAMETERS-----" - "MIICCAKCAgEA///////////JD9qiIWjCNMTGYouA3BzRKQJOCIpnzHQCC76mOxOb" - "IlFKCHmONATd75UZs806QxswKwpt8l8UN0/hNW1tUcJF5IW1dmJefsb0TELppjft" - "awv/XLb0Brft7jhr+1qJn6WunyQRfEsf5kkoZlHs5Fs9wgB8uKFjvwWY2kg2HFXT" - "mmkWP6j9JM9fg2VdI9yjrZYcYvNWIIVSu57VKQdwlpZtZww1Tkq8mATxdGwIyhgh" - "fDKQXkYuNs474553LBgOhgObJ4Oi7Aeij7XFXfBvTFLJ3ivL9pVYFxg5lUl86pVq" - "5RXSJhiY+gUQFXKOWoqqxC2tMxcNBFB6M6hVIavfHLpk7PuFBFjb7wqK6nFXXQYM" - "fbOXD4Wm4eTHq/WujNsJM9cejJTgSiVhnc7j0iYa0u5r8S/6BtmKCGTYdgJzPshq" - "ZFIfKxgXeyAMu+EXV3phXWx3CYjAutlG4gjiT6B05asxQ9tb/OD9EI5LgtEgqSEI" - "ARpyPBKnh+bXiHGaEL26WyaZwycYavTiPBqUaDS2FQvaJYPpyirUTOjbu8LbBN6O" - "+S6O/BQfvsqmKHxZR05rwF2ZspZPoJDDoiM7oYZRW+ftH2EpcM7i16+4G912IXBI" - "HNAGkSfVsFqpk7TqmI2P3cGG/7fckKbAj030Nck0BjGZ//////////8CAQU=" - "-----END DH PARAMETERS-----"); - - config.set("dl", "modp/ietf/6144", - "-----BEGIN X942 DH PARAMETERS-----" - "MIIGDAKCAwEA///////////JD9qiIWjCNMTGYouA3BzRKQJOCIpnzHQCC76mOxOb" - "IlFKCHmONATd75UZs806QxswKwpt8l8UN0/hNW1tUcJF5IW1dmJefsb0TELppjft" - "awv/XLb0Brft7jhr+1qJn6WunyQRfEsf5kkoZlHs5Fs9wgB8uKFjvwWY2kg2HFXT" - "mmkWP6j9JM9fg2VdI9yjrZYcYvNWIIVSu57VKQdwlpZtZww1Tkq8mATxdGwIyhgh" - "fDKQXkYuNs474553LBgOhgObJ4Oi7Aeij7XFXfBvTFLJ3ivL9pVYFxg5lUl86pVq" - "5RXSJhiY+gUQFXKOWoqqxC2tMxcNBFB6M6hVIavfHLpk7PuFBFjb7wqK6nFXXQYM" - "fbOXD4Wm4eTHq/WujNsJM9cejJTgSiVhnc7j0iYa0u5r8S/6BtmKCGTYdgJzPshq" - "ZFIfKxgXeyAMu+EXV3phXWx3CYjAutlG4gjiT6B05asxQ9tb/OD9EI5LgtEgqSEI" - "ARpyPBKnh+bXiHGaEL26WyaZwycYavTiPBqUaDS2FQvaJYPpyirUTOjbu8LbBN6O" - "+S6O/BQfvsqmKHxZR05rwF2ZspZPoJDDoiM7oYZRW+ftH2EpcM7i16+4G912IXBI" - "HNAGkSfVsFqpk7TqmI2P3cGG/7fckKbAj030Nck0AoSSNsP6tNJ8cCbB1NyyYCZG" - "3sl1HnY9uje9+P+UBq2eUw7l2zgvQTABrrBqU+2QJ9gxF5cnsIZaiRjaPtvrz5sU" - "7UTObLrO1Lsb238UR+bMJUszIFFRK9evQm+49AE3jNK/WYPKAcZLkuzwMuoV0XId" - "A/SC185udP721V5wL0aYDIK1qEAxkAscnlnnyX++x+jzI6l6fjbMiL4PHUW3/1ha" - "xUvUB7IrQVSqzI9tfr9I4dgUzF7SD4A34KeXFe7ym+MoBqHVi7fF2nb1UKo9ih+/" - "8OsZzLGjE9Vc2lbJ7C7yljI4f+jXbjwEaAQ+j2Y/SGDuEr8tWwt0dNbmlPkebcxA" - "JP//////////AoIDAH//////////5IftURC0YRpiYzFFwG4OaJSBJwRFM+Y6AQXf" - "Ux2JzZEopQQ8xxoCbvfKjNnmnSGNmBWFNvkvihun8Jq2tqjhIvJC2rsxLz9jeiYh" - "dNMb9rWF/65begNb9vccNf2tRM/S10+SCL4lj/MklDMo9nItnuEAPlxQsd+CzG0k" - "Gw4q6c00ix/UfpJnr8GyrpHuUdbLDjF5qxBCqV3PapSDuEtLNrOGGqclXkwCeLo2" - "BGUMEL4ZSC8jFxtnHfHPO5YMB0MBzZPB0XYD0Ufa4q74N6YpZO8V5ftKrAuMHMqk" - "vnVKtXKK6RMMTH0CiAq5Ry1FVWIW1pmLhoIoPRnUKpDV745dMnZ9woIsbfeFRXU4" - "q66DBj7Zy4fC03DyY9X610ZthJnrj0ZKcCUSsM7ncekTDWl3NfiX/QNsxQQybDsB" - "OZ9kNTIpD5WMC72QBl3wi6u9MK62O4TEYF1so3EEcSfQOnLVmKHtrf5wfohHJcFo" - "kFSQhACNOR4JU8Pza8Q4zQhe3S2TTOGTjDV6cR4NSjQaWwqF7RLB9OUVaiZ0bd3h" - "bYJvR3yXR34KD99lUxQ+LKOnNeAuzNlLJ9BIYdERndDDKK3z9o+wlLhncWvX3A3u" - "uxC4JA5oA0iT6tgtVMnadUxGx+7gw3/b7khTYEem+hrkmgFCSRth/VppPjgTYOpu" - "WTATI29kuo87Ht0b3vx/ygNWzymHcu2cF6CYANdYNSn2yBPsGIvLk9hDLUSMbR9t" - "9efNinaiZzZdZ2pdje2/iiPzZhKlmZAoqJXr16E33HoAm8ZpX6zB5QDjJcl2eBl1" - "Cui5DoH6QWvnNzp/e2qvOBejTAZBWtQgGMgFjk8s8+S/32P0eZHUvT8bZkRfB46i" - "2/+sLWKl6gPZFaCqVWZHtr9fpHDsCmYvaQfAG/BTy4r3eU3xlANQ6sXb4u07eqhV" - "HsUP3/h1jOZY0Ynqrm0rZPYXeUsZHD/0a7ceAjQCH0ezH6Qwdwlflq2Fujprc0p8" - "jzbmIBJ//////////wIBAg==" - "-----END X942 DH PARAMETERS-----"); - - config.set("dl", "modp/srp/6144", - "-----BEGIN DH PARAMETERS-----" - "MIIDCAKCAwEA///////////JD9qiIWjCNMTGYouA3BzRKQJOCIpnzHQCC76mOxOb" - "IlFKCHmONATd75UZs806QxswKwpt8l8UN0/hNW1tUcJF5IW1dmJefsb0TELppjft" - "awv/XLb0Brft7jhr+1qJn6WunyQRfEsf5kkoZlHs5Fs9wgB8uKFjvwWY2kg2HFXT" - "mmkWP6j9JM9fg2VdI9yjrZYcYvNWIIVSu57VKQdwlpZtZww1Tkq8mATxdGwIyhgh" - "fDKQXkYuNs474553LBgOhgObJ4Oi7Aeij7XFXfBvTFLJ3ivL9pVYFxg5lUl86pVq" - "5RXSJhiY+gUQFXKOWoqqxC2tMxcNBFB6M6hVIavfHLpk7PuFBFjb7wqK6nFXXQYM" - "fbOXD4Wm4eTHq/WujNsJM9cejJTgSiVhnc7j0iYa0u5r8S/6BtmKCGTYdgJzPshq" - "ZFIfKxgXeyAMu+EXV3phXWx3CYjAutlG4gjiT6B05asxQ9tb/OD9EI5LgtEgqSEI" - "ARpyPBKnh+bXiHGaEL26WyaZwycYavTiPBqUaDS2FQvaJYPpyirUTOjbu8LbBN6O" - "+S6O/BQfvsqmKHxZR05rwF2ZspZPoJDDoiM7oYZRW+ftH2EpcM7i16+4G912IXBI" - "HNAGkSfVsFqpk7TqmI2P3cGG/7fckKbAj030Nck0AoSSNsP6tNJ8cCbB1NyyYCZG" - "3sl1HnY9uje9+P+UBq2eUw7l2zgvQTABrrBqU+2QJ9gxF5cnsIZaiRjaPtvrz5sU" - "7UTObLrO1Lsb238UR+bMJUszIFFRK9evQm+49AE3jNK/WYPKAcZLkuzwMuoV0XId" - "A/SC185udP721V5wL0aYDIK1qEAxkAscnlnnyX++x+jzI6l6fjbMiL4PHUW3/1ha" - "xUvUB7IrQVSqzI9tfr9I4dgUzF7SD4A34KeXFe7ym+MoBqHVi7fF2nb1UKo9ih+/" - "8OsZzLGjE9Vc2lbJ7C7yljI4f+jXbjwEaAQ+j2Y/SGDuEr8tWwt0dNbmlPkebcxA" - "JP//////////AgEF" - "-----END DH PARAMETERS-----"); - - config.set("dl", "modp/ietf/8192", - "-----BEGIN X942 DH PARAMETERS-----" - "MIIIDAKCBAEA///////////JD9qiIWjCNMTGYouA3BzRKQJOCIpnzHQCC76mOxOb" - "IlFKCHmONATd75UZs806QxswKwpt8l8UN0/hNW1tUcJF5IW1dmJefsb0TELppjft" - "awv/XLb0Brft7jhr+1qJn6WunyQRfEsf5kkoZlHs5Fs9wgB8uKFjvwWY2kg2HFXT" - "mmkWP6j9JM9fg2VdI9yjrZYcYvNWIIVSu57VKQdwlpZtZww1Tkq8mATxdGwIyhgh" - "fDKQXkYuNs474553LBgOhgObJ4Oi7Aeij7XFXfBvTFLJ3ivL9pVYFxg5lUl86pVq" - "5RXSJhiY+gUQFXKOWoqqxC2tMxcNBFB6M6hVIavfHLpk7PuFBFjb7wqK6nFXXQYM" - "fbOXD4Wm4eTHq/WujNsJM9cejJTgSiVhnc7j0iYa0u5r8S/6BtmKCGTYdgJzPshq" - "ZFIfKxgXeyAMu+EXV3phXWx3CYjAutlG4gjiT6B05asxQ9tb/OD9EI5LgtEgqSEI" - "ARpyPBKnh+bXiHGaEL26WyaZwycYavTiPBqUaDS2FQvaJYPpyirUTOjbu8LbBN6O" - "+S6O/BQfvsqmKHxZR05rwF2ZspZPoJDDoiM7oYZRW+ftH2EpcM7i16+4G912IXBI" - "HNAGkSfVsFqpk7TqmI2P3cGG/7fckKbAj030Nck0AoSSNsP6tNJ8cCbB1NyyYCZG" - "3sl1HnY9uje9+P+UBq2eUw7l2zgvQTABrrBqU+2QJ9gxF5cnsIZaiRjaPtvrz5sU" - "7UTObLrO1Lsb238UR+bMJUszIFFRK9evQm+49AE3jNK/WYPKAcZLkuzwMuoV0XId" - "A/SC185udP721V5wL0aYDIK1qEAxkAscnlnnyX++x+jzI6l6fjbMiL4PHUW3/1ha" - "xUvUB7IrQVSqzI9tfr9I4dgUzF7SD4A34KeXFe7ym+MoBqHVi7fF2nb1UKo9ih+/" - "8OsZzLGjE9Vc2lbJ7C7yljI4f+jXbjwEaAQ+j2Y/SGDuEr8tWwt0dNbmlPkebb4R" - "WXSjkm8S/uXkOHd8tqky34zYvsTQc7kxujvIMraNndMAdB+nv4r8R+0ldvaTa6Qk" - "ZjqrY5xa5PVoNCO0dCvxyXgjjxbL451lLeP9uL78hIrZIiIuBKQDfAcT61eoGiPw" - "xzRz/GRs6jBrS8vIhi+Dhd36nUt/osCH6HloMwPtW906Bis89bOieKZtKhP4P0T4" - "Ld8xDuB0q2o2RZfomaAlXcFk8xzFCEaFHfmrSBld7X6hsdUQvX7nTXP682vDHs+i" - "aDWQRvTrh5+SQAlDi0gcbNeImgAu1e44K8kZDab8Am5HlVjkR1Z36aqeMFDidlaU" - "38gfVuiAuW5xYMmA3Zjt09///////////wKCBAB//////////+SH7VEQtGEaYmMx" - "RcBuDmiUgScERTPmOgEF31Mdic2RKKUEPMcaAm73yozZ5p0hjZgVhTb5L4obp/Ca" - "trao4SLyQtq7MS8/Y3omIXTTG/a1hf+uW3oDW/b3HDX9rUTP0tdPkgi+JY/zJJQz" - "KPZyLZ7hAD5cULHfgsxtJBsOKunNNIsf1H6SZ6/Bsq6R7lHWyw4xeasQQqldz2qU" - "g7hLSzazhhqnJV5MAni6NgRlDBC+GUgvIxcbZx3xzzuWDAdDAc2TwdF2A9FH2uKu" - "+DemKWTvFeX7SqwLjBzKpL51SrVyiukTDEx9AogKuUctRVViFtaZi4aCKD0Z1CqQ" - "1e+OXTJ2fcKCLG33hUV1OKuugwY+2cuHwtNw8mPV+tdGbYSZ649GSnAlErDO53Hp" - "Ew1pdzX4l/0DbMUEMmw7ATmfZDUyKQ+VjAu9kAZd8IurvTCutjuExGBdbKNxBHEn" - "0Dpy1Zih7a3+cH6IRyXBaJBUkIQAjTkeCVPD82vEOM0IXt0tk0zhk4w1enEeDUo0" - "GlsKhe0SwfTlFWomdG3d4W2Cb0d8l0d+Cg/fZVMUPiyjpzXgLszZSyfQSGHREZ3Q" - "wyit8/aPsJS4Z3Fr19wN7rsQuCQOaANIk+rYLVTJ2nVMRsfu4MN/2+5IU2BHpvoa" - "5JoBQkkbYf1aaT44E2DqblkwEyNvZLqPOx7dG978f8oDVs8ph3LtnBegmADXWDUp" - "9sgT7BiLy5PYQy1EjG0fbfXnzYp2omc2XWdqXY3tv4oj82YSpZmQKKiV69ehN9x6" - "AJvGaV+sweUA4yXJdngZdQrouQ6B+kFr5zc6f3tqrzgXo0wGQVrUIBjIBY5PLPPk" - "v99j9HmR1L0/G2ZEXweOotv/rC1ipeoD2RWgqlVmR7a/X6Rw7ApmL2kHwBvwU8uK" - "93lN8ZQDUOrF2+LtO3qoVR7FD9/4dYzmWNGJ6q5tK2T2F3lLGRw/9Gu3HgI0Ah9H" - "sx+kMHcJX5athbo6a3NKfI823wisulHJN4l/cvIcO75bVJlvxmxfYmg53JjdHeQZ" - "W0bO6YA6D9PfxX4j9pK7e0m10hIzHVWxzi1yerQaEdo6FfjkvBHHi2XxzrKW8f7c" - "X35CRWyRERcCUgG+A4n1q9QNEfhjmjn+MjZ1GDWl5eRDF8HC7v1Opb/RYEP0PLQZ" - "gfat7p0DFZ562dE8UzaVCfwfonwW75iHcDpVtRsiy/RM0BKu4LJ5jmKEI0KO/NWk" - "DK72v1DY6ohev3Omuf15teGPZ9E0GsgjenXDz8kgBKHFpA42a8RNABdq9xwV5IyG" - "034BNyPKrHIjqzv01U8YKHE7K0pv5A+rdEBctziwZMBuzHbp7///////////AgEC" - "-----END X942 DH PARAMETERS-----"); - - config.set("dl", "modp/srp/8192", - "-----BEGIN DH PARAMETERS-----" - "MIIECAKCBAEA///////////JD9qiIWjCNMTGYouA3BzRKQJOCIpnzHQCC76mOxOb" - "IlFKCHmONATd75UZs806QxswKwpt8l8UN0/hNW1tUcJF5IW1dmJefsb0TELppjft" - "awv/XLb0Brft7jhr+1qJn6WunyQRfEsf5kkoZlHs5Fs9wgB8uKFjvwWY2kg2HFXT" - "mmkWP6j9JM9fg2VdI9yjrZYcYvNWIIVSu57VKQdwlpZtZww1Tkq8mATxdGwIyhgh" - "fDKQXkYuNs474553LBgOhgObJ4Oi7Aeij7XFXfBvTFLJ3ivL9pVYFxg5lUl86pVq" - "5RXSJhiY+gUQFXKOWoqqxC2tMxcNBFB6M6hVIavfHLpk7PuFBFjb7wqK6nFXXQYM" - "fbOXD4Wm4eTHq/WujNsJM9cejJTgSiVhnc7j0iYa0u5r8S/6BtmKCGTYdgJzPshq" - "ZFIfKxgXeyAMu+EXV3phXWx3CYjAutlG4gjiT6B05asxQ9tb/OD9EI5LgtEgqSEI" - "ARpyPBKnh+bXiHGaEL26WyaZwycYavTiPBqUaDS2FQvaJYPpyirUTOjbu8LbBN6O" - "+S6O/BQfvsqmKHxZR05rwF2ZspZPoJDDoiM7oYZRW+ftH2EpcM7i16+4G912IXBI" - "HNAGkSfVsFqpk7TqmI2P3cGG/7fckKbAj030Nck0AoSSNsP6tNJ8cCbB1NyyYCZG" - "3sl1HnY9uje9+P+UBq2eUw7l2zgvQTABrrBqU+2QJ9gxF5cnsIZaiRjaPtvrz5sU" - "7UTObLrO1Lsb238UR+bMJUszIFFRK9evQm+49AE3jNK/WYPKAcZLkuzwMuoV0XId" - "A/SC185udP721V5wL0aYDIK1qEAxkAscnlnnyX++x+jzI6l6fjbMiL4PHUW3/1ha" - "xUvUB7IrQVSqzI9tfr9I4dgUzF7SD4A34KeXFe7ym+MoBqHVi7fF2nb1UKo9ih+/" - "8OsZzLGjE9Vc2lbJ7C7yljI4f+jXbjwEaAQ+j2Y/SGDuEr8tWwt0dNbmlPkebb4R" - "WXSjkm8S/uXkOHd8tqky34zYvsTQc7kxujvIMraNndMAdB+nv4r8R+0ldvaTa6Qk" - "ZjqrY5xa5PVoNCO0dCvxyXgjjxbL451lLeP9uL78hIrZIiIuBKQDfAcT61eoGiPw" - "xzRz/GRs6jBrS8vIhi+Dhd36nUt/osCH6HloMwPtW906Bis89bOieKZtKhP4P0T4" - "Ld8xDuB0q2o2RZfomaAlXcFk8xzFCEaFHfmrSBld7X6hsdUQvX7nTXP682vDHs+i" - "aDWQRvTrh5+SQAlDi0gcbNeImgAu1e44K8kZDab8Am5HlVjkR1Z36aqeMFDidlaU" - "38gfVuiAuW5xYMmA3Zjt09///////////wIBEw==" - "-----END DH PARAMETERS-----"); - - config.set("dl", "dsa/jce/512", - "-----BEGIN DSA PARAMETERS-----" - "MIGdAkEA/KaCzo4Syrom78z3EQ5SbbB4sF7ey80etKII864WF64B81uRpH5t9jQT" - "xeEu0ImbzRMqzVDZkVG9xD7nN1kuFwIVAJYu3cw2nLqOuyYO5rahJtk0bjjFAkEA" - "3gtU76vylwh+5iPVylWIxkgo70/eT/uuHs0gBndrBbEbgeo83pvDlkwWh8UyW/Q9" - "fM76DQqGvl3/3dDRFD3NdQ==" - "-----END DSA PARAMETERS-----"); - - config.set("dl", "dsa/jce/768", - "-----BEGIN DSA PARAMETERS-----" - "MIHdAmEA6eZCWZ01XzfJf/01ZxILjiXJzUPpJ7OpZw++xdiQFBki0sOzrSSACTeZ" - "hp0ehGqrSfqwrSbSzmoiIZ1HC859d31KIfvpwnC1f2BwAvPO+Dk2lM9F7jaIwRqM" - "VqsSej2vAhUAnNvYTJ8awvOND4D0KrlS5zOL9RECYQDe7p717RUWzn5pXmcrjO5F" - "5s17NuDmOF+JS6hhY/bz5sbU6KgRRtQBfe/dccvZD6Akdlm4i3zByJT0gmn9Txqs" - "CjBTjf9rP8ds+xMcnnlltYhYqwpDtVczWRKoqlR/lWg=" - "-----END DSA PARAMETERS-----"); - - config.set("dl", "dsa/jce/1024", - "-----BEGIN DSA PARAMETERS-----" - "MIIBHgKBgQD9f1OBHXUSKVLfSpwu7OTn9hG3UjzvRADDHj+AtlEmaUVdQCJR+1k9" - "jVj6v8X1ujD2y5tVbNeBO4AdNG/yZmC3a5lQpaSfn+gEexAiwk+7qdf+t8Yb+DtX" - "58aophUPBPuD9tPFHsMCNVQTWhaRMvZ1864rYdcq7/IiAxmd0UgBxwIVAJdgUI8V" - "IwvMspK5gqLrhAvwWBz1AoGARpYDUS4wJ4zTlHWV2yLuyYJqYyKtyXNE9B10DDJX" - "JMj577qn1NgD/4xgnc0QDrxb38+tfGpCX66nhuogUOvpg1HqH9of3yTWlHqmuaoj" - "dmlTgC9NfUqOy6BtGXaKJJH/sW0O+cQ6mbX3FnL/bwoktETQc20E04oaEyLa9s3Y" - "jJ0=" - "-----END DSA PARAMETERS-----"); - - config.set("dl", "dsa/botan/2048", - "-----BEGIN DSA PARAMETERS-----" - "MIICLAKCAQEAkcSKT9+898Aq6V59oSYSK13Shk9Vm4fo50oobVL1m9HeaN/WRdDg" - "DGDAgAMYkZgDdO61lKUyv9Z7mgnqxLhmOgeRDmjzlGX7cEDSXfE5MuusQ0elMOy6" - "YchU+biA08DDZgCAWHxFVm2t4mvVo5S+CTtMDyS1r/747GxbPlf7iQJam8FnaZMh" - "MeFtPJTvyrGNDfBhIDzFPmEDvHLVWUv9QMplOA9EqahR3LB1SV/AM6ilgHGhvXj+" - "BS9mVVZI60txnSr+i0iA+NrW8VgYuhePiSdMhwvpuW6wjEbEAEDMLv4d+xsYaN0x" - "nePDSjKmOrbrEiQgmkGWgMx5AtFyjU354QIhAIzX1FD4bwrZTu5M5GmodW0evRBY" - "JBlD6v+ws1RYXpJNAoIBAA2fXgdhtNvRgz1qsalhoJlsXyIwP3LYTBQPZ8Qx2Uq1" - "cVvqgaDJjTnOS8941rnryJXTT+idlAkdWEhhXvFfXobxHZb2yWniA936WDVkIKSc" - "tES1lbkBqTPP4HZ7WU8YoHt/kd7NukRriJkPePL/kfL+fNQ/0uRtGOraH3u2YCxh" - "f27zpLKE8v2boQo2BC3o+oeiyjZZf+yBFXoUheRAQd8CgwERy4gLvm7UlIFIhvll" - "zcMTX1zPE4Nyi/ZbgG+WksCxDWxMCcdabKO0ATyxarLBBfa+I66pAA6rIXiYX5cs" - "mAV+HIbkTnIYaI6krg82NtzKdFydzU5q/7Z8y8E9YTE=" - "-----END DSA PARAMETERS-----"); - - config.set("dl", "dsa/botan/3072", - "-----BEGIN DSA PARAMETERS-----" - "MIIDLAKCAYEA5LUIgHWWY1heFCRgyi2d/xMviuTIQN2jomZoiRJP5WOLhOiim3rz" - "+hIJvmv8S1By7Tsrc4e68/hX9HioAijvNgC3az3Pth0g00RlslBtLK+H3259wM6R" - "vS0Wekb2rcwxxTHk+cervbkq3fNbCoBsZikqX14X6WTdCZkDczrEKKs12A6m9oW/" - "uovkBo5UGK5eytno/wc94rY+Tn6tNciptwtb1Hz7iNNztm83kxk5sKtxvVWVgJCG" - "2gFVM30YWg5Ps2pRmxtiArhZHmACRJzxzTpmOE9tIHOxzXO+ypO68eGmEX0COPIi" - "rh7X/tGFqJDn9n+rj+uXU8wTSlGD3+h64llfe1wtn7tCJJ/dWVE+HTOWs+sv2GaE" - "8oWoRI/nV6ApiBxAdguU75Gb35dAw4OJWZ7FGm6btRmo4GhJHpzgovz+PLYNZs8N" - "+tIKjsaEBIaEphREV1vRck1zUrRKdgB3s71r04XOWwpyUMwL92jagpI4Buuc+7E4" - "hDcxthggjHWbAiEAs+vTZOxp74zzuvZDt1c0sWM5suSeXN4bWcHp+0DuDFsCggGA" - "K+0h7vg5ZKIwrom7px2ffDnFL8gim047x+WUTTKdoQ8BDqyee69sAJ/E6ylgcj4r" - "Vt9GY+TDrIAOkljeL3ZJ0gZ4KJP4Ze/KSY0u7zAHTqXop6smJxKk2UovOwuaku5A" - "D7OKPMWaXcfkNtXABLIuNQKDgbUck0B+sy1K4P1Cy0XhLQ7O6KJiOO3iCCp7FSIR" - "PGbO+NdFxs88uUX4TS9N4W1Epx3hmCcOE/A1U8iLjTI60LlIob8hA6lJl5tu0W+1" - "88lT2Vt8jojKZ9z1pjb7nKOdkkIV96iE7Wx+48ltjZcVQnl0t8Q1EoLhPTdz99KL" - "RS8QiSoTx1hzKN6kgntrNpsqjcFyrcWD9R8qZZjFSD5bxGewL5HQWcQC0Y4sJoD3" - "dqoG9JKAoscsF8xC1bbnQMXEsas8UcLtCSviotiwU65Xc9FCXtKwjwbi3VBZLfGk" - "eMFVkc39EVZP+I/zi3IdQjkv2kcyEtz9jS2IqXagCv/m//tDCjWeZMorNRyiQSOU" - "-----END DSA PARAMETERS-----"); - - config.set("ec", "secp112r1", - "-----BEGIN EC PARAMETERS-----" - "MHQCAQEwGgYHKoZIzj0BAQIPANt8Kr9i415mgHa+rSCLMCAEDtt8Kr9i415mgHa+" - "rSCIBA5lnvi6BDkW7t6JEXArIgQdBAlIcjmZWl7na1X5wvCYqJzlr4ckwKI+Dg/3" - "dQACDwDbfCq/YuNedijfrGVhxQIBAQ==" - "-----END EC PARAMETERS-----"); - - config.set("ec", "secp112r2", - "-----BEGIN EC PARAMETERS-----" - "MHMCAQEwGgYHKoZIzj0BAQIPANt8Kr9i415mgHa+rSCLMCAEDmEnwkwF84oKqvZc" - "DvAsBA5R3vGBXbXtdPzDTIXXCQQdBEujCrXokrThZJ3QkoZDrc1G9YguN0fe826V" - "bpcCDjbfCq/YuNdZfKEFINBLAgEB" - "-----END EC PARAMETERS-----"); - - config.set("ec", "secp128r1", - "-----BEGIN EC PARAMETERS-----" - "MIGAAgEBMBwGByqGSM49AQECEQD////9////////////////MCQEEP////3/////" - "//////////wEEOh1ecEQefQ92CSZPCzuXtMEIQQWH/dSi4mbLQwoYHylLFuGz1rI" - "OVuv6xPALaKS3e16gwIRAP////4AAAAAdaMNG5A4oRUCAQE=" - "-----END EC PARAMETERS-----"); - - config.set("ec", "secp128r2", - "-----BEGIN EC PARAMETERS-----" - "MH8CAQEwHAYHKoZIzj0BAQIRAP////3///////////////8wJAQQ1gMZmNGzu/6/" - "Wcybv/mu4QQQXu78o4DQKRncLGVYu22KXQQhBHtqpdheVymD5vsyp83rwUAntpFq" - "iU067nEG/oBfw0tEAhA/////f////74AJHIGE7WjAgEE" - "-----END EC PARAMETERS-----"); - - config.set("ec", "secp160k1", - "-----BEGIN EC PARAMETERS-----" - "MIGYAgEBMCAGByqGSM49AQECFQD////////////////////+//+sczAsBBQAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAQUAAAAAAAAAAAAAAAAAAAAAAAAAAcEKQQ7TDgs43qh" - "kqQBnnYwNvT13U1+u5OM+TUxj9zta8KChlMXM8PwPE/uAhUBAAAAAAAAAAAAAbj6" - "Ft+rmsoWtrMCAQE=" - "-----END EC PARAMETERS-----"); - - config.set("ec", "secp160r1", - "-----BEGIN EC PARAMETERS-----" - "MIGYAgEBMCAGByqGSM49AQECFQD/////////////////////f////zAsBBT/////" - "////////////////f////AQUHJe+/FS9eotlrPifgdTUrcVl+kUEKQRKlrVojvVz" - "KEZkaYlow4u5E8v8giOmKFUxaJR9WdzJEgQjUTd6xfsyAhUBAAAAAAAAAAAAAfTI" - "+Seu08p1IlcCAQE=" - "-----END EC PARAMETERS-----"); - - config.set("ec", "secp160r2", - "-----BEGIN EC PARAMETERS-----" - "MIGYAgEBMCAGByqGSM49AQECFQD////////////////////+//+sczAsBBT/////" - "///////////////+//+scAQUtOE00/tZ64urVydJBGZNWvUDiLoEKQRS3LA0KToR" - "fh9P8Rsw9xmdMUTObf6v/vLjMfKW4HH6DfmYLP6n1D8uAhUBAAAAAAAAAAAAADUe" - "54aoGPOhoWsCAQE=" - "-----END EC PARAMETERS-----"); - - config.set("ec", "secp192k1", - "-----BEGIN EC PARAMETERS-----" - "MIGwAgEBMCQGByqGSM49AQECGQD//////////////////////////v//7jcwNAQY" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBgAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAMEMQTbT/EOwFfpriawfQKAt/Q0HaXRsergbH2bLy9tnFYop4RBY9AVvoY0QIKq" - "iNleL50CGQD///////////////4m8vwXD2lGanTe/Y0CAQE=" - "-----END EC PARAMETERS-----"); - - config.set("ec", "secp192r1", - "-----BEGIN EC PARAMETERS-----" - "MIGwAgEBMCQGByqGSM49AQECGQD////////////////////+//////////8wNAQY" - "/////////////////////v/////////8BBhkIQUZ5ZyA5w+n6atyJDBJ/rje7MFG" - "ubEEMQQYjagOsDCQ9ny/IOtDoYgA9P8K/YL/EBIHGSuV/8jaeGMQEe1rJM3Vc/l3" - "oR55SBECGQD///////////////+Z3vg2FGvJsbTSKDECAQE=" - "-----END EC PARAMETERS-----"); - - config.set("ec", "secp224k1", - "-----BEGIN EC PARAMETERS-----" - "MIHIAgEBMCgGByqGSM49AQECHQD///////////////////////////////7//+Vt" - "MDwEHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEHAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAUEOQShRVszTfCZ3zD8KKFppGfp5HB1qQ9+ZQ62t6Rcfgif" - "7X+6NEKCyvvW9+MZ98CwvVniykvbVW1hpQIdAQAAAAAAAAAAAAAAAAAB3OjS7GGE" - "yvCpcXafsfcCAQE=" - "-----END EC PARAMETERS-----"); - - config.set("ec", "secp224r1", - "-----BEGIN EC PARAMETERS-----" - "MIHIAgEBMCgGByqGSM49AQECHQD/////////////////////AAAAAAAAAAAAAAAB" - "MDwEHP////////////////////7///////////////4EHLQFCoUMBLOr9UEyVlBE" - "sLfXv9i6Jws5QyNV/7QEOQS3Dgy9a7S/fzITkLlKA8HTVsIRIjQygNYRXB0hvTdj" - "iLX3I/tMIt/mzUN1oFoHR2RE1YGZhQB+NAIdAP//////////////////FqLguPA+" - "E90pRVxcKj0CAQE=" - "-----END EC PARAMETERS-----"); - - config.set("ec", "secp256k1", - "-----BEGIN EC PARAMETERS-----" - "MIHgAgEBMCwGByqGSM49AQECIQD////////////////////////////////////+" - "///8LzBEBCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQgAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcEQQR5vmZ++dy7rFWgYpXOhwsHApv8" - "2y3OKNlZ8oFbFvgXmEg62ncmo8RlXaT7/A4RCKj9F7RIpoVUGZxH0I/7ENS4AiEA" - "/////////////////////rqu3OavSKA7v9JejNA2QUECAQE=" - "-----END EC PARAMETERS-----"); - - config.set("ec", "secp256r1", - "-----BEGIN EC PARAMETERS-----" - "MIHgAgEBMCwGByqGSM49AQECIQD/////AAAAAQAAAAAAAAAAAAAAAP//////////" - "/////zBEBCD/////AAAAAQAAAAAAAAAAAAAAAP///////////////AQgWsY12Ko6" - "k+ez671VdpiGvGUdBrDMU7D2O848PifSYEsEQQRrF9Hy4SxCR/i85uVjpEDydwN9" - "gS3rM6D0oTlF2JjClk/jQuL+Gn+bjufrSnwPnhYrzjNXazFezsu2QGg3v1H1AiEA" - "/////wAAAAD//////////7zm+q2nF56E87nKwvxjJVECAQE=" - "-----END EC PARAMETERS-----"); - - config.set("ec", "secp384r1", - "-----BEGIN EC PARAMETERS-----" - "MIIBQAIBATA8BgcqhkjOPQEBAjEA////////////////////////////////////" - "//////7/////AAAAAAAAAAD/////MGQEMP//////////////////////////////" - "///////////+/////wAAAAAAAAAA/////AQwszEvp+I+5+SYjgVr4/gtGRgdnG7+" - "gUESAxQIj1ATh1rGVjmNii7RnSqFyO3T7CrvBGEEqofKIr6LBTeOscce8yCtdG4d" - "O2KLp5uYWfdB4IJUKjhVAvJdv1UpbDpUXjhydgq3NhfeSpYmLG9dnpi/kpLcKfj0" - "Hb0omhR86doxE7XwuMAKYLHOHX6BnXpDHXyQ6g5fAjEA////////////////////" - "////////////x2NNgfQ3Ld9YGg2ySLCneuzsGWrMxSlzAgEB" - "-----END EC PARAMETERS-----"); - - config.set("ec", "secp521r1", - "-----BEGIN EC PARAMETERS-----" - "MIIBrAIBATBNBgcqhkjOPQEBAkIB////////////////////////////////////" - "//////////////////////////////////////////////////8wgYgEQgH/////" - "////////////////////////////////////////////////////////////////" - "/////////////////ARCAFGVPrlhjhyaH5KaIaC2hUDuotpyW5mzFfO4tImRjvEJ" - "4VYZOVHsfpN7FlLAvTuxvwc1c9+IPSw08e9FH9RrUD8ABIGFBADGhY4GtwQE6c2e" - "PstmI5W0QpxkgTkFP7Uh+CivYGtNPbqhS1537+dZKP4dwSei/6jeM0izwYVqQpv5" - "fn4xwuW9ZgEYOSlqeJo7wARcil+0LH0b2Zj1RElXm0RoF6+9Fyc+ZiyX7nKZXvQm" - "QMVQuQE/rQdhNTxwhqJywkCIvpR2n9FmUAJCAf//////////////////////////" - "////////////////+lGGh4O/L5Zrf8wBSPcJpdA7tcm4iZxHrrtvtx6ROGQJAgEB" - "-----END EC PARAMETERS-----"); - - config.set("ec", "1.3.6.1.4.1.8301.3.1.2.9.0.38", - "-----BEGIN EC PARAMETERS-----" - "MIIBrAIBATBNBgcqhkjOPQEBAkIB////////////////////////////////////" - "//////////////////////////////////////////////////8wgYgEQgH/////" - "////////////////////////////////////////////////////////////////" - "/////////////////ARCAFGVPrlhjhyaH5KaIaC2hUDuotpyW5mzFfO4tImRjvEJ" - "4VYZOVHsfpN7FlLAvTuxvwc1c9+IPSw08e9FH9RrUD8ABIGFBADGhY4GtwQE6c2e" - "PstmI5W0QpxkgTkFP7Uh+CivYGtNPbqhS1537+dZKP4dwSei/6jeM0izwYVqQpv5" - "fn4xwuW9ZgEYOSlqeJo7wARcil+0LH0b2Zj1RElXm0RoF6+9Fyc+ZiyX7nKZXvQm" - "QMVQuQE/rQdhNTxwhqJywkCIvpR2n9FmUAJCAf//////////////////////////" - "////////////////+lGGh4O/L5Zrf8wBSPcJpdA7tcm4iZxHrrtvtx6ROGQJAgEB" - "-----END EC PARAMETERS-----"); - - config.set("ec", "brainpool160r1", - "-----BEGIN EC PARAMETERS-----" - "MIGYAgEBMCAGByqGSM49AQECFQDpXkpfc3BZ3GDfx62Vs9gTlRViDzAsBBQ0Dnvi" - "ooDrdOK+YbradF2X6PfDAAQUHliahZVCNBITT6otveyVyNhnXlgEKQS+1a8W6j9q" - "T2KTjEYx61r3vbzbwxZny0d6Go7DOPlHQWacl2MW2mMhAhUA6V5KX3NwWdxg31mR" - "1FApQJ5g/AkCAQE=" - "-----END EC PARAMETERS-----"); - - config.set("ec", "brainpool192r1", - "-----BEGIN EC PARAMETERS-----" - "MIGwAgEBMCQGByqGSM49AQECGQDDAvQdkyo2zaejRjCT0Y23j85HbeGoYpcwNAQY" - "apEXQHax4OGcOcAx/oaFwcrgQOXGmijvBBhGmijvfCjMo9xyHQRPRJa8yn70FG+/" - "JckEMQTAoGR+qrakh1OwM8VssPCQCi9cSFM3X9YUtpCGar1buItfSCjBSQAC5nc/" - "ovopm48CGQDDAvQdkyo2zaejRi+enpFrW+jxAprErMECAQE=" - "-----END EC PARAMETERS-----"); - - config.set("ec", "brainpool224r1", - "-----BEGIN EC PARAMETERS-----" - "MIHIAgEBMCgGByqGSM49AQECHQDXwTSqJkNmhioYMCV10deHsJ8HV5faifV+yMD/" - "MDwEHGil5iypzmwcKZgDpsFTC1FOGCrYsAQqWcrSn0MEHCWA9jzP5EE4hwcTsakj" - "aeM+ITXSZtuzcjhsQAsEOQQNkCmtLH5c9DQII7KofcaMnkzjF0webv3uEsB9WKpW" - "93LAcm8kxrieTs2sJDVLnpnKo/bTdhQCzQIdANfBNKomQ2aGKhgwJXXQ+5jRFrxL" - "bd68o6Wnk58CAQE=" - "-----END EC PARAMETERS-----"); - - config.set("ec", "brainpool256r1", - "-----BEGIN EC PARAMETERS-----" - "MIHgAgEBMCwGByqGSM49AQECIQCp+1fboe6pvD5mCpCdg41ybjv2I9UmICggE0gd" - "H25TdzBEBCB9Wgl1/CwwV+72dTBBev/n+4BVwSbcXGzpSktE8zC12QQgJtxcbOlK" - "S0TzMLXZu9d8v5WEFilc9+HOa8zcGP+MB7YEQQSL0q65y35XyyxLSC/8gbevud4n" - "4eO9I8I6RFO9ms4yYlR++DXD2sT9l/hGGhRhHcnCd0UTLe2OVFwdVMcvBGmXAiEA" - "qftX26Huqbw+ZgqQnYONcYw5eqO1Yab3kB4OgpdIVqcCAQE=" - "-----END EC PARAMETERS-----"); - - config.set("ec", "brainpool320r1", - "-----BEGIN EC PARAMETERS-----" - "MIIBEAIBATA0BgcqhkjOPQEBAikA015HIDa8T7fhPHhe0gHgZfmPz6b29A3vT5K5" - "7HiT7Cj81BKx8bMuJzBUBCg+4wtWj7qw+IPM69RtPzu4oqc1E/XredpmGQ6whf+p" - "9JLzdal9hg60BChSCIOUnf28QtOtGYZAaIpv4T9BNJVUtJrMMdzNiEU5gW9etKyP" - "sfGmBFEEQ71+mvtT2LhSibzEjuW/5vIBN9EKCH6254ceKhClmccQr40NOeIGERT9" - "0FVF7BzIq0CTJH93J14HQ//tEXGC6qnHeHeqrGrH01JF0WkujuECKQDTXkcgNrxP" - "t+E8eF7SAeBl+Y/PpbaPEqMtSC7H7oZY6YaRVVtExZMRAgEB" - "-----END EC PARAMETERS-----"); - - config.set("ec", "brainpool384r1", - "-----BEGIN EC PARAMETERS-----" - "MIIBQAIBATA8BgcqhkjOPQEBAjEAjLkegqM4bSgPXW9+UOZB3xUvcQntVFa0ErHa" - "GX+3ESOs06cpkB0acYdHABMxB+xTMGQEMHvDgsY9jBUMPHIICs4Fr6DCvqKOT7In" - "hxORZe+6kfkPiqWBSlA61OsEqMfdIs4oJgQwBKjH3SLOKCaLObVUFvBEfC+3feEH" - "3NKmLogOpT7rYtV8tDkCldvJlDq3hpb6UEwRBGEEHRxk8GjPRf+ipjqBt8E/a4hH" - "o+d+8U/j23/K/gy9EOjoJuA0NtZGqu+HsuJH1K8eir4ddSD5wqRcseuOlc/VUmK3" - "Cyn+7Fhk4ZwFT/mRKSgORkYhd5GBEUKCA0EmPFMVAjEAjLkegqM4bSgPXW9+UOZB" - "3xUvcQntVFazHxZubKwEJafPOrava3/DEDuIMgLpBGVlAgEB" - "-----END EC PARAMETERS-----"); - - config.set("ec", "brainpool512r1", - "-----BEGIN EC PARAMETERS-----" - "MIIBogIBATBMBgcqhkjOPQEBAkEAqt2duNvpxIs/1OauM8n8B8swjbOzydIO1mOc" - "ynAzCHF9TZsAm8ZoQq7NoSrmo4DmKIH/Ly2CxoUoqmBWWDpI8zCBhARAeDCjMYtg" - "O4niMnFFrCNMxZTL3Y09+RYQqDRByuqYY7wt7V1aqCU6oQou8cmLmsi1fxEXpyvy" - "x7nnwaxNd/yUygRAPfkWEKg0QcrqmGO8Le1dWqglOqEKLvHJi5rItX8RF6cr8se5" - "58GsTXf8lMrcCD5nmEBQt1665d0oCb1jgBb3IwSBgQSBruS92C7ZZFohMi6cTGqT" - "he2fcLXZFsG0O2Lu9NAJjv87H3ji0NSNUNFoe5O5fV98bVBHQGpeaIs1Igm8ufgi" - "fd44XVZjMuzA6r+pz3gi/fIJ9wAkpXsaoADFW4gfgRGy3N5JSl9IXlvKS9iKJ2Ou" - "0corL6jwVAZ4zR4POtgIkgJBAKrdnbjb6cSLP9TmrjPJ/AfLMI2zs8nSDtZjnMpw" - "MwhwVT5cQUypJhlBhmEZf6wQRx2x04EIXdrdtYeWgpypAGkCAQE=" - "-----END EC PARAMETERS-----"); - - config.set("ec", "x962_p192v2", - "-----BEGIN EC PARAMETERS-----" - "MIGwAgEBMCQGByqGSM49AQECGQD////////////////////+//////////8wNAQY" - "/////////////////////v/////////8BBjMItbfuVxrJeScDWNkpOWYDDk6ohZo" - "2VMEMQTuorrn4Ul4QvLed2nP6cmJwHKtaW9IA0pldNEdabbsemcruCoIPfLysIR9" - "6XCy3hUCGQD///////////////5fsack3IBBhkjY3TECAQE=" - "-----END EC PARAMETERS-----"); - - config.set("ec", "x962_p192v3", - "-----BEGIN EC PARAMETERS-----" - "MIGwAgEBMCQGByqGSM49AQECGQD////////////////////+//////////8wNAQY" - "/////////////////////v/////////8BBgiEj3COVoFyqdCPa7MyUdgp9RiJWvV" - "aRYEMQR9KXeBAMZaHaF4NxZYjc4ri0rujiKPGJY4qQ8iY3M3M0tJ3LZqbcj5l4rK" - "dkipQ7ACGQD///////////////96YtAxyD9ClPZA7BMCAQE=" - "-----END EC PARAMETERS-----"); - - config.set("ec", "x962_p239v1", - "-----BEGIN EC PARAMETERS-----" - "MIHSAgEBMCkGByqGSM49AQECHn///////////////3///////4AAAAAAAH//////" - "/zBABB5///////////////9///////+AAAAAAAB///////wEHmsBbDvc8YlB0NZU" - "khR1ynGp2y+yfR03eWGFwpQsCgQ9BA/6ljzcqIFszDO4ZCvt+QXD01hXPT8n+707" - "PLmqr33r6OTpCl2ubkBUylMLoEZUs2gYziJrOfzLewLxrgIef///////////////" - "f///nl6an12QcfvRUiaIkJ0LAgEB" - "-----END EC PARAMETERS-----"); - - config.set("ec", "x962_p239v2", - "-----BEGIN EC PARAMETERS-----" - "MIHSAgEBMCkGByqGSM49AQECHn///////////////3///////4AAAAAAAH//////" - "/zBABB5///////////////9///////+AAAAAAAB///////wEHmF/q2gyV2y7/tUN" - "mfAknD/uWLlLoAOMeuhMjIMvLAQ9BDivCdmHJ3BRIMkhu16eJilqPNzy81dXoOr9" - "h7gw51sBJeTb6g7HIG2g/AHZsIEyn7VV3m70YCN9/4vkugIef///////////////" - "gAAAz6foWUN31BTAOCG8WCBjAgEB" - "-----END EC PARAMETERS-----"); - - config.set("ec", "x962_p239v3", - "-----BEGIN EC PARAMETERS-----" - "MIHSAgEBMCkGByqGSM49AQECHn///////////////3///////4AAAAAAAH//////" - "/zBABB5///////////////9///////+AAAAAAAB///////wEHiVXBfoqMGZUsfTL" - "A9anUKMMJQEC1JiHF9m6FattPgQ9BGdoro4Yu5LPzwBclJqixtlIU9DmYLv4VLHJ" - "UF/pWhYH5omPOQwGvB1VK60ibztvz+SLboGEma8Y4+1s8wIef///////////////" - "f///l13rQbOmBXw8QyFGUmVRAgEB" - "-----END EC PARAMETERS-----"); - - config.set("ec", "gost_256A", - "-----BEGIN EC PARAMETERS-----" - "MIHgAgEBMCwGByqGSM49AQECIQD/////////////////////////////////////" - "///9lzBEBCD////////////////////////////////////////9lAQgAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKYEQQQAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAY2R5HHgmJzaJ99QWkU/K3Y1KU8t3yPjsSKsyZyenx4UAiEA" - "/////////////////////2xhEHCZWtEARYQbCbdhuJMCAQE=" - "-----END EC PARAMETERS-----"); - } -} - -/* -* Set the default policy -*/ -void Library_State::load_default_config() - { - set_default_aliases(*this); - set_default_oids(*this); - set_default_dl_groups(*this); - } - -} -/* -* SCAN Name Abstraction -* (C) 2008-2009 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include - -namespace Botan { - -namespace { - -std::string make_arg( - const std::vector >& name, size_t start) - { - std::string output = name[start].second; - size_t level = name[start].first; - - size_t paren_depth = 0; - - for(size_t i = start + 1; i != name.size(); ++i) - { - if(name[i].first <= name[start].first) - break; - - if(name[i].first > level) - { - output += '(' + name[i].second; - ++paren_depth; - } - else if(name[i].first < level) - { - output += ")," + name[i].second; - --paren_depth; - } - else - { - if(output[output.size() - 1] != '(') - output += ","; - output += name[i].second; - } - - level = name[i].first; - } - - for(size_t i = 0; i != paren_depth; ++i) - output += ')'; - - return output; - } - -std::pair -deref_aliases(const std::pair& in) - { - return std::make_pair(in.first, - global_state().deref_alias(in.second)); - } - -} - -SCAN_Name::SCAN_Name(std::string algo_spec) - { - orig_algo_spec = algo_spec; - - std::vector > name; - size_t level = 0; - std::pair accum = std::make_pair(level, ""); - - std::string decoding_error = "Bad SCAN name '" + algo_spec + "': "; - - algo_spec = global_state().deref_alias(algo_spec); - - for(size_t i = 0; i != algo_spec.size(); ++i) - { - char c = algo_spec[i]; - - if(c == '/' || c == ',' || c == '(' || c == ')') - { - if(c == '(') - ++level; - else if(c == ')') - { - if(level == 0) - throw Decoding_Error(decoding_error + "Mismatched parens"); - --level; - } - - if(c == '/' && level > 0) - accum.second.push_back(c); - else - { - if(accum.second != "") - name.push_back(deref_aliases(accum)); - accum = std::make_pair(level, ""); - } - } - else - accum.second.push_back(c); - } - - if(accum.second != "") - name.push_back(deref_aliases(accum)); - - if(level != 0) - throw Decoding_Error(decoding_error + "Missing close paren"); - - if(name.size() == 0) - throw Decoding_Error(decoding_error + "Empty name"); - - alg_name = name[0].second; - - bool in_modes = false; - - for(size_t i = 1; i != name.size(); ++i) - { - if(name[i].first == 0) - { - mode_info.push_back(make_arg(name, i)); - in_modes = true; - } - else if(name[i].first == 1 && !in_modes) - args.push_back(make_arg(name, i)); - } - } - -std::string SCAN_Name::algo_name_and_args() const - { - std::string out; - - out = algo_name(); - - if(arg_count()) - { - out += '('; - for(size_t i = 0; i != arg_count(); ++i) - { - out += arg(i); - if(i != arg_count() - 1) - out += ','; - } - out += ')'; - - } - - return out; - } - -std::string SCAN_Name::arg(size_t i) const - { - if(i >= arg_count()) - throw std::range_error("SCAN_Name::argument - i out of range"); - return args[i]; - } - -std::string SCAN_Name::arg(size_t i, const std::string& def_value) const - { - if(i >= arg_count()) - return def_value; - return args[i]; - } - -size_t SCAN_Name::arg_as_integer(size_t i, size_t def_value) const - { - if(i >= arg_count()) - return def_value; - return to_u32bit(args[i]); - } - -} -/* -* CBC-MAC -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include - -namespace Botan { - -/* -* Update an CBC-MAC Calculation -*/ -void CBC_MAC::add_data(const byte input[], size_t length) - { - size_t xored = std::min(output_length() - position, length); - xor_buf(&state[position], input, xored); - position += xored; - - if(position < output_length()) - return; - - e->encrypt(state); - input += xored; - length -= xored; - while(length >= output_length()) - { - xor_buf(state, input, output_length()); - e->encrypt(state); - input += output_length(); - length -= output_length(); - } - - xor_buf(state, input, length); - position = length; - } - -/* -* Finalize an CBC-MAC Calculation -*/ -void CBC_MAC::final_result(byte mac[]) - { - if(position) - e->encrypt(state); - - copy_mem(mac, &state[0], state.size()); - zeroise(state); - position = 0; - } - -/* -* CBC-MAC Key Schedule -*/ -void CBC_MAC::key_schedule(const byte key[], size_t length) - { - e->set_key(key, length); - } - -/* -* Clear memory of sensitive data -*/ -void CBC_MAC::clear() - { - e->clear(); - zeroise(state); - position = 0; - } - -/* -* Return the name of this type -*/ -std::string CBC_MAC::name() const - { - return "CBC-MAC(" + e->name() + ")"; - } - -/* -* Return a clone of this object -*/ -MessageAuthenticationCode* CBC_MAC::clone() const - { - return new CBC_MAC(e->clone()); - } - -/* -* CBC-MAC Constructor -*/ -CBC_MAC::CBC_MAC(BlockCipher* e_in) : - e(e_in), state(e->block_size()) - { - position = 0; - } - -/* -* CBC-MAC Destructor -*/ -CBC_MAC::~CBC_MAC() - { - delete e; - } - -} -/* -* CMAC -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -/* -* Perform CMAC's multiplication in GF(2^n) -*/ -SecureVector CMAC::poly_double(const MemoryRegion& in, - byte polynomial) - { - const byte poly_xor = (in[0] & 0x80) ? polynomial : 0; - - SecureVector out = in; - - byte carry = 0; - for(size_t i = out.size(); i != 0; --i) - { - byte temp = out[i-1]; - out[i-1] = (temp << 1) | carry; - carry = (temp >> 7); - } - - out[out.size()-1] ^= poly_xor; - - return out; - } - -/* -* Update an CMAC Calculation -*/ -void CMAC::add_data(const byte input[], size_t length) - { - buffer.copy(position, input, length); - if(position + length > output_length()) - { - xor_buf(state, buffer, output_length()); - e->encrypt(state); - input += (output_length() - position); - length -= (output_length() - position); - while(length > output_length()) - { - xor_buf(state, input, output_length()); - e->encrypt(state); - input += output_length(); - length -= output_length(); - } - buffer.copy(input, length); - position = 0; - } - position += length; - } - -/* -* Finalize an CMAC Calculation -*/ -void CMAC::final_result(byte mac[]) - { - xor_buf(state, buffer, position); - - if(position == output_length()) - { - xor_buf(state, B, output_length()); - } - else - { - state[position] ^= 0x80; - xor_buf(state, P, output_length()); - } - - e->encrypt(state); - - for(size_t i = 0; i != output_length(); ++i) - mac[i] = state[i]; - - zeroise(state); - zeroise(buffer); - position = 0; - } - -/* -* CMAC Key Schedule -*/ -void CMAC::key_schedule(const byte key[], size_t length) - { - clear(); - e->set_key(key, length); - e->encrypt(B); - B = poly_double(B, polynomial); - P = poly_double(B, polynomial); - } - -/* -* Clear memory of sensitive data -*/ -void CMAC::clear() - { - e->clear(); - zeroise(state); - zeroise(buffer); - zeroise(B); - zeroise(P); - position = 0; - } - -/* -* Return the name of this type -*/ -std::string CMAC::name() const - { - return "CMAC(" + e->name() + ")"; - } - -/* -* Return a clone of this object -*/ -MessageAuthenticationCode* CMAC::clone() const - { - return new CMAC(e->clone()); - } - -/* -* CMAC Constructor -*/ -CMAC::CMAC(BlockCipher* e_in) : e(e_in) - { - if(e->block_size() == 16) - polynomial = 0x87; - else if(e->block_size() == 8) - polynomial = 0x1B; - else - throw Invalid_Argument("CMAC cannot use the cipher " + e->name()); - - state.resize(output_length()); - buffer.resize(output_length()); - B.resize(output_length()); - P.resize(output_length()); - position = 0; - } - -/* -* CMAC Destructor -*/ -CMAC::~CMAC() - { - delete e; - } - -} -/* -* HMAC -* (C) 1999-2007 Jack Lloyd -* 2007 Yves Jerschow -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -/* -* Update a HMAC Calculation -*/ -void HMAC::add_data(const byte input[], size_t length) - { - hash->update(input, length); - } - -/* -* Finalize a HMAC Calculation -*/ -void HMAC::final_result(byte mac[]) - { - hash->final(mac); - hash->update(o_key); - hash->update(mac, output_length()); - hash->final(mac); - hash->update(i_key); - } - -/* -* HMAC Key Schedule -*/ -void HMAC::key_schedule(const byte key[], size_t length) - { - hash->clear(); - std::fill(i_key.begin(), i_key.end(), 0x36); - std::fill(o_key.begin(), o_key.end(), 0x5C); - - if(length > hash->hash_block_size()) - { - SecureVector hmac_key = hash->process(key, length); - xor_buf(i_key, hmac_key, hmac_key.size()); - xor_buf(o_key, hmac_key, hmac_key.size()); - } - else - { - xor_buf(i_key, key, length); - xor_buf(o_key, key, length); - } - - hash->update(i_key); - } - -/* -* Clear memory of sensitive data -*/ -void HMAC::clear() - { - hash->clear(); - zeroise(i_key); - zeroise(o_key); - } - -/* -* Return the name of this type -*/ -std::string HMAC::name() const - { - return "HMAC(" + hash->name() + ")"; - } - -/* -* Return a clone of this object -*/ -MessageAuthenticationCode* HMAC::clone() const - { - return new HMAC(hash->clone()); - } - -/* -* HMAC Constructor -*/ -HMAC::HMAC(HashFunction* hash_in) : hash(hash_in) - { - if(hash->hash_block_size() == 0) - throw Invalid_Argument("HMAC cannot be used with " + hash->name()); - - i_key.resize(hash->hash_block_size()); - o_key.resize(hash->hash_block_size()); - } - -} -/* -* Message Authentication Code base class -* (C) 1999-2008 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -/* -* Default (deterministic) MAC verification operation -*/ -bool MessageAuthenticationCode::verify_mac(const byte mac[], size_t length) - { - SecureVector our_mac = final(); - - if(our_mac.size() != length) - return false; - - return same_mem(&our_mac[0], &mac[0], length); - } - -} -/* -* SSL3-MAC -* (C) 1999-2004 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -/* -* Update a SSL3-MAC Calculation -*/ -void SSL3_MAC::add_data(const byte input[], size_t length) - { - hash->update(input, length); - } - -/* -* Finalize a SSL3-MAC Calculation -*/ -void SSL3_MAC::final_result(byte mac[]) - { - hash->final(mac); - hash->update(o_key); - hash->update(mac, output_length()); - hash->final(mac); - hash->update(i_key); - } - -/* -* SSL3-MAC Key Schedule -*/ -void SSL3_MAC::key_schedule(const byte key[], size_t length) - { - hash->clear(); - std::fill(i_key.begin(), i_key.end(), 0x36); - std::fill(o_key.begin(), o_key.end(), 0x5C); - - i_key.copy(key, length); - o_key.copy(key, length); - hash->update(i_key); - } - -/* -* Clear memory of sensitive data -*/ -void SSL3_MAC::clear() - { - hash->clear(); - zeroise(i_key); - zeroise(o_key); - } - -/* -* Return the name of this type -*/ -std::string SSL3_MAC::name() const - { - return "SSL3-MAC(" + hash->name() + ")"; - } - -/* -* Return a clone of this object -*/ -MessageAuthenticationCode* SSL3_MAC::clone() const - { - return new SSL3_MAC(hash->clone()); - } - -/* -* SSL3-MAC Constructor -*/ -SSL3_MAC::SSL3_MAC(HashFunction* hash_in) : hash(hash_in) - { - if(hash->hash_block_size() == 0) - throw Invalid_Argument("SSL3-MAC cannot be used with " + hash->name()); - - // Quirk to deal with specification bug - const size_t INNER_HASH_LENGTH = - (hash->name() == "SHA-160") ? 60 : hash->hash_block_size(); - - i_key.resize(INNER_HASH_LENGTH); - o_key.resize(INNER_HASH_LENGTH); - } - -} -/* -* ANSI X9.19 MAC -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include - -namespace Botan { - -/* -* Update an ANSI X9.19 MAC Calculation -*/ -void ANSI_X919_MAC::add_data(const byte input[], size_t length) - { - size_t xored = std::min(8 - position, length); - xor_buf(&state[position], input, xored); - position += xored; - - if(position < 8) return; - - e->encrypt(state); - input += xored; - length -= xored; - while(length >= 8) - { - xor_buf(state, input, 8); - e->encrypt(state); - input += 8; - length -= 8; - } - - xor_buf(state, input, length); - position = length; - } - -/* -* Finalize an ANSI X9.19 MAC Calculation -*/ -void ANSI_X919_MAC::final_result(byte mac[]) - { - if(position) - e->encrypt(state); - d->decrypt(state, mac); - e->encrypt(mac); - zeroise(state); - position = 0; - } - -/* -* ANSI X9.19 MAC Key Schedule -*/ -void ANSI_X919_MAC::key_schedule(const byte key[], size_t length) - { - e->set_key(key, 8); - if(length == 8) d->set_key(key, 8); - else d->set_key(key + 8, 8); - } - -/* -* Clear memory of sensitive data -*/ -void ANSI_X919_MAC::clear() - { - e->clear(); - d->clear(); - zeroise(state); - position = 0; - } - -std::string ANSI_X919_MAC::name() const - { - return "X9.19-MAC"; - } - -MessageAuthenticationCode* ANSI_X919_MAC::clone() const - { - return new ANSI_X919_MAC(e->clone()); - } - -/* -* ANSI X9.19 MAC Constructor -*/ -ANSI_X919_MAC::ANSI_X919_MAC(BlockCipher* e_in) : - e(e_in), d(e->clone()), state(e->block_size()), position(0) - { - if(e->name() != "DES") - throw Invalid_Argument("ANSI X9.19 MAC only supports DES"); - } - -/* -* ANSI X9.19 MAC Destructor -le*/ -ANSI_X919_MAC::~ANSI_X919_MAC() - { - delete e; - delete d; - } - -} -/* -* BigInt Encoding/Decoding -* (C) 1999-2010 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -/* -* Encode a BigInt -*/ -void BigInt::encode(byte output[], const BigInt& n, Base base) - { - if(base == Binary) - n.binary_encode(output); - else if(base == Hexadecimal) - { - SecureVector binary(n.encoded_size(Binary)); - n.binary_encode(&binary[0]); - - hex_encode(reinterpret_cast(output), - &binary[0], binary.size()); - } - else if(base == Octal) - { - BigInt copy = n; - const size_t output_size = n.encoded_size(Octal); - for(size_t j = 0; j != output_size; ++j) - { - output[output_size - 1 - j] = - Charset::digit2char(static_cast(copy % 8)); - - copy /= 8; - } - } - else if(base == Decimal) - { - BigInt copy = n; - BigInt remainder; - copy.set_sign(Positive); - const size_t output_size = n.encoded_size(Decimal); - for(size_t j = 0; j != output_size; ++j) - { - divide(copy, 10, copy, remainder); - output[output_size - 1 - j] = - Charset::digit2char(static_cast(remainder.word_at(0))); - if(copy.is_zero()) - break; - } - } - else - throw Invalid_Argument("Unknown BigInt encoding method"); - } - -/* -* Encode a BigInt -*/ -SecureVector BigInt::encode(const BigInt& n, Base base) - { - SecureVector output(n.encoded_size(base)); - encode(&output[0], n, base); - if(base != Binary) - for(size_t j = 0; j != output.size(); ++j) - if(output[j] == 0) - output[j] = '0'; - return output; - } - -/* -* Encode a BigInt, with leading 0s if needed -*/ -SecureVector BigInt::encode_1363(const BigInt& n, size_t bytes) - { - const size_t n_bytes = n.bytes(); - if(n_bytes > bytes) - throw Encoding_Error("encode_1363: n is too large to encode properly"); - - const size_t leading_0s = bytes - n_bytes; - - SecureVector output(bytes); - encode(&output[leading_0s], n, Binary); - return output; - } - -/* -* Decode a BigInt -*/ -BigInt BigInt::decode(const MemoryRegion& buf, Base base) - { - return BigInt::decode(&buf[0], buf.size(), base); - } - -/* -* Decode a BigInt -*/ -BigInt BigInt::decode(const byte buf[], size_t length, Base base) - { - BigInt r; - if(base == Binary) - r.binary_decode(buf, length); - else if(base == Hexadecimal) - { - SecureVector binary; - const char *cbuf = reinterpret_cast(buf); - - if(length % 2) - { - // Handle lack of leading 0 - const char buf0_with_leading_0[2] = { '0', cbuf[0] }; - binary = hex_decode(buf0_with_leading_0, 2); - - binary += hex_decode(&cbuf[1], length - 1, false); - } - else - binary = hex_decode(cbuf, length, false); - - r.binary_decode(&binary[0], binary.size()); - } - else if(base == Decimal || base == Octal) - { - const size_t RADIX = ((base == Decimal) ? 10 : 8); - for(size_t j = 0; j != length; ++j) - { - if(Charset::is_space(buf[j])) - continue; - - if(!Charset::is_digit(buf[j])) - throw Invalid_Argument("BigInt::decode: " - "Invalid character in decimal input"); - - byte x = Charset::char2digit(buf[j]); - if(x >= RADIX) - { - if(RADIX == 10) - throw Invalid_Argument("BigInt: Invalid decimal string"); - else - throw Invalid_Argument("BigInt: Invalid octal string"); - } - - r *= RADIX; - r += x; - } - } - else - throw Invalid_Argument("Unknown BigInt decoding method"); - return r; - } - -} -/* -* BigInt Input/Output -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include - -namespace Botan { - -/* -* Write the BigInt into a stream -*/ -std::ostream& operator<<(std::ostream& stream, const BigInt& n) - { - BigInt::Base base = BigInt::Decimal; - if(stream.flags() & std::ios::hex) - base = BigInt::Hexadecimal; - else if(stream.flags() & std::ios::oct) - base = BigInt::Octal; - - if(n == 0) - stream.write("0", 1); - else - { - if(n < 0) - stream.write("-", 1); - SecureVector buffer = BigInt::encode(n, base); - size_t skip = 0; - while(buffer[skip] == '0' && skip < buffer.size()) - ++skip; - stream.write(reinterpret_cast(&buffer[0]) + skip, - buffer.size() - skip); - } - if(!stream.good()) - throw Stream_IO_Error("BigInt output operator has failed"); - return stream; - } - -/* -* Read the BigInt from a stream -*/ -std::istream& operator>>(std::istream& stream, BigInt& n) - { - std::string str; - std::getline(stream, str); - if(stream.bad() || (stream.fail() && !stream.eof())) - throw Stream_IO_Error("BigInt input operator has failed"); - n = BigInt(str); - return stream; - } - -} -/* -* BigInt Assignment Operators -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include - -namespace Botan { - -/* -* Addition Operator -*/ -BigInt& BigInt::operator+=(const BigInt& y) - { - const size_t x_sw = sig_words(), y_sw = y.sig_words(); - - const size_t reg_size = std::max(x_sw, y_sw) + 1; - grow_to(reg_size); - - if(sign() == y.sign()) - bigint_add2(get_reg(), reg_size - 1, y.data(), y_sw); - else - { - s32bit relative_size = bigint_cmp(data(), x_sw, y.data(), y_sw); - - if(relative_size < 0) - { - SecureVector z(reg_size - 1); - bigint_sub3(z, y.data(), reg_size - 1, data(), x_sw); - copy_mem(®[0], &z[0], z.size()); - set_sign(y.sign()); - } - else if(relative_size == 0) - { - zeroise(reg); - set_sign(Positive); - } - else if(relative_size > 0) - bigint_sub2(get_reg(), x_sw, y.data(), y_sw); - } - - return (*this); - } - -/* -* Subtraction Operator -*/ -BigInt& BigInt::operator-=(const BigInt& y) - { - const size_t x_sw = sig_words(), y_sw = y.sig_words(); - - s32bit relative_size = bigint_cmp(data(), x_sw, y.data(), y_sw); - - const size_t reg_size = std::max(x_sw, y_sw) + 1; - grow_to(reg_size); - - if(relative_size < 0) - { - if(sign() == y.sign()) - bigint_sub2_rev(get_reg(), y.data(), y_sw); - else - bigint_add2(get_reg(), reg_size - 1, y.data(), y_sw); - - set_sign(y.reverse_sign()); - } - else if(relative_size == 0) - { - if(sign() == y.sign()) - { - clear(); - set_sign(Positive); - } - else - bigint_shl1(get_reg(), x_sw, 0, 1); - } - else if(relative_size > 0) - { - if(sign() == y.sign()) - bigint_sub2(get_reg(), x_sw, y.data(), y_sw); - else - bigint_add2(get_reg(), reg_size - 1, y.data(), y_sw); - } - - return (*this); - } - -/* -* Multiplication Operator -*/ -BigInt& BigInt::operator*=(const BigInt& y) - { - const size_t x_sw = sig_words(), y_sw = y.sig_words(); - set_sign((sign() == y.sign()) ? Positive : Negative); - - if(x_sw == 0 || y_sw == 0) - { - clear(); - set_sign(Positive); - } - else if(x_sw == 1 && y_sw) - { - grow_to(y_sw + 2); - bigint_linmul3(get_reg(), y.data(), y_sw, word_at(0)); - } - else if(y_sw == 1 && x_sw) - { - grow_to(x_sw + 2); - bigint_linmul2(get_reg(), x_sw, y.word_at(0)); - } - else - { - grow_to(size() + y.size()); - - SecureVector z(data(), x_sw); - SecureVector workspace(size()); - - bigint_mul(get_reg(), size(), workspace, - z, z.size(), x_sw, - y.data(), y.size(), y_sw); - } - - return (*this); - } - -/* -* Division Operator -*/ -BigInt& BigInt::operator/=(const BigInt& y) - { - if(y.sig_words() == 1 && power_of_2(y.word_at(0))) - (*this) >>= (y.bits() - 1); - else - (*this) = (*this) / y; - return (*this); - } - -/* -* Modulo Operator -*/ -BigInt& BigInt::operator%=(const BigInt& mod) - { - return (*this = (*this) % mod); - } - -/* -* Modulo Operator -*/ -word BigInt::operator%=(word mod) - { - if(mod == 0) - throw BigInt::DivideByZero(); - if(power_of_2(mod)) - { - word result = (word_at(0) & (mod - 1)); - clear(); - grow_to(2); - get_reg()[0] = result; - return result; - } - - word remainder = 0; - - for(size_t j = sig_words(); j > 0; --j) - remainder = bigint_modop(remainder, word_at(j-1), mod); - clear(); - grow_to(2); - - if(remainder && sign() == BigInt::Negative) - get_reg()[0] = mod - remainder; - else - get_reg()[0] = remainder; - - set_sign(BigInt::Positive); - - return word_at(0); - } - -/* -* Left Shift Operator -*/ -BigInt& BigInt::operator<<=(size_t shift) - { - if(shift) - { - const size_t shift_words = shift / MP_WORD_BITS, - shift_bits = shift % MP_WORD_BITS, - words = sig_words(); - - grow_to(words + shift_words + (shift_bits ? 1 : 0)); - bigint_shl1(get_reg(), words, shift_words, shift_bits); - } - - return (*this); - } - -/* -* Right Shift Operator -*/ -BigInt& BigInt::operator>>=(size_t shift) - { - if(shift) - { - const size_t shift_words = shift / MP_WORD_BITS, - shift_bits = shift % MP_WORD_BITS; - - bigint_shr1(get_reg(), sig_words(), shift_words, shift_bits); - - if(is_zero()) - set_sign(Positive); - } - - return (*this); - } - -} -/* -* BigInt Binary Operators -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include - -namespace Botan { - -/* -* Addition Operator -*/ -BigInt operator+(const BigInt& x, const BigInt& y) - { - const size_t x_sw = x.sig_words(), y_sw = y.sig_words(); - - BigInt z(x.sign(), std::max(x_sw, y_sw) + 1); - - if((x.sign() == y.sign())) - bigint_add3(z.get_reg(), x.data(), x_sw, y.data(), y_sw); - else - { - s32bit relative_size = bigint_cmp(x.data(), x_sw, y.data(), y_sw); - - if(relative_size < 0) - { - bigint_sub3(z.get_reg(), y.data(), y_sw, x.data(), x_sw); - z.set_sign(y.sign()); - } - else if(relative_size == 0) - z.set_sign(BigInt::Positive); - else if(relative_size > 0) - bigint_sub3(z.get_reg(), x.data(), x_sw, y.data(), y_sw); - } - - return z; - } - -/* -* Subtraction Operator -*/ -BigInt operator-(const BigInt& x, const BigInt& y) - { - const size_t x_sw = x.sig_words(), y_sw = y.sig_words(); - - s32bit relative_size = bigint_cmp(x.data(), x_sw, y.data(), y_sw); - - BigInt z(BigInt::Positive, std::max(x_sw, y_sw) + 1); - - if(relative_size < 0) - { - if(x.sign() == y.sign()) - bigint_sub3(z.get_reg(), y.data(), y_sw, x.data(), x_sw); - else - bigint_add3(z.get_reg(), x.data(), x_sw, y.data(), y_sw); - z.set_sign(y.reverse_sign()); - } - else if(relative_size == 0) - { - if(x.sign() != y.sign()) - bigint_shl2(z.get_reg(), x.data(), x_sw, 0, 1); - } - else if(relative_size > 0) - { - if(x.sign() == y.sign()) - bigint_sub3(z.get_reg(), x.data(), x_sw, y.data(), y_sw); - else - bigint_add3(z.get_reg(), x.data(), x_sw, y.data(), y_sw); - z.set_sign(x.sign()); - } - return z; - } - -/* -* Multiplication Operator -*/ -BigInt operator*(const BigInt& x, const BigInt& y) - { - const size_t x_sw = x.sig_words(), y_sw = y.sig_words(); - - BigInt z(BigInt::Positive, x.size() + y.size()); - - if(x_sw == 1 && y_sw) - bigint_linmul3(z.get_reg(), y.data(), y_sw, x.word_at(0)); - else if(y_sw == 1 && x_sw) - bigint_linmul3(z.get_reg(), x.data(), x_sw, y.word_at(0)); - else if(x_sw && y_sw) - { - SecureVector workspace(z.size()); - bigint_mul(z.get_reg(), z.size(), workspace, - x.data(), x.size(), x_sw, - y.data(), y.size(), y_sw); - } - - if(x_sw && y_sw && x.sign() != y.sign()) - z.flip_sign(); - return z; - } - -/* -* Division Operator -*/ -BigInt operator/(const BigInt& x, const BigInt& y) - { - BigInt q, r; - divide(x, y, q, r); - return q; - } - -/* -* Modulo Operator -*/ -BigInt operator%(const BigInt& n, const BigInt& mod) - { - if(mod.is_zero()) - throw BigInt::DivideByZero(); - if(mod.is_negative()) - throw Invalid_Argument("BigInt::operator%: modulus must be > 0"); - if(n.is_positive() && mod.is_positive() && n < mod) - return n; - - BigInt q, r; - divide(n, mod, q, r); - return r; - } - -/* -* Modulo Operator -*/ -word operator%(const BigInt& n, word mod) - { - if(mod == 0) - throw BigInt::DivideByZero(); - if(power_of_2(mod)) - return (n.word_at(0) & (mod - 1)); - - word remainder = 0; - - for(size_t j = n.sig_words(); j > 0; --j) - remainder = bigint_modop(remainder, n.word_at(j-1), mod); - - if(remainder && n.sign() == BigInt::Negative) - return mod - remainder; - return remainder; - } - -/* -* Left Shift Operator -*/ -BigInt operator<<(const BigInt& x, size_t shift) - { - if(shift == 0) - return x; - - const size_t shift_words = shift / MP_WORD_BITS, - shift_bits = shift % MP_WORD_BITS; - - const size_t x_sw = x.sig_words(); - - BigInt y(x.sign(), x_sw + shift_words + (shift_bits ? 1 : 0)); - bigint_shl2(y.get_reg(), x.data(), x_sw, shift_words, shift_bits); - return y; - } - -/* -* Right Shift Operator -*/ -BigInt operator>>(const BigInt& x, size_t shift) - { - if(shift == 0) - return x; - if(x.bits() <= shift) - return 0; - - const size_t shift_words = shift / MP_WORD_BITS, - shift_bits = shift % MP_WORD_BITS, - x_sw = x.sig_words(); - - BigInt y(x.sign(), x_sw - shift_words); - bigint_shr2(y.get_reg(), x.data(), x_sw, shift_words, shift_bits); - return y; - } - -} -/* -* BigInt Random Generation -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -/* -* Construct a BigInt of a specific form -*/ -BigInt::BigInt(NumberType type, size_t bits) - { - set_sign(Positive); - - if(type == Power2) - set_bit(bits); - else - throw Invalid_Argument("BigInt(NumberType): Unknown type"); - } - -/* -* Randomize this number -*/ -void BigInt::randomize(RandomNumberGenerator& rng, - size_t bitsize) - { - set_sign(Positive); - - if(bitsize == 0) - clear(); - else - { - SecureVector array = rng.random_vec((bitsize + 7) / 8); - - if(bitsize % 8) - array[0] &= 0xFF >> (8 - (bitsize % 8)); - array[0] |= 0x80 >> ((bitsize % 8) ? (8 - bitsize % 8) : 0); - binary_decode(&array[0], array.size()); - } - } - -/* -* Generate a random integer within given range -*/ -BigInt BigInt::random_integer(RandomNumberGenerator& rng, - const BigInt& min, const BigInt& max) - { - BigInt range = max - min; - - if(range <= 0) - throw Invalid_Argument("random_integer: invalid min/max values"); - - return (min + (BigInt(rng, range.bits() + 2) % range)); - } - -} -/* -* BigInt Base -* (C) 1999-2011 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -/* -* Construct a BigInt from a regular number -*/ -BigInt::BigInt(u64bit n) - { - set_sign(Positive); - - if(n == 0) - return; - - const size_t limbs_needed = sizeof(u64bit) / sizeof(word); - - reg.resize(4*limbs_needed); - for(size_t i = 0; i != limbs_needed; ++i) - reg[i] = ((n >> (i*MP_WORD_BITS)) & MP_WORD_MASK); - } - -/* -* Construct a BigInt of the specified size -*/ -BigInt::BigInt(Sign s, size_t size) - { - reg.resize(round_up(size, 8)); - signedness = s; - } - -/* -* Construct a BigInt from a "raw" BigInt -*/ -BigInt::BigInt(const BigInt& b) - { - const size_t b_words = b.sig_words(); - - if(b_words) - { - reg.resize(round_up(b_words, 8)); - reg.copy(b.data(), b_words); - set_sign(b.sign()); - } - else - { - reg.resize(2); - set_sign(Positive); - } - } - -/* -* Construct a BigInt from a string -*/ -BigInt::BigInt(const std::string& str) - { - Base base = Decimal; - size_t markers = 0; - bool negative = false; - if(str.length() > 0 && str[0] == '-') { markers += 1; negative = true; } - - if(str.length() > markers + 2 && str[markers ] == '0' && - str[markers + 1] == 'x') - { markers += 2; base = Hexadecimal; } - else if(str.length() > markers + 1 && str[markers] == '0') - { markers += 1; base = Octal; } - - *this = decode(reinterpret_cast(str.data()) + markers, - str.length() - markers, base); - - if(negative) set_sign(Negative); - else set_sign(Positive); - } - -/* -* Construct a BigInt from an encoded BigInt -*/ -BigInt::BigInt(const byte input[], size_t length, Base base) - { - set_sign(Positive); - *this = decode(input, length, base); - } - -/* -* Construct a BigInt from an encoded BigInt -*/ -BigInt::BigInt(RandomNumberGenerator& rng, size_t bits) - { - set_sign(Positive); - randomize(rng, bits); - } - -/* -* Swap this BigInt with another -*/ -void BigInt::swap(BigInt& other) - { - reg.swap(other.reg); - std::swap(signedness, other.signedness); - } - -/* -* Grow the internal storage -*/ -void BigInt::grow_reg(size_t n) - { - reg.resize(round_up(size() + n, 8)); - } - -/* -* Grow the internal storage -*/ -void BigInt::grow_to(size_t n) - { - if(n > size()) - reg.resize(round_up(n, 8)); - } - -/* -* Comparison Function -*/ -s32bit BigInt::cmp(const BigInt& n, bool check_signs) const - { - if(check_signs) - { - if(n.is_positive() && this->is_negative()) return -1; - if(n.is_negative() && this->is_positive()) return 1; - if(n.is_negative() && this->is_negative()) - return (-bigint_cmp(data(), sig_words(), n.data(), n.sig_words())); - } - return bigint_cmp(data(), sig_words(), n.data(), n.sig_words()); - } - -/* -* Return byte n of this number -*/ -byte BigInt::byte_at(size_t n) const - { - const size_t WORD_BYTES = sizeof(word); - size_t word_num = n / WORD_BYTES, byte_num = n % WORD_BYTES; - if(word_num >= size()) - return 0; - else - return get_byte(WORD_BYTES - byte_num - 1, reg[word_num]); - } - -/* -* Return bit n of this number -*/ -bool BigInt::get_bit(size_t n) const - { - return ((word_at(n / MP_WORD_BITS) >> (n % MP_WORD_BITS)) & 1); - } - -/* -* Return bits {offset...offset+length} -*/ -u32bit BigInt::get_substring(size_t offset, size_t length) const - { - if(length > 32) - throw Invalid_Argument("BigInt::get_substring: Substring size too big"); - - u64bit piece = 0; - for(size_t i = 0; i != 8; ++i) - { - const byte part = byte_at((offset / 8) + (7-i)); - piece = (piece << 8) | part; - } - - const u64bit mask = (static_cast(1) << length) - 1; - const size_t shift = (offset % 8); - - return static_cast((piece >> shift) & mask); - } - -/* -* Convert this number to a u32bit, if possible -*/ -u32bit BigInt::to_u32bit() const - { - if(is_negative()) - throw Encoding_Error("BigInt::to_u32bit: Number is negative"); - if(bits() >= 32) - throw Encoding_Error("BigInt::to_u32bit: Number is too big to convert"); - - u32bit out = 0; - for(u32bit j = 0; j != 4; ++j) - out = (out << 8) | byte_at(3-j); - return out; - } - -/* -* Set bit number n -*/ -void BigInt::set_bit(size_t n) - { - const size_t which = n / MP_WORD_BITS; - const word mask = static_cast(1) << (n % MP_WORD_BITS); - if(which >= size()) grow_to(which + 1); - reg[which] |= mask; - } - -/* -* Clear bit number n -*/ -void BigInt::clear_bit(size_t n) - { - const size_t which = n / MP_WORD_BITS; - const word mask = static_cast(1) << (n % MP_WORD_BITS); - if(which < size()) - reg[which] &= ~mask; - } - -/* -* Clear all but the lowest n bits -*/ -void BigInt::mask_bits(size_t n) - { - if(n == 0) { clear(); return; } - if(n >= bits()) return; - - const size_t top_word = n / MP_WORD_BITS; - const word mask = (static_cast(1) << (n % MP_WORD_BITS)) - 1; - - if(top_word < size()) - for(size_t i = top_word + 1; i != size(); ++i) - reg[i] = 0; - - reg[top_word] &= mask; - } - -/* -* Count how many bytes are being used -*/ -size_t BigInt::bytes() const - { - return (bits() + 7) / 8; - } - -/* -* Count how many bits are being used -*/ -size_t BigInt::bits() const - { - const size_t words = sig_words(); - - if(words == 0) - return 0; - - size_t full_words = words - 1, top_bits = MP_WORD_BITS; - word top_word = word_at(full_words), mask = MP_WORD_TOP_BIT; - - while(top_bits && ((top_word & mask) == 0)) - { mask >>= 1; top_bits--; } - - return (full_words * MP_WORD_BITS + top_bits); - } - -/* -* Calcluate the size in a certain base -*/ -size_t BigInt::encoded_size(Base base) const - { - static const double LOG_2_BASE_10 = 0.30102999566; - - if(base == Binary) - return bytes(); - else if(base == Hexadecimal) - return 2*bytes(); - else if(base == Octal) - return ((bits() + 2) / 3); - else if(base == Decimal) - return static_cast((bits() * LOG_2_BASE_10) + 1); - else - throw Invalid_Argument("Unknown base for BigInt encoding"); - } - -/* -* Set the sign -*/ -void BigInt::set_sign(Sign s) - { - if(is_zero()) - signedness = Positive; - else - signedness = s; - } - -/* -* Reverse the value of the sign flag -*/ -void BigInt::flip_sign() - { - set_sign(reverse_sign()); - } - -/* -* Return the opposite value of the current sign -*/ -BigInt::Sign BigInt::reverse_sign() const - { - if(sign() == Positive) - return Negative; - return Positive; - } - -/* -* Return the negation of this number -*/ -BigInt BigInt::operator-() const - { - BigInt x = (*this); - x.flip_sign(); - return x; - } - -/* -* Return the absolute value of this number -*/ -BigInt BigInt::abs() const - { - BigInt x = (*this); - x.set_sign(Positive); - return x; - } - -/* -* Encode this number into bytes -*/ -void BigInt::binary_encode(byte output[]) const - { - const size_t sig_bytes = bytes(); - for(size_t i = 0; i != sig_bytes; ++i) - output[sig_bytes-i-1] = byte_at(i); - } - -/* -* Set this number to the value in buf -*/ -void BigInt::binary_decode(const byte buf[], size_t length) - { - const size_t WORD_BYTES = sizeof(word); - - clear(); - reg.resize(round_up((length / WORD_BYTES) + 1, 8)); - - for(size_t i = 0; i != length / WORD_BYTES; ++i) - { - const size_t top = length - WORD_BYTES*i; - for(size_t j = WORD_BYTES; j > 0; --j) - reg[i] = (reg[i] << 8) | buf[top - j]; - } - - for(size_t i = 0; i != length % WORD_BYTES; ++i) - reg[length / WORD_BYTES] = (reg[length / WORD_BYTES] << 8) | buf[i]; - } - -/* -* Set this number to the value in buf -*/ -void BigInt::binary_decode(const MemoryRegion& buf) - { - binary_decode(buf, buf.size()); - } - -} -/* -* Division Algorithm -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -namespace { - -/* -* Handle signed operands, if necessary -*/ -void sign_fixup(const BigInt& x, const BigInt& y, BigInt& q, BigInt& r) - { - if(x.sign() == BigInt::Negative) - { - q.flip_sign(); - if(r.is_nonzero()) { --q; r = y.abs() - r; } - } - if(y.sign() == BigInt::Negative) - q.flip_sign(); - } - -} - -/* -* Solve x = q * y + r -*/ -void divide(const BigInt& x, const BigInt& y_arg, BigInt& q, BigInt& r) - { - if(y_arg.is_zero()) - throw BigInt::DivideByZero(); - - BigInt y = y_arg; - const size_t y_words = y.sig_words(); - - r = x; - q = 0; - - r.set_sign(BigInt::Positive); - y.set_sign(BigInt::Positive); - - s32bit compare = r.cmp(y); - - if(compare == 0) - { - q = 1; - r = 0; - } - else if(compare > 0) - { - size_t shifts = 0; - word y_top = y[y.sig_words()-1]; - while(y_top < MP_WORD_TOP_BIT) { y_top <<= 1; ++shifts; } - y <<= shifts; - r <<= shifts; - - const size_t n = r.sig_words() - 1, t = y_words - 1; - - if(n < t) - throw Internal_Error("BigInt division word sizes"); - - q.get_reg().resize(n - t + 1); - if(n <= t) - { - while(r > y) { r -= y; ++q; } - r >>= shifts; - sign_fixup(x, y_arg, q, r); - return; - } - - BigInt temp = y << (MP_WORD_BITS * (n-t)); - - while(r >= temp) { r -= temp; ++q[n-t]; } - - for(size_t j = n; j != t; --j) - { - const word x_j0 = r.word_at(j); - const word x_j1 = r.word_at(j-1); - const word y_t = y.word_at(t); - - if(x_j0 == y_t) - q[j-t-1] = MP_WORD_MAX; - else - q[j-t-1] = bigint_divop(x_j0, x_j1, y_t); - - while(bigint_divcore(q[j-t-1], y_t, y.word_at(t-1), - x_j0, x_j1, r.word_at(j-2))) - --q[j-t-1]; - - r -= (q[j-t-1] * y) << (MP_WORD_BITS * (j-t-1)); - if(r.is_negative()) - { - r += y << (MP_WORD_BITS * (j-t-1)); - --q[j-t-1]; - } - } - r >>= shifts; - } - - sign_fixup(x, y_arg, q, r); - } - -} -/* -* Point arithmetic on elliptic curves over GF(p) -* -* (C) 2007 Martin Doering, Christoph Ludwig, Falko Strenzke -* 2008-2011 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -PointGFp::PointGFp(const CurveGFp& curve) : - curve(curve), ws(2 * (curve.get_p_words() + 2)) - { - coord_x = 0; - coord_y = monty_mult(1, curve.get_r2()); - coord_z = 0; - } - -PointGFp::PointGFp(const CurveGFp& curve, const BigInt& x, const BigInt& y) : - curve(curve), ws(2 * (curve.get_p_words() + 2)) - { - coord_x = monty_mult(x, curve.get_r2()); - coord_y = monty_mult(y, curve.get_r2()); - coord_z = monty_mult(1, curve.get_r2()); - } - -// Montgomery multiplication -void PointGFp::monty_mult(BigInt& z, const BigInt& x, const BigInt& y) const - { - //assert(&z != &x && &z != &y); - - if(x.is_zero() || y.is_zero()) - { - z = 0; - return; - } - - const BigInt& p = curve.get_p(); - const size_t p_size = curve.get_p_words(); - const word p_dash = curve.get_p_dash(); - - SecureVector& z_reg = z.get_reg(); - z_reg.resize(2*p_size+1); - zeroise(z_reg); - - bigint_monty_mul(&z_reg[0], z_reg.size(), - x.data(), x.size(), x.sig_words(), - y.data(), y.size(), y.sig_words(), - p.data(), p_size, p_dash, - &ws[0]); - } - -// Montgomery squaring -void PointGFp::monty_sqr(BigInt& z, const BigInt& x) const - { - //assert(&z != &x); - - if(x.is_zero()) - { - z = 0; - return; - } - - const BigInt& p = curve.get_p(); - const size_t p_size = curve.get_p_words(); - const word p_dash = curve.get_p_dash(); - - SecureVector& z_reg = z.get_reg(); - z_reg.resize(2*p_size+1); - zeroise(z_reg); - - bigint_monty_sqr(&z_reg[0], z_reg.size(), - x.data(), x.size(), x.sig_words(), - p.data(), p_size, p_dash, - &ws[0]); - } - -// Point addition -void PointGFp::add(const PointGFp& rhs, std::vector& ws_bn) - { - if(is_zero()) - { - coord_x = rhs.coord_x; - coord_y = rhs.coord_y; - coord_z = rhs.coord_z; - return; - } - else if(rhs.is_zero()) - return; - - const BigInt& p = curve.get_p(); - - BigInt& rhs_z2 = ws_bn[0]; - BigInt& U1 = ws_bn[1]; - BigInt& S1 = ws_bn[2]; - - BigInt& lhs_z2 = ws_bn[3]; - BigInt& U2 = ws_bn[4]; - BigInt& S2 = ws_bn[5]; - - BigInt& H = ws_bn[6]; - BigInt& r = ws_bn[7]; - - monty_sqr(rhs_z2, rhs.coord_z); - monty_mult(U1, coord_x, rhs_z2); - monty_mult(S1, coord_y, monty_mult(rhs.coord_z, rhs_z2)); - - monty_sqr(lhs_z2, coord_z); - monty_mult(U2, rhs.coord_x, lhs_z2); - monty_mult(S2, rhs.coord_y, monty_mult(coord_z, lhs_z2)); - - H = U2; - H -= U1; - if(H.is_negative()) - H += p; - - r = S2; - r -= S1; - if(r.is_negative()) - r += p; - - if(H.is_zero()) - { - if(r.is_zero()) - { - mult2(ws_bn); - return; - } - - *this = PointGFp(curve); // setting myself to zero - return; - } - - monty_sqr(U2, H); - - monty_mult(S2, U2, H); - - U2 = monty_mult(U1, U2); - - monty_sqr(coord_x, r); - coord_x -= S2; - coord_x -= (U2 << 1); - while(coord_x.is_negative()) - coord_x += p; - - U2 -= coord_x; - if(U2.is_negative()) - U2 += p; - - monty_mult(coord_y, r, U2); - coord_y -= monty_mult(S1, S2); - if(coord_y.is_negative()) - coord_y += p; - - monty_mult(coord_z, monty_mult(coord_z, rhs.coord_z), H); - } - -// *this *= 2 -void PointGFp::mult2(std::vector& ws_bn) - { - if(is_zero()) - return; - else if(coord_y.is_zero()) - { - *this = PointGFp(curve); // setting myself to zero - return; - } - - const BigInt& p = curve.get_p(); - - BigInt& y_2 = ws_bn[0]; - BigInt& S = ws_bn[1]; - BigInt& z4 = ws_bn[2]; - BigInt& a_z4 = ws_bn[3]; - BigInt& M = ws_bn[4]; - BigInt& U = ws_bn[5]; - BigInt& x = ws_bn[6]; - BigInt& y = ws_bn[7]; - BigInt& z = ws_bn[8]; - - monty_sqr(y_2, coord_y); - - monty_mult(S, coord_x, y_2); - S <<= 2; // * 4 - while(S >= p) - S -= p; - - monty_sqr(z4, monty_sqr(coord_z)); - monty_mult(a_z4, curve.get_a_r(), z4); - - M = 3 * monty_sqr(coord_x); - M += a_z4; - while(M >= p) - M -= p; - - monty_sqr(x, M); - x -= (S << 1); - while(x.is_negative()) - x += p; - - monty_sqr(U, y_2); - U <<= 3; - while(U >= p) - U -= p; - - S -= x; - while(S.is_negative()) - S += p; - - monty_mult(y, M, S); - y -= U; - if(y.is_negative()) - y += p; - - monty_mult(z, coord_y, coord_z); - z <<= 1; - if(z >= p) - z -= p; - - coord_x = x; - coord_y = y; - coord_z = z; - } - -// arithmetic operators -PointGFp& PointGFp::operator+=(const PointGFp& rhs) - { - std::vector ws(9); - add(rhs, ws); - return *this; - } - -PointGFp& PointGFp::operator-=(const PointGFp& rhs) - { - PointGFp minus_rhs = PointGFp(rhs).negate(); - - if(is_zero()) - *this = minus_rhs; - else - *this += minus_rhs; - - return *this; - } - -PointGFp& PointGFp::operator*=(const BigInt& scalar) - { - *this = scalar * *this; - return *this; - } - -PointGFp multi_exponentiate(const PointGFp& p1, const BigInt& z1, - const PointGFp& p2, const BigInt& z2) - { - const PointGFp p3 = p1 + p2; - - PointGFp H(p1.curve); // create as zero - size_t bits_left = std::max(z1.bits(), z2.bits()); - - std::vector ws(9); - - while(bits_left) - { - H.mult2(ws); - - const bool z1_b = z1.get_bit(bits_left - 1); - const bool z2_b = z2.get_bit(bits_left - 1); - - if(z1_b == true && z2_b == true) - H.add(p3, ws); - else if(z1_b) - H.add(p1, ws); - else if(z2_b) - H.add(p2, ws); - - --bits_left; - } - - if(z1.is_negative() != z2.is_negative()) - H.negate(); - - return H; - } - -PointGFp operator*(const BigInt& scalar, const PointGFp& point) - { - const CurveGFp& curve = point.get_curve(); - - if(scalar.is_zero()) - return PointGFp(curve); // zero point - - std::vector ws(9); - - if(scalar.abs() <= 2) // special cases for small values - { - byte value = scalar.abs().byte_at(0); - - PointGFp result = point; - - if(value == 2) - result.mult2(ws); - - if(scalar.is_negative()) - result.negate(); - - return result; - } - - const size_t scalar_bits = scalar.bits(); - -#if 0 - - PointGFp x1 = PointGFp(curve); - PointGFp x2 = point; - - size_t bits_left = scalar_bits; - - // Montgomery Ladder - while(bits_left) - { - const bool bit_set = scalar.get_bit(bits_left - 1); - - if(bit_set) - { - x1.add(x2, ws); - x2.mult2(ws); - } - else - { - x2.add(x1, ws); - x1.mult2(ws); - } - - --bits_left; - } - - if(scalar.is_negative()) - x1.negate(); - - return x1; - -#else - const size_t window_size = 4; - - std::vector Ps(1 << window_size); - Ps[0] = PointGFp(curve); - Ps[1] = point; - - for(size_t i = 2; i != Ps.size(); ++i) - { - Ps[i] = Ps[i-1]; - Ps[i].add(point, ws); - } - - PointGFp H(curve); // create as zero - size_t bits_left = scalar_bits; - - while(bits_left >= window_size) - { - for(size_t i = 0; i != window_size; ++i) - H.mult2(ws); - - const u32bit nibble = scalar.get_substring(bits_left - window_size, - window_size); - - H.add(Ps[nibble], ws); - - bits_left -= window_size; - } - - while(bits_left) - { - H.mult2(ws); - if(scalar.get_bit(bits_left-1)) - H.add(point, ws); - - --bits_left; - } - - if(scalar.is_negative()) - H.negate(); - - return H; -#endif - } - -BigInt PointGFp::get_affine_x() const - { - if(is_zero()) - throw Illegal_Transformation("Cannot convert zero point to affine"); - - const BigInt& r2 = curve.get_r2(); - - BigInt z2 = monty_sqr(coord_z); - z2 = inverse_mod(z2, curve.get_p()); - - z2 = monty_mult(z2, r2); - return monty_mult(coord_x, z2); - } - -BigInt PointGFp::get_affine_y() const - { - if(is_zero()) - throw Illegal_Transformation("Cannot convert zero point to affine"); - - const BigInt& r2 = curve.get_r2(); - - BigInt z3 = monty_mult(coord_z, monty_sqr(coord_z)); - z3 = inverse_mod(z3, curve.get_p()); - z3 = monty_mult(z3, r2); - return monty_mult(coord_y, z3); - } - -bool PointGFp::on_the_curve() const - { - /* - Is the point still on the curve?? (If everything is correct, the - point is always on its curve; then the function will return true. - If somehow the state is corrupted, which suggests a fault attack - (or internal computational error), then return false. - */ - - if(is_zero()) - return true; - - BigInt y2 = monty_mult(monty_sqr(coord_y), 1); - BigInt x3 = monty_mult(coord_x, monty_sqr(coord_x)); - - BigInt ax = monty_mult(coord_x, curve.get_a_r()); - - const BigInt& b_r = curve.get_b_r(); - - BigInt z2 = monty_sqr(coord_z); - - if(coord_z == z2) // Is z equal to 1 (in Montgomery form)? - { - if(y2 != monty_mult(x3 + ax + b_r, 1)) - return false; - } - - BigInt z3 = monty_mult(coord_z, z2); - - BigInt ax_z4 = monty_mult(ax, monty_sqr(z2)); - - BigInt b_z6 = monty_mult(b_r, monty_sqr(z3)); - - if(y2 != monty_mult(x3 + ax_z4 + b_z6, 1)) - return false; - - return true; - } - -// swaps the states of *this and other, does not throw! -void PointGFp::swap(PointGFp& other) - { - curve.swap(other.curve); - coord_x.swap(other.coord_x); - coord_y.swap(other.coord_y); - coord_z.swap(other.coord_z); - ws.swap(other.ws); - } - -bool PointGFp::operator==(const PointGFp& other) const - { - if(get_curve() != other.get_curve()) - return false; - - // If this is zero, only equal if other is also zero - if(is_zero()) - return other.is_zero(); - - return (get_affine_x() == other.get_affine_x() && - get_affine_y() == other.get_affine_y()); - } - -// encoding and decoding -SecureVector EC2OSP(const PointGFp& point, byte format) - { - if(point.is_zero()) - return SecureVector(1); // single 0 byte - - const size_t p_bytes = point.get_curve().get_p().bytes(); - - BigInt x = point.get_affine_x(); - BigInt y = point.get_affine_y(); - - SecureVector bX = BigInt::encode_1363(x, p_bytes); - SecureVector bY = BigInt::encode_1363(y, p_bytes); - - if(format == PointGFp::UNCOMPRESSED) - { - SecureVector result; - result.push_back(0x04); - - result += bX; - result += bY; - - return result; - } - else if(format == PointGFp::COMPRESSED) - { - SecureVector result; - result.push_back(0x02 | static_cast(y.get_bit(0))); - - result += bX; - - return result; - } - else if(format == PointGFp::HYBRID) - { - SecureVector result; - result.push_back(0x06 | static_cast(y.get_bit(0))); - - result += bX; - result += bY; - - return result; - } - else - throw Invalid_Argument("illegal point encoding format specification"); - } - -namespace { - -BigInt decompress_point(bool yMod2, - const BigInt& x, - const CurveGFp& curve) - { - BigInt xpow3 = x * x * x; - - BigInt g = curve.get_a() * x; - g += xpow3; - g += curve.get_b(); - g = g % curve.get_p(); - - BigInt z = ressol(g, curve.get_p()); - - if(z < 0) - throw Illegal_Point("error during decompression"); - - if(z.get_bit(0) != yMod2) - z = curve.get_p() - z; - - return z; - } - -} - -PointGFp OS2ECP(const byte data[], size_t data_len, - const CurveGFp& curve) - { - if(data_len <= 1) - return PointGFp(curve); // return zero - - const byte pc = data[0]; - - BigInt x, y; - - if(pc == 2 || pc == 3) - { - //compressed form - x = BigInt::decode(&data[1], data_len - 1); - - const bool y_mod_2 = ((pc & 0x01) == 1); - y = decompress_point(y_mod_2, x, curve); - } - else if(pc == 4) - { - const size_t l = (data_len - 1) / 2; - - // uncompressed form - x = BigInt::decode(&data[1], l); - y = BigInt::decode(&data[l+1], l); - } - else if(pc == 6 || pc == 7) - { - const size_t l = (data_len - 1) / 2; - - // hybrid form - x = BigInt::decode(&data[1], l); - y = BigInt::decode(&data[l+1], l); - - const bool y_mod_2 = ((pc & 0x01) == 1); - - if(decompress_point(y_mod_2, x, curve) != y) - throw Illegal_Point("OS2ECP: Decoding error in hybrid format"); - } - else - throw Invalid_Argument("OS2ECP: Unknown format type"); - - PointGFp result(curve, x, y); - - if(!result.on_the_curve()) - throw Illegal_Point("OS2ECP: Decoded point was not on the curve"); - - return result; - } - -} -/* -* Lowest Level MPI Algorithms -* (C) 1999-2010 Jack Lloyd -* 2006 Luca Piccarreta -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -extern "C" { - -/* -* Two Operand Addition, No Carry -*/ -word bigint_add2_nc(word x[], size_t x_size, const word y[], size_t y_size) - { - word carry = 0; - - const size_t blocks = y_size - (y_size % 8); - - for(size_t i = 0; i != blocks; i += 8) - carry = word8_add2(x + i, y + i, carry); - - for(size_t i = blocks; i != y_size; ++i) - x[i] = word_add(x[i], y[i], &carry); - - for(size_t i = y_size; i != x_size; ++i) - x[i] = word_add(x[i], 0, &carry); - - return carry; - } - -/* -* Three Operand Addition, No Carry -*/ -word bigint_add3_nc(word z[], const word x[], size_t x_size, - const word y[], size_t y_size) - { - if(x_size < y_size) - { return bigint_add3_nc(z, y, y_size, x, x_size); } - - word carry = 0; - - const size_t blocks = y_size - (y_size % 8); - - for(size_t i = 0; i != blocks; i += 8) - carry = word8_add3(z + i, x + i, y + i, carry); - - for(size_t i = blocks; i != y_size; ++i) - z[i] = word_add(x[i], y[i], &carry); - - for(size_t i = y_size; i != x_size; ++i) - z[i] = word_add(x[i], 0, &carry); - - return carry; - } - -/* -* Two Operand Addition -*/ -void bigint_add2(word x[], size_t x_size, const word y[], size_t y_size) - { - if(bigint_add2_nc(x, x_size, y, y_size)) - x[x_size] += 1; - } - -/* -* Three Operand Addition -*/ -void bigint_add3(word z[], const word x[], size_t x_size, - const word y[], size_t y_size) - { - z[(x_size > y_size ? x_size : y_size)] += - bigint_add3_nc(z, x, x_size, y, y_size); - } - -/* -* Two Operand Subtraction -*/ -word bigint_sub2(word x[], size_t x_size, const word y[], size_t y_size) - { - word borrow = 0; - - const size_t blocks = y_size - (y_size % 8); - - for(size_t i = 0; i != blocks; i += 8) - borrow = word8_sub2(x + i, y + i, borrow); - - for(size_t i = blocks; i != y_size; ++i) - x[i] = word_sub(x[i], y[i], &borrow); - - for(size_t i = y_size; i != x_size; ++i) - x[i] = word_sub(x[i], 0, &borrow); - - return borrow; - } - -/* -* Two Operand Subtraction x = y - x -*/ -void bigint_sub2_rev(word x[], const word y[], size_t y_size) - { - word borrow = 0; - - const size_t blocks = y_size - (y_size % 8); - - for(size_t i = 0; i != blocks; i += 8) - borrow = word8_sub2_rev(x + i, y + i, borrow); - - for(size_t i = blocks; i != y_size; ++i) - x[i] = word_sub(y[i], x[i], &borrow); - - if(borrow) - throw Internal_Error("bigint_sub2_rev: x >= y"); - } - -/* -* Three Operand Subtraction -*/ -word bigint_sub3(word z[], const word x[], size_t x_size, - const word y[], size_t y_size) - { - word borrow = 0; - - const size_t blocks = y_size - (y_size % 8); - - for(size_t i = 0; i != blocks; i += 8) - borrow = word8_sub3(z + i, x + i, y + i, borrow); - - for(size_t i = blocks; i != y_size; ++i) - z[i] = word_sub(x[i], y[i], &borrow); - - for(size_t i = y_size; i != x_size; ++i) - z[i] = word_sub(x[i], 0, &borrow); - - return borrow; - } - -/* -* Two Operand Linear Multiply -*/ -void bigint_linmul2(word x[], size_t x_size, word y) - { - const size_t blocks = x_size - (x_size % 8); - - word carry = 0; - - for(size_t i = 0; i != blocks; i += 8) - carry = word8_linmul2(x + i, y, carry); - - for(size_t i = blocks; i != x_size; ++i) - x[i] = word_madd2(x[i], y, &carry); - - x[x_size] = carry; - } - -/* -* Three Operand Linear Multiply -*/ -void bigint_linmul3(word z[], const word x[], size_t x_size, word y) - { - const size_t blocks = x_size - (x_size % 8); - - word carry = 0; - - for(size_t i = 0; i != blocks; i += 8) - carry = word8_linmul3(z + i, x + i, y, carry); - - for(size_t i = blocks; i != x_size; ++i) - z[i] = word_madd2(x[i], y, &carry); - - z[x_size] = carry; - } - -} - -} -/* -* Comba Multiplication and Squaring -* (C) 1999-2007,2011 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -extern "C" { - -/* -* Comba 4x4 Squaring -*/ -void bigint_comba_sqr4(word z[8], const word x[4]) - { - word w2 = 0, w1 = 0, w0 = 0; - - word3_muladd(&w2, &w1, &w0, x[ 0], x[ 0]); - z[ 0] = w0; w0 = 0; - - word3_muladd_2(&w0, &w2, &w1, x[ 0], x[ 1]); - z[ 1] = w1; w1 = 0; - - word3_muladd_2(&w1, &w0, &w2, x[ 0], x[ 2]); - word3_muladd(&w1, &w0, &w2, x[ 1], x[ 1]); - z[ 2] = w2; w2 = 0; - - word3_muladd_2(&w2, &w1, &w0, x[ 0], x[ 3]); - word3_muladd_2(&w2, &w1, &w0, x[ 1], x[ 2]); - z[ 3] = w0; w0 = 0; - - word3_muladd_2(&w0, &w2, &w1, x[ 1], x[ 3]); - word3_muladd(&w0, &w2, &w1, x[ 2], x[ 2]); - z[ 4] = w1; w1 = 0; - - word3_muladd_2(&w1, &w0, &w2, x[ 2], x[ 3]); - z[ 5] = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[ 3], x[ 3]); - z[ 6] = w0; - z[ 7] = w1; - } - -/* -* Comba 4x4 Multiplication -*/ -void bigint_comba_mul4(word z[8], const word x[4], const word y[4]) - { - word w2 = 0, w1 = 0, w0 = 0; - - word3_muladd(&w2, &w1, &w0, x[ 0], y[ 0]); - z[ 0] = w0; w0 = 0; - - word3_muladd(&w0, &w2, &w1, x[ 0], y[ 1]); - word3_muladd(&w0, &w2, &w1, x[ 1], y[ 0]); - z[ 1] = w1; w1 = 0; - - word3_muladd(&w1, &w0, &w2, x[ 0], y[ 2]); - word3_muladd(&w1, &w0, &w2, x[ 1], y[ 1]); - word3_muladd(&w1, &w0, &w2, x[ 2], y[ 0]); - z[ 2] = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[ 0], y[ 3]); - word3_muladd(&w2, &w1, &w0, x[ 1], y[ 2]); - word3_muladd(&w2, &w1, &w0, x[ 2], y[ 1]); - word3_muladd(&w2, &w1, &w0, x[ 3], y[ 0]); - z[ 3] = w0; w0 = 0; - - word3_muladd(&w0, &w2, &w1, x[ 1], y[ 3]); - word3_muladd(&w0, &w2, &w1, x[ 2], y[ 2]); - word3_muladd(&w0, &w2, &w1, x[ 3], y[ 1]); - z[ 4] = w1; w1 = 0; - - word3_muladd(&w1, &w0, &w2, x[ 2], y[ 3]); - word3_muladd(&w1, &w0, &w2, x[ 3], y[ 2]); - z[ 5] = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[ 3], y[ 3]); - z[ 6] = w0; - z[ 7] = w1; - } - -/* -* Comba 6x6 Squaring -*/ -void bigint_comba_sqr6(word z[12], const word x[6]) - { - word w2 = 0, w1 = 0, w0 = 0; - - word3_muladd(&w2, &w1, &w0, x[ 0], x[ 0]); - z[ 0] = w0; w0 = 0; - - word3_muladd_2(&w0, &w2, &w1, x[ 0], x[ 1]); - z[ 1] = w1; w1 = 0; - - word3_muladd_2(&w1, &w0, &w2, x[ 0], x[ 2]); - word3_muladd(&w1, &w0, &w2, x[ 1], x[ 1]); - z[ 2] = w2; w2 = 0; - - word3_muladd_2(&w2, &w1, &w0, x[ 0], x[ 3]); - word3_muladd_2(&w2, &w1, &w0, x[ 1], x[ 2]); - z[ 3] = w0; w0 = 0; - - word3_muladd_2(&w0, &w2, &w1, x[ 0], x[ 4]); - word3_muladd_2(&w0, &w2, &w1, x[ 1], x[ 3]); - word3_muladd(&w0, &w2, &w1, x[ 2], x[ 2]); - z[ 4] = w1; w1 = 0; - - word3_muladd_2(&w1, &w0, &w2, x[ 0], x[ 5]); - word3_muladd_2(&w1, &w0, &w2, x[ 1], x[ 4]); - word3_muladd_2(&w1, &w0, &w2, x[ 2], x[ 3]); - z[ 5] = w2; w2 = 0; - - word3_muladd_2(&w2, &w1, &w0, x[ 1], x[ 5]); - word3_muladd_2(&w2, &w1, &w0, x[ 2], x[ 4]); - word3_muladd(&w2, &w1, &w0, x[ 3], x[ 3]); - z[ 6] = w0; w0 = 0; - - word3_muladd_2(&w0, &w2, &w1, x[ 2], x[ 5]); - word3_muladd_2(&w0, &w2, &w1, x[ 3], x[ 4]); - z[ 7] = w1; w1 = 0; - - word3_muladd_2(&w1, &w0, &w2, x[ 3], x[ 5]); - word3_muladd(&w1, &w0, &w2, x[ 4], x[ 4]); - z[ 8] = w2; w2 = 0; - - word3_muladd_2(&w2, &w1, &w0, x[ 4], x[ 5]); - z[ 9] = w0; w0 = 0; - - word3_muladd(&w0, &w2, &w1, x[ 5], x[ 5]); - z[10] = w1; - z[11] = w2; - } - -/* -* Comba 6x6 Multiplication -*/ -void bigint_comba_mul6(word z[12], const word x[6], const word y[6]) - { - word w2 = 0, w1 = 0, w0 = 0; - - word3_muladd(&w2, &w1, &w0, x[ 0], y[ 0]); - z[ 0] = w0; w0 = 0; - - word3_muladd(&w0, &w2, &w1, x[ 0], y[ 1]); - word3_muladd(&w0, &w2, &w1, x[ 1], y[ 0]); - z[ 1] = w1; w1 = 0; - - word3_muladd(&w1, &w0, &w2, x[ 0], y[ 2]); - word3_muladd(&w1, &w0, &w2, x[ 1], y[ 1]); - word3_muladd(&w1, &w0, &w2, x[ 2], y[ 0]); - z[ 2] = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[ 0], y[ 3]); - word3_muladd(&w2, &w1, &w0, x[ 1], y[ 2]); - word3_muladd(&w2, &w1, &w0, x[ 2], y[ 1]); - word3_muladd(&w2, &w1, &w0, x[ 3], y[ 0]); - z[ 3] = w0; w0 = 0; - - word3_muladd(&w0, &w2, &w1, x[ 0], y[ 4]); - word3_muladd(&w0, &w2, &w1, x[ 1], y[ 3]); - word3_muladd(&w0, &w2, &w1, x[ 2], y[ 2]); - word3_muladd(&w0, &w2, &w1, x[ 3], y[ 1]); - word3_muladd(&w0, &w2, &w1, x[ 4], y[ 0]); - z[ 4] = w1; w1 = 0; - - word3_muladd(&w1, &w0, &w2, x[ 0], y[ 5]); - word3_muladd(&w1, &w0, &w2, x[ 1], y[ 4]); - word3_muladd(&w1, &w0, &w2, x[ 2], y[ 3]); - word3_muladd(&w1, &w0, &w2, x[ 3], y[ 2]); - word3_muladd(&w1, &w0, &w2, x[ 4], y[ 1]); - word3_muladd(&w1, &w0, &w2, x[ 5], y[ 0]); - z[ 5] = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[ 1], y[ 5]); - word3_muladd(&w2, &w1, &w0, x[ 2], y[ 4]); - word3_muladd(&w2, &w1, &w0, x[ 3], y[ 3]); - word3_muladd(&w2, &w1, &w0, x[ 4], y[ 2]); - word3_muladd(&w2, &w1, &w0, x[ 5], y[ 1]); - z[ 6] = w0; w0 = 0; - - word3_muladd(&w0, &w2, &w1, x[ 2], y[ 5]); - word3_muladd(&w0, &w2, &w1, x[ 3], y[ 4]); - word3_muladd(&w0, &w2, &w1, x[ 4], y[ 3]); - word3_muladd(&w0, &w2, &w1, x[ 5], y[ 2]); - z[ 7] = w1; w1 = 0; - - word3_muladd(&w1, &w0, &w2, x[ 3], y[ 5]); - word3_muladd(&w1, &w0, &w2, x[ 4], y[ 4]); - word3_muladd(&w1, &w0, &w2, x[ 5], y[ 3]); - z[ 8] = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[ 4], y[ 5]); - word3_muladd(&w2, &w1, &w0, x[ 5], y[ 4]); - z[ 9] = w0; w0 = 0; - - word3_muladd(&w0, &w2, &w1, x[ 5], y[ 5]); - z[10] = w1; - z[11] = w2; - } - -/* -* Comba 8x8 Squaring -*/ -void bigint_comba_sqr8(word z[16], const word x[8]) - { - word w2 = 0, w1 = 0, w0 = 0; - - word3_muladd(&w2, &w1, &w0, x[ 0], x[ 0]); - z[ 0] = w0; w0 = 0; - - word3_muladd_2(&w0, &w2, &w1, x[ 0], x[ 1]); - z[ 1] = w1; w1 = 0; - - word3_muladd_2(&w1, &w0, &w2, x[ 0], x[ 2]); - word3_muladd(&w1, &w0, &w2, x[ 1], x[ 1]); - z[ 2] = w2; w2 = 0; - - word3_muladd_2(&w2, &w1, &w0, x[ 0], x[ 3]); - word3_muladd_2(&w2, &w1, &w0, x[ 1], x[ 2]); - z[ 3] = w0; w0 = 0; - - word3_muladd_2(&w0, &w2, &w1, x[ 0], x[ 4]); - word3_muladd_2(&w0, &w2, &w1, x[ 1], x[ 3]); - word3_muladd(&w0, &w2, &w1, x[ 2], x[ 2]); - z[ 4] = w1; w1 = 0; - - word3_muladd_2(&w1, &w0, &w2, x[ 0], x[ 5]); - word3_muladd_2(&w1, &w0, &w2, x[ 1], x[ 4]); - word3_muladd_2(&w1, &w0, &w2, x[ 2], x[ 3]); - z[ 5] = w2; w2 = 0; - - word3_muladd_2(&w2, &w1, &w0, x[ 0], x[ 6]); - word3_muladd_2(&w2, &w1, &w0, x[ 1], x[ 5]); - word3_muladd_2(&w2, &w1, &w0, x[ 2], x[ 4]); - word3_muladd(&w2, &w1, &w0, x[ 3], x[ 3]); - z[ 6] = w0; w0 = 0; - - word3_muladd_2(&w0, &w2, &w1, x[ 0], x[ 7]); - word3_muladd_2(&w0, &w2, &w1, x[ 1], x[ 6]); - word3_muladd_2(&w0, &w2, &w1, x[ 2], x[ 5]); - word3_muladd_2(&w0, &w2, &w1, x[ 3], x[ 4]); - z[ 7] = w1; w1 = 0; - - word3_muladd_2(&w1, &w0, &w2, x[ 1], x[ 7]); - word3_muladd_2(&w1, &w0, &w2, x[ 2], x[ 6]); - word3_muladd_2(&w1, &w0, &w2, x[ 3], x[ 5]); - word3_muladd(&w1, &w0, &w2, x[ 4], x[ 4]); - z[ 8] = w2; w2 = 0; - - word3_muladd_2(&w2, &w1, &w0, x[ 2], x[ 7]); - word3_muladd_2(&w2, &w1, &w0, x[ 3], x[ 6]); - word3_muladd_2(&w2, &w1, &w0, x[ 4], x[ 5]); - z[ 9] = w0; w0 = 0; - - word3_muladd_2(&w0, &w2, &w1, x[ 3], x[ 7]); - word3_muladd_2(&w0, &w2, &w1, x[ 4], x[ 6]); - word3_muladd(&w0, &w2, &w1, x[ 5], x[ 5]); - z[10] = w1; w1 = 0; - - word3_muladd_2(&w1, &w0, &w2, x[ 4], x[ 7]); - word3_muladd_2(&w1, &w0, &w2, x[ 5], x[ 6]); - z[11] = w2; w2 = 0; - - word3_muladd_2(&w2, &w1, &w0, x[ 5], x[ 7]); - word3_muladd(&w2, &w1, &w0, x[ 6], x[ 6]); - z[12] = w0; w0 = 0; - - word3_muladd_2(&w0, &w2, &w1, x[ 6], x[ 7]); - z[13] = w1; w1 = 0; - - word3_muladd(&w1, &w0, &w2, x[ 7], x[ 7]); - z[14] = w2; - z[15] = w0; - } - -/* -* Comba 8x8 Multiplication -*/ -void bigint_comba_mul8(word z[16], const word x[8], const word y[8]) - { - word w2 = 0, w1 = 0, w0 = 0; - - word3_muladd(&w2, &w1, &w0, x[ 0], y[ 0]); - z[ 0] = w0; w0 = 0; - - word3_muladd(&w0, &w2, &w1, x[ 0], y[ 1]); - word3_muladd(&w0, &w2, &w1, x[ 1], y[ 0]); - z[ 1] = w1; w1 = 0; - - word3_muladd(&w1, &w0, &w2, x[ 0], y[ 2]); - word3_muladd(&w1, &w0, &w2, x[ 1], y[ 1]); - word3_muladd(&w1, &w0, &w2, x[ 2], y[ 0]); - z[ 2] = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[ 0], y[ 3]); - word3_muladd(&w2, &w1, &w0, x[ 1], y[ 2]); - word3_muladd(&w2, &w1, &w0, x[ 2], y[ 1]); - word3_muladd(&w2, &w1, &w0, x[ 3], y[ 0]); - z[ 3] = w0; w0 = 0; - - word3_muladd(&w0, &w2, &w1, x[ 0], y[ 4]); - word3_muladd(&w0, &w2, &w1, x[ 1], y[ 3]); - word3_muladd(&w0, &w2, &w1, x[ 2], y[ 2]); - word3_muladd(&w0, &w2, &w1, x[ 3], y[ 1]); - word3_muladd(&w0, &w2, &w1, x[ 4], y[ 0]); - z[ 4] = w1; w1 = 0; - - word3_muladd(&w1, &w0, &w2, x[ 0], y[ 5]); - word3_muladd(&w1, &w0, &w2, x[ 1], y[ 4]); - word3_muladd(&w1, &w0, &w2, x[ 2], y[ 3]); - word3_muladd(&w1, &w0, &w2, x[ 3], y[ 2]); - word3_muladd(&w1, &w0, &w2, x[ 4], y[ 1]); - word3_muladd(&w1, &w0, &w2, x[ 5], y[ 0]); - z[ 5] = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[ 0], y[ 6]); - word3_muladd(&w2, &w1, &w0, x[ 1], y[ 5]); - word3_muladd(&w2, &w1, &w0, x[ 2], y[ 4]); - word3_muladd(&w2, &w1, &w0, x[ 3], y[ 3]); - word3_muladd(&w2, &w1, &w0, x[ 4], y[ 2]); - word3_muladd(&w2, &w1, &w0, x[ 5], y[ 1]); - word3_muladd(&w2, &w1, &w0, x[ 6], y[ 0]); - z[ 6] = w0; w0 = 0; - - word3_muladd(&w0, &w2, &w1, x[ 0], y[ 7]); - word3_muladd(&w0, &w2, &w1, x[ 1], y[ 6]); - word3_muladd(&w0, &w2, &w1, x[ 2], y[ 5]); - word3_muladd(&w0, &w2, &w1, x[ 3], y[ 4]); - word3_muladd(&w0, &w2, &w1, x[ 4], y[ 3]); - word3_muladd(&w0, &w2, &w1, x[ 5], y[ 2]); - word3_muladd(&w0, &w2, &w1, x[ 6], y[ 1]); - word3_muladd(&w0, &w2, &w1, x[ 7], y[ 0]); - z[ 7] = w1; w1 = 0; - - word3_muladd(&w1, &w0, &w2, x[ 1], y[ 7]); - word3_muladd(&w1, &w0, &w2, x[ 2], y[ 6]); - word3_muladd(&w1, &w0, &w2, x[ 3], y[ 5]); - word3_muladd(&w1, &w0, &w2, x[ 4], y[ 4]); - word3_muladd(&w1, &w0, &w2, x[ 5], y[ 3]); - word3_muladd(&w1, &w0, &w2, x[ 6], y[ 2]); - word3_muladd(&w1, &w0, &w2, x[ 7], y[ 1]); - z[ 8] = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[ 2], y[ 7]); - word3_muladd(&w2, &w1, &w0, x[ 3], y[ 6]); - word3_muladd(&w2, &w1, &w0, x[ 4], y[ 5]); - word3_muladd(&w2, &w1, &w0, x[ 5], y[ 4]); - word3_muladd(&w2, &w1, &w0, x[ 6], y[ 3]); - word3_muladd(&w2, &w1, &w0, x[ 7], y[ 2]); - z[ 9] = w0; w0 = 0; - - word3_muladd(&w0, &w2, &w1, x[ 3], y[ 7]); - word3_muladd(&w0, &w2, &w1, x[ 4], y[ 6]); - word3_muladd(&w0, &w2, &w1, x[ 5], y[ 5]); - word3_muladd(&w0, &w2, &w1, x[ 6], y[ 4]); - word3_muladd(&w0, &w2, &w1, x[ 7], y[ 3]); - z[10] = w1; w1 = 0; - - word3_muladd(&w1, &w0, &w2, x[ 4], y[ 7]); - word3_muladd(&w1, &w0, &w2, x[ 5], y[ 6]); - word3_muladd(&w1, &w0, &w2, x[ 6], y[ 5]); - word3_muladd(&w1, &w0, &w2, x[ 7], y[ 4]); - z[11] = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[ 5], y[ 7]); - word3_muladd(&w2, &w1, &w0, x[ 6], y[ 6]); - word3_muladd(&w2, &w1, &w0, x[ 7], y[ 5]); - z[12] = w0; w0 = 0; - - word3_muladd(&w0, &w2, &w1, x[ 6], y[ 7]); - word3_muladd(&w0, &w2, &w1, x[ 7], y[ 6]); - z[13] = w1; w1 = 0; - - word3_muladd(&w1, &w0, &w2, x[ 7], y[ 7]); - z[14] = w2; - z[15] = w0; - } - -/* -* Comba 16x16 Squaring -*/ -void bigint_comba_sqr16(word z[32], const word x[16]) - { - word w2 = 0, w1 = 0, w0 = 0; - - word3_muladd(&w2, &w1, &w0, x[ 0], x[ 0]); - z[ 0] = w0; w0 = 0; - - word3_muladd_2(&w0, &w2, &w1, x[ 0], x[ 1]); - z[ 1] = w1; w1 = 0; - - word3_muladd_2(&w1, &w0, &w2, x[ 0], x[ 2]); - word3_muladd(&w1, &w0, &w2, x[ 1], x[ 1]); - z[ 2] = w2; w2 = 0; - - word3_muladd_2(&w2, &w1, &w0, x[ 0], x[ 3]); - word3_muladd_2(&w2, &w1, &w0, x[ 1], x[ 2]); - z[ 3] = w0; w0 = 0; - - word3_muladd_2(&w0, &w2, &w1, x[ 0], x[ 4]); - word3_muladd_2(&w0, &w2, &w1, x[ 1], x[ 3]); - word3_muladd(&w0, &w2, &w1, x[ 2], x[ 2]); - z[ 4] = w1; w1 = 0; - - word3_muladd_2(&w1, &w0, &w2, x[ 0], x[ 5]); - word3_muladd_2(&w1, &w0, &w2, x[ 1], x[ 4]); - word3_muladd_2(&w1, &w0, &w2, x[ 2], x[ 3]); - z[ 5] = w2; w2 = 0; - - word3_muladd_2(&w2, &w1, &w0, x[ 0], x[ 6]); - word3_muladd_2(&w2, &w1, &w0, x[ 1], x[ 5]); - word3_muladd_2(&w2, &w1, &w0, x[ 2], x[ 4]); - word3_muladd(&w2, &w1, &w0, x[ 3], x[ 3]); - z[ 6] = w0; w0 = 0; - - word3_muladd_2(&w0, &w2, &w1, x[ 0], x[ 7]); - word3_muladd_2(&w0, &w2, &w1, x[ 1], x[ 6]); - word3_muladd_2(&w0, &w2, &w1, x[ 2], x[ 5]); - word3_muladd_2(&w0, &w2, &w1, x[ 3], x[ 4]); - z[ 7] = w1; w1 = 0; - - word3_muladd_2(&w1, &w0, &w2, x[ 0], x[ 8]); - word3_muladd_2(&w1, &w0, &w2, x[ 1], x[ 7]); - word3_muladd_2(&w1, &w0, &w2, x[ 2], x[ 6]); - word3_muladd_2(&w1, &w0, &w2, x[ 3], x[ 5]); - word3_muladd(&w1, &w0, &w2, x[ 4], x[ 4]); - z[ 8] = w2; w2 = 0; - - word3_muladd_2(&w2, &w1, &w0, x[ 0], x[ 9]); - word3_muladd_2(&w2, &w1, &w0, x[ 1], x[ 8]); - word3_muladd_2(&w2, &w1, &w0, x[ 2], x[ 7]); - word3_muladd_2(&w2, &w1, &w0, x[ 3], x[ 6]); - word3_muladd_2(&w2, &w1, &w0, x[ 4], x[ 5]); - z[ 9] = w0; w0 = 0; - - word3_muladd_2(&w0, &w2, &w1, x[ 0], x[10]); - word3_muladd_2(&w0, &w2, &w1, x[ 1], x[ 9]); - word3_muladd_2(&w0, &w2, &w1, x[ 2], x[ 8]); - word3_muladd_2(&w0, &w2, &w1, x[ 3], x[ 7]); - word3_muladd_2(&w0, &w2, &w1, x[ 4], x[ 6]); - word3_muladd(&w0, &w2, &w1, x[ 5], x[ 5]); - z[10] = w1; w1 = 0; - - word3_muladd_2(&w1, &w0, &w2, x[ 0], x[11]); - word3_muladd_2(&w1, &w0, &w2, x[ 1], x[10]); - word3_muladd_2(&w1, &w0, &w2, x[ 2], x[ 9]); - word3_muladd_2(&w1, &w0, &w2, x[ 3], x[ 8]); - word3_muladd_2(&w1, &w0, &w2, x[ 4], x[ 7]); - word3_muladd_2(&w1, &w0, &w2, x[ 5], x[ 6]); - z[11] = w2; w2 = 0; - - word3_muladd_2(&w2, &w1, &w0, x[ 0], x[12]); - word3_muladd_2(&w2, &w1, &w0, x[ 1], x[11]); - word3_muladd_2(&w2, &w1, &w0, x[ 2], x[10]); - word3_muladd_2(&w2, &w1, &w0, x[ 3], x[ 9]); - word3_muladd_2(&w2, &w1, &w0, x[ 4], x[ 8]); - word3_muladd_2(&w2, &w1, &w0, x[ 5], x[ 7]); - word3_muladd(&w2, &w1, &w0, x[ 6], x[ 6]); - z[12] = w0; w0 = 0; - - word3_muladd_2(&w0, &w2, &w1, x[ 0], x[13]); - word3_muladd_2(&w0, &w2, &w1, x[ 1], x[12]); - word3_muladd_2(&w0, &w2, &w1, x[ 2], x[11]); - word3_muladd_2(&w0, &w2, &w1, x[ 3], x[10]); - word3_muladd_2(&w0, &w2, &w1, x[ 4], x[ 9]); - word3_muladd_2(&w0, &w2, &w1, x[ 5], x[ 8]); - word3_muladd_2(&w0, &w2, &w1, x[ 6], x[ 7]); - z[13] = w1; w1 = 0; - - word3_muladd_2(&w1, &w0, &w2, x[ 0], x[14]); - word3_muladd_2(&w1, &w0, &w2, x[ 1], x[13]); - word3_muladd_2(&w1, &w0, &w2, x[ 2], x[12]); - word3_muladd_2(&w1, &w0, &w2, x[ 3], x[11]); - word3_muladd_2(&w1, &w0, &w2, x[ 4], x[10]); - word3_muladd_2(&w1, &w0, &w2, x[ 5], x[ 9]); - word3_muladd_2(&w1, &w0, &w2, x[ 6], x[ 8]); - word3_muladd(&w1, &w0, &w2, x[ 7], x[ 7]); - z[14] = w2; w2 = 0; - - word3_muladd_2(&w2, &w1, &w0, x[ 0], x[15]); - word3_muladd_2(&w2, &w1, &w0, x[ 1], x[14]); - word3_muladd_2(&w2, &w1, &w0, x[ 2], x[13]); - word3_muladd_2(&w2, &w1, &w0, x[ 3], x[12]); - word3_muladd_2(&w2, &w1, &w0, x[ 4], x[11]); - word3_muladd_2(&w2, &w1, &w0, x[ 5], x[10]); - word3_muladd_2(&w2, &w1, &w0, x[ 6], x[ 9]); - word3_muladd_2(&w2, &w1, &w0, x[ 7], x[ 8]); - z[15] = w0; w0 = 0; - - word3_muladd_2(&w0, &w2, &w1, x[ 1], x[15]); - word3_muladd_2(&w0, &w2, &w1, x[ 2], x[14]); - word3_muladd_2(&w0, &w2, &w1, x[ 3], x[13]); - word3_muladd_2(&w0, &w2, &w1, x[ 4], x[12]); - word3_muladd_2(&w0, &w2, &w1, x[ 5], x[11]); - word3_muladd_2(&w0, &w2, &w1, x[ 6], x[10]); - word3_muladd_2(&w0, &w2, &w1, x[ 7], x[ 9]); - word3_muladd(&w0, &w2, &w1, x[ 8], x[ 8]); - z[16] = w1; w1 = 0; - - word3_muladd_2(&w1, &w0, &w2, x[ 2], x[15]); - word3_muladd_2(&w1, &w0, &w2, x[ 3], x[14]); - word3_muladd_2(&w1, &w0, &w2, x[ 4], x[13]); - word3_muladd_2(&w1, &w0, &w2, x[ 5], x[12]); - word3_muladd_2(&w1, &w0, &w2, x[ 6], x[11]); - word3_muladd_2(&w1, &w0, &w2, x[ 7], x[10]); - word3_muladd_2(&w1, &w0, &w2, x[ 8], x[ 9]); - z[17] = w2; w2 = 0; - - word3_muladd_2(&w2, &w1, &w0, x[ 3], x[15]); - word3_muladd_2(&w2, &w1, &w0, x[ 4], x[14]); - word3_muladd_2(&w2, &w1, &w0, x[ 5], x[13]); - word3_muladd_2(&w2, &w1, &w0, x[ 6], x[12]); - word3_muladd_2(&w2, &w1, &w0, x[ 7], x[11]); - word3_muladd_2(&w2, &w1, &w0, x[ 8], x[10]); - word3_muladd(&w2, &w1, &w0, x[ 9], x[ 9]); - z[18] = w0; w0 = 0; - - word3_muladd_2(&w0, &w2, &w1, x[ 4], x[15]); - word3_muladd_2(&w0, &w2, &w1, x[ 5], x[14]); - word3_muladd_2(&w0, &w2, &w1, x[ 6], x[13]); - word3_muladd_2(&w0, &w2, &w1, x[ 7], x[12]); - word3_muladd_2(&w0, &w2, &w1, x[ 8], x[11]); - word3_muladd_2(&w0, &w2, &w1, x[ 9], x[10]); - z[19] = w1; w1 = 0; - - word3_muladd_2(&w1, &w0, &w2, x[ 5], x[15]); - word3_muladd_2(&w1, &w0, &w2, x[ 6], x[14]); - word3_muladd_2(&w1, &w0, &w2, x[ 7], x[13]); - word3_muladd_2(&w1, &w0, &w2, x[ 8], x[12]); - word3_muladd_2(&w1, &w0, &w2, x[ 9], x[11]); - word3_muladd(&w1, &w0, &w2, x[10], x[10]); - z[20] = w2; w2 = 0; - - word3_muladd_2(&w2, &w1, &w0, x[ 6], x[15]); - word3_muladd_2(&w2, &w1, &w0, x[ 7], x[14]); - word3_muladd_2(&w2, &w1, &w0, x[ 8], x[13]); - word3_muladd_2(&w2, &w1, &w0, x[ 9], x[12]); - word3_muladd_2(&w2, &w1, &w0, x[10], x[11]); - z[21] = w0; w0 = 0; - - word3_muladd_2(&w0, &w2, &w1, x[ 7], x[15]); - word3_muladd_2(&w0, &w2, &w1, x[ 8], x[14]); - word3_muladd_2(&w0, &w2, &w1, x[ 9], x[13]); - word3_muladd_2(&w0, &w2, &w1, x[10], x[12]); - word3_muladd(&w0, &w2, &w1, x[11], x[11]); - z[22] = w1; w1 = 0; - - word3_muladd_2(&w1, &w0, &w2, x[ 8], x[15]); - word3_muladd_2(&w1, &w0, &w2, x[ 9], x[14]); - word3_muladd_2(&w1, &w0, &w2, x[10], x[13]); - word3_muladd_2(&w1, &w0, &w2, x[11], x[12]); - z[23] = w2; w2 = 0; - - word3_muladd_2(&w2, &w1, &w0, x[ 9], x[15]); - word3_muladd_2(&w2, &w1, &w0, x[10], x[14]); - word3_muladd_2(&w2, &w1, &w0, x[11], x[13]); - word3_muladd(&w2, &w1, &w0, x[12], x[12]); - z[24] = w0; w0 = 0; - - word3_muladd_2(&w0, &w2, &w1, x[10], x[15]); - word3_muladd_2(&w0, &w2, &w1, x[11], x[14]); - word3_muladd_2(&w0, &w2, &w1, x[12], x[13]); - z[25] = w1; w1 = 0; - - word3_muladd_2(&w1, &w0, &w2, x[11], x[15]); - word3_muladd_2(&w1, &w0, &w2, x[12], x[14]); - word3_muladd(&w1, &w0, &w2, x[13], x[13]); - z[26] = w2; w2 = 0; - - word3_muladd_2(&w2, &w1, &w0, x[12], x[15]); - word3_muladd_2(&w2, &w1, &w0, x[13], x[14]); - z[27] = w0; w0 = 0; - - word3_muladd_2(&w0, &w2, &w1, x[13], x[15]); - word3_muladd(&w0, &w2, &w1, x[14], x[14]); - z[28] = w1; w1 = 0; - - word3_muladd_2(&w1, &w0, &w2, x[14], x[15]); - z[29] = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[15], x[15]); - z[30] = w0; - z[31] = w1; - } - -/* -* Comba 16x16 Multiplication -*/ -void bigint_comba_mul16(word z[32], const word x[16], const word y[16]) - { - word w2 = 0, w1 = 0, w0 = 0; - - word3_muladd(&w2, &w1, &w0, x[ 0], y[ 0]); - z[ 0] = w0; w0 = 0; - - word3_muladd(&w0, &w2, &w1, x[ 0], y[ 1]); - word3_muladd(&w0, &w2, &w1, x[ 1], y[ 0]); - z[ 1] = w1; w1 = 0; - - word3_muladd(&w1, &w0, &w2, x[ 0], y[ 2]); - word3_muladd(&w1, &w0, &w2, x[ 1], y[ 1]); - word3_muladd(&w1, &w0, &w2, x[ 2], y[ 0]); - z[ 2] = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[ 0], y[ 3]); - word3_muladd(&w2, &w1, &w0, x[ 1], y[ 2]); - word3_muladd(&w2, &w1, &w0, x[ 2], y[ 1]); - word3_muladd(&w2, &w1, &w0, x[ 3], y[ 0]); - z[ 3] = w0; w0 = 0; - - word3_muladd(&w0, &w2, &w1, x[ 0], y[ 4]); - word3_muladd(&w0, &w2, &w1, x[ 1], y[ 3]); - word3_muladd(&w0, &w2, &w1, x[ 2], y[ 2]); - word3_muladd(&w0, &w2, &w1, x[ 3], y[ 1]); - word3_muladd(&w0, &w2, &w1, x[ 4], y[ 0]); - z[ 4] = w1; w1 = 0; - - word3_muladd(&w1, &w0, &w2, x[ 0], y[ 5]); - word3_muladd(&w1, &w0, &w2, x[ 1], y[ 4]); - word3_muladd(&w1, &w0, &w2, x[ 2], y[ 3]); - word3_muladd(&w1, &w0, &w2, x[ 3], y[ 2]); - word3_muladd(&w1, &w0, &w2, x[ 4], y[ 1]); - word3_muladd(&w1, &w0, &w2, x[ 5], y[ 0]); - z[ 5] = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[ 0], y[ 6]); - word3_muladd(&w2, &w1, &w0, x[ 1], y[ 5]); - word3_muladd(&w2, &w1, &w0, x[ 2], y[ 4]); - word3_muladd(&w2, &w1, &w0, x[ 3], y[ 3]); - word3_muladd(&w2, &w1, &w0, x[ 4], y[ 2]); - word3_muladd(&w2, &w1, &w0, x[ 5], y[ 1]); - word3_muladd(&w2, &w1, &w0, x[ 6], y[ 0]); - z[ 6] = w0; w0 = 0; - - word3_muladd(&w0, &w2, &w1, x[ 0], y[ 7]); - word3_muladd(&w0, &w2, &w1, x[ 1], y[ 6]); - word3_muladd(&w0, &w2, &w1, x[ 2], y[ 5]); - word3_muladd(&w0, &w2, &w1, x[ 3], y[ 4]); - word3_muladd(&w0, &w2, &w1, x[ 4], y[ 3]); - word3_muladd(&w0, &w2, &w1, x[ 5], y[ 2]); - word3_muladd(&w0, &w2, &w1, x[ 6], y[ 1]); - word3_muladd(&w0, &w2, &w1, x[ 7], y[ 0]); - z[ 7] = w1; w1 = 0; - - word3_muladd(&w1, &w0, &w2, x[ 0], y[ 8]); - word3_muladd(&w1, &w0, &w2, x[ 1], y[ 7]); - word3_muladd(&w1, &w0, &w2, x[ 2], y[ 6]); - word3_muladd(&w1, &w0, &w2, x[ 3], y[ 5]); - word3_muladd(&w1, &w0, &w2, x[ 4], y[ 4]); - word3_muladd(&w1, &w0, &w2, x[ 5], y[ 3]); - word3_muladd(&w1, &w0, &w2, x[ 6], y[ 2]); - word3_muladd(&w1, &w0, &w2, x[ 7], y[ 1]); - word3_muladd(&w1, &w0, &w2, x[ 8], y[ 0]); - z[ 8] = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[ 0], y[ 9]); - word3_muladd(&w2, &w1, &w0, x[ 1], y[ 8]); - word3_muladd(&w2, &w1, &w0, x[ 2], y[ 7]); - word3_muladd(&w2, &w1, &w0, x[ 3], y[ 6]); - word3_muladd(&w2, &w1, &w0, x[ 4], y[ 5]); - word3_muladd(&w2, &w1, &w0, x[ 5], y[ 4]); - word3_muladd(&w2, &w1, &w0, x[ 6], y[ 3]); - word3_muladd(&w2, &w1, &w0, x[ 7], y[ 2]); - word3_muladd(&w2, &w1, &w0, x[ 8], y[ 1]); - word3_muladd(&w2, &w1, &w0, x[ 9], y[ 0]); - z[ 9] = w0; w0 = 0; - - word3_muladd(&w0, &w2, &w1, x[ 0], y[10]); - word3_muladd(&w0, &w2, &w1, x[ 1], y[ 9]); - word3_muladd(&w0, &w2, &w1, x[ 2], y[ 8]); - word3_muladd(&w0, &w2, &w1, x[ 3], y[ 7]); - word3_muladd(&w0, &w2, &w1, x[ 4], y[ 6]); - word3_muladd(&w0, &w2, &w1, x[ 5], y[ 5]); - word3_muladd(&w0, &w2, &w1, x[ 6], y[ 4]); - word3_muladd(&w0, &w2, &w1, x[ 7], y[ 3]); - word3_muladd(&w0, &w2, &w1, x[ 8], y[ 2]); - word3_muladd(&w0, &w2, &w1, x[ 9], y[ 1]); - word3_muladd(&w0, &w2, &w1, x[10], y[ 0]); - z[10] = w1; w1 = 0; - - word3_muladd(&w1, &w0, &w2, x[ 0], y[11]); - word3_muladd(&w1, &w0, &w2, x[ 1], y[10]); - word3_muladd(&w1, &w0, &w2, x[ 2], y[ 9]); - word3_muladd(&w1, &w0, &w2, x[ 3], y[ 8]); - word3_muladd(&w1, &w0, &w2, x[ 4], y[ 7]); - word3_muladd(&w1, &w0, &w2, x[ 5], y[ 6]); - word3_muladd(&w1, &w0, &w2, x[ 6], y[ 5]); - word3_muladd(&w1, &w0, &w2, x[ 7], y[ 4]); - word3_muladd(&w1, &w0, &w2, x[ 8], y[ 3]); - word3_muladd(&w1, &w0, &w2, x[ 9], y[ 2]); - word3_muladd(&w1, &w0, &w2, x[10], y[ 1]); - word3_muladd(&w1, &w0, &w2, x[11], y[ 0]); - z[11] = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[ 0], y[12]); - word3_muladd(&w2, &w1, &w0, x[ 1], y[11]); - word3_muladd(&w2, &w1, &w0, x[ 2], y[10]); - word3_muladd(&w2, &w1, &w0, x[ 3], y[ 9]); - word3_muladd(&w2, &w1, &w0, x[ 4], y[ 8]); - word3_muladd(&w2, &w1, &w0, x[ 5], y[ 7]); - word3_muladd(&w2, &w1, &w0, x[ 6], y[ 6]); - word3_muladd(&w2, &w1, &w0, x[ 7], y[ 5]); - word3_muladd(&w2, &w1, &w0, x[ 8], y[ 4]); - word3_muladd(&w2, &w1, &w0, x[ 9], y[ 3]); - word3_muladd(&w2, &w1, &w0, x[10], y[ 2]); - word3_muladd(&w2, &w1, &w0, x[11], y[ 1]); - word3_muladd(&w2, &w1, &w0, x[12], y[ 0]); - z[12] = w0; w0 = 0; - - word3_muladd(&w0, &w2, &w1, x[ 0], y[13]); - word3_muladd(&w0, &w2, &w1, x[ 1], y[12]); - word3_muladd(&w0, &w2, &w1, x[ 2], y[11]); - word3_muladd(&w0, &w2, &w1, x[ 3], y[10]); - word3_muladd(&w0, &w2, &w1, x[ 4], y[ 9]); - word3_muladd(&w0, &w2, &w1, x[ 5], y[ 8]); - word3_muladd(&w0, &w2, &w1, x[ 6], y[ 7]); - word3_muladd(&w0, &w2, &w1, x[ 7], y[ 6]); - word3_muladd(&w0, &w2, &w1, x[ 8], y[ 5]); - word3_muladd(&w0, &w2, &w1, x[ 9], y[ 4]); - word3_muladd(&w0, &w2, &w1, x[10], y[ 3]); - word3_muladd(&w0, &w2, &w1, x[11], y[ 2]); - word3_muladd(&w0, &w2, &w1, x[12], y[ 1]); - word3_muladd(&w0, &w2, &w1, x[13], y[ 0]); - z[13] = w1; w1 = 0; - - word3_muladd(&w1, &w0, &w2, x[ 0], y[14]); - word3_muladd(&w1, &w0, &w2, x[ 1], y[13]); - word3_muladd(&w1, &w0, &w2, x[ 2], y[12]); - word3_muladd(&w1, &w0, &w2, x[ 3], y[11]); - word3_muladd(&w1, &w0, &w2, x[ 4], y[10]); - word3_muladd(&w1, &w0, &w2, x[ 5], y[ 9]); - word3_muladd(&w1, &w0, &w2, x[ 6], y[ 8]); - word3_muladd(&w1, &w0, &w2, x[ 7], y[ 7]); - word3_muladd(&w1, &w0, &w2, x[ 8], y[ 6]); - word3_muladd(&w1, &w0, &w2, x[ 9], y[ 5]); - word3_muladd(&w1, &w0, &w2, x[10], y[ 4]); - word3_muladd(&w1, &w0, &w2, x[11], y[ 3]); - word3_muladd(&w1, &w0, &w2, x[12], y[ 2]); - word3_muladd(&w1, &w0, &w2, x[13], y[ 1]); - word3_muladd(&w1, &w0, &w2, x[14], y[ 0]); - z[14] = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[ 0], y[15]); - word3_muladd(&w2, &w1, &w0, x[ 1], y[14]); - word3_muladd(&w2, &w1, &w0, x[ 2], y[13]); - word3_muladd(&w2, &w1, &w0, x[ 3], y[12]); - word3_muladd(&w2, &w1, &w0, x[ 4], y[11]); - word3_muladd(&w2, &w1, &w0, x[ 5], y[10]); - word3_muladd(&w2, &w1, &w0, x[ 6], y[ 9]); - word3_muladd(&w2, &w1, &w0, x[ 7], y[ 8]); - word3_muladd(&w2, &w1, &w0, x[ 8], y[ 7]); - word3_muladd(&w2, &w1, &w0, x[ 9], y[ 6]); - word3_muladd(&w2, &w1, &w0, x[10], y[ 5]); - word3_muladd(&w2, &w1, &w0, x[11], y[ 4]); - word3_muladd(&w2, &w1, &w0, x[12], y[ 3]); - word3_muladd(&w2, &w1, &w0, x[13], y[ 2]); - word3_muladd(&w2, &w1, &w0, x[14], y[ 1]); - word3_muladd(&w2, &w1, &w0, x[15], y[ 0]); - z[15] = w0; w0 = 0; - - word3_muladd(&w0, &w2, &w1, x[ 1], y[15]); - word3_muladd(&w0, &w2, &w1, x[ 2], y[14]); - word3_muladd(&w0, &w2, &w1, x[ 3], y[13]); - word3_muladd(&w0, &w2, &w1, x[ 4], y[12]); - word3_muladd(&w0, &w2, &w1, x[ 5], y[11]); - word3_muladd(&w0, &w2, &w1, x[ 6], y[10]); - word3_muladd(&w0, &w2, &w1, x[ 7], y[ 9]); - word3_muladd(&w0, &w2, &w1, x[ 8], y[ 8]); - word3_muladd(&w0, &w2, &w1, x[ 9], y[ 7]); - word3_muladd(&w0, &w2, &w1, x[10], y[ 6]); - word3_muladd(&w0, &w2, &w1, x[11], y[ 5]); - word3_muladd(&w0, &w2, &w1, x[12], y[ 4]); - word3_muladd(&w0, &w2, &w1, x[13], y[ 3]); - word3_muladd(&w0, &w2, &w1, x[14], y[ 2]); - word3_muladd(&w0, &w2, &w1, x[15], y[ 1]); - z[16] = w1; w1 = 0; - - word3_muladd(&w1, &w0, &w2, x[ 2], y[15]); - word3_muladd(&w1, &w0, &w2, x[ 3], y[14]); - word3_muladd(&w1, &w0, &w2, x[ 4], y[13]); - word3_muladd(&w1, &w0, &w2, x[ 5], y[12]); - word3_muladd(&w1, &w0, &w2, x[ 6], y[11]); - word3_muladd(&w1, &w0, &w2, x[ 7], y[10]); - word3_muladd(&w1, &w0, &w2, x[ 8], y[ 9]); - word3_muladd(&w1, &w0, &w2, x[ 9], y[ 8]); - word3_muladd(&w1, &w0, &w2, x[10], y[ 7]); - word3_muladd(&w1, &w0, &w2, x[11], y[ 6]); - word3_muladd(&w1, &w0, &w2, x[12], y[ 5]); - word3_muladd(&w1, &w0, &w2, x[13], y[ 4]); - word3_muladd(&w1, &w0, &w2, x[14], y[ 3]); - word3_muladd(&w1, &w0, &w2, x[15], y[ 2]); - z[17] = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[ 3], y[15]); - word3_muladd(&w2, &w1, &w0, x[ 4], y[14]); - word3_muladd(&w2, &w1, &w0, x[ 5], y[13]); - word3_muladd(&w2, &w1, &w0, x[ 6], y[12]); - word3_muladd(&w2, &w1, &w0, x[ 7], y[11]); - word3_muladd(&w2, &w1, &w0, x[ 8], y[10]); - word3_muladd(&w2, &w1, &w0, x[ 9], y[ 9]); - word3_muladd(&w2, &w1, &w0, x[10], y[ 8]); - word3_muladd(&w2, &w1, &w0, x[11], y[ 7]); - word3_muladd(&w2, &w1, &w0, x[12], y[ 6]); - word3_muladd(&w2, &w1, &w0, x[13], y[ 5]); - word3_muladd(&w2, &w1, &w0, x[14], y[ 4]); - word3_muladd(&w2, &w1, &w0, x[15], y[ 3]); - z[18] = w0; w0 = 0; - - word3_muladd(&w0, &w2, &w1, x[ 4], y[15]); - word3_muladd(&w0, &w2, &w1, x[ 5], y[14]); - word3_muladd(&w0, &w2, &w1, x[ 6], y[13]); - word3_muladd(&w0, &w2, &w1, x[ 7], y[12]); - word3_muladd(&w0, &w2, &w1, x[ 8], y[11]); - word3_muladd(&w0, &w2, &w1, x[ 9], y[10]); - word3_muladd(&w0, &w2, &w1, x[10], y[ 9]); - word3_muladd(&w0, &w2, &w1, x[11], y[ 8]); - word3_muladd(&w0, &w2, &w1, x[12], y[ 7]); - word3_muladd(&w0, &w2, &w1, x[13], y[ 6]); - word3_muladd(&w0, &w2, &w1, x[14], y[ 5]); - word3_muladd(&w0, &w2, &w1, x[15], y[ 4]); - z[19] = w1; w1 = 0; - - word3_muladd(&w1, &w0, &w2, x[ 5], y[15]); - word3_muladd(&w1, &w0, &w2, x[ 6], y[14]); - word3_muladd(&w1, &w0, &w2, x[ 7], y[13]); - word3_muladd(&w1, &w0, &w2, x[ 8], y[12]); - word3_muladd(&w1, &w0, &w2, x[ 9], y[11]); - word3_muladd(&w1, &w0, &w2, x[10], y[10]); - word3_muladd(&w1, &w0, &w2, x[11], y[ 9]); - word3_muladd(&w1, &w0, &w2, x[12], y[ 8]); - word3_muladd(&w1, &w0, &w2, x[13], y[ 7]); - word3_muladd(&w1, &w0, &w2, x[14], y[ 6]); - word3_muladd(&w1, &w0, &w2, x[15], y[ 5]); - z[20] = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[ 6], y[15]); - word3_muladd(&w2, &w1, &w0, x[ 7], y[14]); - word3_muladd(&w2, &w1, &w0, x[ 8], y[13]); - word3_muladd(&w2, &w1, &w0, x[ 9], y[12]); - word3_muladd(&w2, &w1, &w0, x[10], y[11]); - word3_muladd(&w2, &w1, &w0, x[11], y[10]); - word3_muladd(&w2, &w1, &w0, x[12], y[ 9]); - word3_muladd(&w2, &w1, &w0, x[13], y[ 8]); - word3_muladd(&w2, &w1, &w0, x[14], y[ 7]); - word3_muladd(&w2, &w1, &w0, x[15], y[ 6]); - z[21] = w0; w0 = 0; - - word3_muladd(&w0, &w2, &w1, x[ 7], y[15]); - word3_muladd(&w0, &w2, &w1, x[ 8], y[14]); - word3_muladd(&w0, &w2, &w1, x[ 9], y[13]); - word3_muladd(&w0, &w2, &w1, x[10], y[12]); - word3_muladd(&w0, &w2, &w1, x[11], y[11]); - word3_muladd(&w0, &w2, &w1, x[12], y[10]); - word3_muladd(&w0, &w2, &w1, x[13], y[ 9]); - word3_muladd(&w0, &w2, &w1, x[14], y[ 8]); - word3_muladd(&w0, &w2, &w1, x[15], y[ 7]); - z[22] = w1; w1 = 0; - - word3_muladd(&w1, &w0, &w2, x[ 8], y[15]); - word3_muladd(&w1, &w0, &w2, x[ 9], y[14]); - word3_muladd(&w1, &w0, &w2, x[10], y[13]); - word3_muladd(&w1, &w0, &w2, x[11], y[12]); - word3_muladd(&w1, &w0, &w2, x[12], y[11]); - word3_muladd(&w1, &w0, &w2, x[13], y[10]); - word3_muladd(&w1, &w0, &w2, x[14], y[ 9]); - word3_muladd(&w1, &w0, &w2, x[15], y[ 8]); - z[23] = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[ 9], y[15]); - word3_muladd(&w2, &w1, &w0, x[10], y[14]); - word3_muladd(&w2, &w1, &w0, x[11], y[13]); - word3_muladd(&w2, &w1, &w0, x[12], y[12]); - word3_muladd(&w2, &w1, &w0, x[13], y[11]); - word3_muladd(&w2, &w1, &w0, x[14], y[10]); - word3_muladd(&w2, &w1, &w0, x[15], y[ 9]); - z[24] = w0; w0 = 0; - - word3_muladd(&w0, &w2, &w1, x[10], y[15]); - word3_muladd(&w0, &w2, &w1, x[11], y[14]); - word3_muladd(&w0, &w2, &w1, x[12], y[13]); - word3_muladd(&w0, &w2, &w1, x[13], y[12]); - word3_muladd(&w0, &w2, &w1, x[14], y[11]); - word3_muladd(&w0, &w2, &w1, x[15], y[10]); - z[25] = w1; w1 = 0; - - word3_muladd(&w1, &w0, &w2, x[11], y[15]); - word3_muladd(&w1, &w0, &w2, x[12], y[14]); - word3_muladd(&w1, &w0, &w2, x[13], y[13]); - word3_muladd(&w1, &w0, &w2, x[14], y[12]); - word3_muladd(&w1, &w0, &w2, x[15], y[11]); - z[26] = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[12], y[15]); - word3_muladd(&w2, &w1, &w0, x[13], y[14]); - word3_muladd(&w2, &w1, &w0, x[14], y[13]); - word3_muladd(&w2, &w1, &w0, x[15], y[12]); - z[27] = w0; w0 = 0; - - word3_muladd(&w0, &w2, &w1, x[13], y[15]); - word3_muladd(&w0, &w2, &w1, x[14], y[14]); - word3_muladd(&w0, &w2, &w1, x[15], y[13]); - z[28] = w1; w1 = 0; - - word3_muladd(&w1, &w0, &w2, x[14], y[15]); - word3_muladd(&w1, &w0, &w2, x[15], y[14]); - z[29] = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[15], y[15]); - z[30] = w0; - z[31] = w1; - } - -} - -} -/* -* Karatsuba Multiplication/Squaring -* (C) 1999-2010 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -namespace { - -/* -* Karatsuba Multiplication Operation -*/ -void karatsuba_mul(word z[], const word x[], const word y[], size_t N, - word workspace[]) - { - if(N < BOTAN_KARAT_MUL_THRESHOLD || N % 2) - { - if(N == 6) - return bigint_comba_mul6(z, x, y); - else if(N == 8) - return bigint_comba_mul8(z, x, y); - else if(N == 16) - return bigint_comba_mul16(z, x, y); - else - return bigint_simple_mul(z, x, N, y, N); - } - - const size_t N2 = N / 2; - - const word* x0 = x; - const word* x1 = x + N2; - const word* y0 = y; - const word* y1 = y + N2; - word* z0 = z; - word* z1 = z + N; - - const s32bit cmp0 = bigint_cmp(x0, N2, x1, N2); - const s32bit cmp1 = bigint_cmp(y1, N2, y0, N2); - - clear_mem(workspace, 2*N); - - if(cmp0 && cmp1) - { - if(cmp0 > 0) - bigint_sub3(z0, x0, N2, x1, N2); - else - bigint_sub3(z0, x1, N2, x0, N2); - - if(cmp1 > 0) - bigint_sub3(z1, y1, N2, y0, N2); - else - bigint_sub3(z1, y0, N2, y1, N2); - - karatsuba_mul(workspace, z0, z1, N2, workspace+N); - } - - karatsuba_mul(z0, x0, y0, N2, workspace+N); - karatsuba_mul(z1, x1, y1, N2, workspace+N); - - const size_t blocks_of_8 = N - (N % 8); - - word ws_carry = 0; - - for(size_t j = 0; j != blocks_of_8; j += 8) - ws_carry = word8_add3(workspace + N + j, z0 + j, z1 + j, ws_carry); - - for(size_t j = blocks_of_8; j != N; ++j) - workspace[N + j] = word_add(z0[j], z1[j], &ws_carry); - - word z_carry = 0; - - for(size_t j = 0; j != blocks_of_8; j += 8) - z_carry = word8_add2(z + N2 + j, workspace + N + j, z_carry); - - for(size_t j = blocks_of_8; j != N; ++j) - z[N2 + j] = word_add(z[N2 + j], workspace[N + j], &z_carry); - - z[N + N2] = word_add(z[N + N2], ws_carry, &z_carry); - - if(z_carry) - for(size_t j = 1; j != N2; ++j) - if(++z[N + N2 + j]) - break; - - if((cmp0 == cmp1) || (cmp0 == 0) || (cmp1 == 0)) - bigint_add2(z + N2, 2*N-N2, workspace, N); - else - bigint_sub2(z + N2, 2*N-N2, workspace, N); - } - -/* -* Karatsuba Squaring Operation -*/ -void karatsuba_sqr(word z[], const word x[], size_t N, word workspace[]) - { - if(N < BOTAN_KARAT_SQR_THRESHOLD || N % 2) - { - if(N == 6) - return bigint_comba_sqr6(z, x); - else if(N == 8) - return bigint_comba_sqr8(z, x); - else if(N == 16) - return bigint_comba_sqr16(z, x); - else - return bigint_simple_sqr(z, x, N); - } - - const size_t N2 = N / 2; - - const word* x0 = x; - const word* x1 = x + N2; - word* z0 = z; - word* z1 = z + N; - - const s32bit cmp = bigint_cmp(x0, N2, x1, N2); - - clear_mem(workspace, 2*N); - - if(cmp) - { - if(cmp > 0) - bigint_sub3(z0, x0, N2, x1, N2); - else - bigint_sub3(z0, x1, N2, x0, N2); - - karatsuba_sqr(workspace, z0, N2, workspace+N); - } - - karatsuba_sqr(z0, x0, N2, workspace+N); - karatsuba_sqr(z1, x1, N2, workspace+N); - - const size_t blocks_of_8 = N - (N % 8); - - word ws_carry = 0; - - for(size_t j = 0; j != blocks_of_8; j += 8) - ws_carry = word8_add3(workspace + N + j, z0 + j, z1 + j, ws_carry); - - for(size_t j = blocks_of_8; j != N; ++j) - workspace[N + j] = word_add(z0[j], z1[j], &ws_carry); - - word z_carry = 0; - - for(size_t j = 0; j != blocks_of_8; j += 8) - z_carry = word8_add2(z + N2 + j, workspace + N + j, z_carry); - - for(size_t j = blocks_of_8; j != N; ++j) - z[N2 + j] = word_add(z[N2 + j], workspace[N + j], &z_carry); - - z[N + N2] = word_add(z[N + N2], ws_carry, &z_carry); - - if(z_carry) - for(size_t j = 1; j != N2; ++j) - if(++z[N + N2 + j]) - break; - - /* - * This is only actually required if cmp is != 0, however - * if cmp==0 then workspace[0:N] == 0 and avoiding the jump - * hides a timing channel. - */ - bigint_sub2(z + N2, 2*N-N2, workspace, N); - } - -/* -* Pick a good size for the Karatsuba multiply -*/ -size_t karatsuba_size(size_t z_size, - size_t x_size, size_t x_sw, - size_t y_size, size_t y_sw) - { - if(x_sw > x_size || x_sw > y_size || y_sw > x_size || y_sw > y_size) - return 0; - - if(((x_size == x_sw) && (x_size % 2)) || - ((y_size == y_sw) && (y_size % 2))) - return 0; - - const size_t start = (x_sw > y_sw) ? x_sw : y_sw; - const size_t end = (x_size < y_size) ? x_size : y_size; - - if(start == end) - { - if(start % 2) - return 0; - return start; - } - - for(size_t j = start; j <= end; ++j) - { - if(j % 2) - continue; - - if(2*j > z_size) - return 0; - - if(x_sw <= j && j <= x_size && y_sw <= j && j <= y_size) - { - if(j % 4 == 2 && - (j+2) <= x_size && (j+2) <= y_size && 2*(j+2) <= z_size) - return j+2; - return j; - } - } - - return 0; - } - -/* -* Pick a good size for the Karatsuba squaring -*/ -size_t karatsuba_size(size_t z_size, size_t x_size, size_t x_sw) - { - if(x_sw == x_size) - { - if(x_sw % 2) - return 0; - return x_sw; - } - - for(size_t j = x_sw; j <= x_size; ++j) - { - if(j % 2) - continue; - - if(2*j > z_size) - return 0; - - if(j % 4 == 2 && (j+2) <= x_size && 2*(j+2) <= z_size) - return j+2; - return j; - } - - return 0; - } - -} - -/* -* Multiplication Algorithm Dispatcher -*/ -void bigint_mul(word z[], size_t z_size, word workspace[], - const word x[], size_t x_size, size_t x_sw, - const word y[], size_t y_size, size_t y_sw) - { - if(x_sw == 1) - { - bigint_linmul3(z, y, y_sw, x[0]); - } - else if(y_sw == 1) - { - bigint_linmul3(z, x, x_sw, y[0]); - } - else if(x_sw <= 4 && x_size >= 4 && - y_sw <= 4 && y_size >= 4 && z_size >= 8) - { - bigint_comba_mul4(z, x, y); - } - else if(x_sw <= 6 && x_size >= 6 && - y_sw <= 6 && y_size >= 6 && z_size >= 12) - { - bigint_comba_mul6(z, x, y); - } - else if(x_sw <= 8 && x_size >= 8 && - y_sw <= 8 && y_size >= 8 && z_size >= 16) - { - bigint_comba_mul8(z, x, y); - } - else if(x_sw <= 16 && x_size >= 16 && - y_sw <= 16 && y_size >= 16 && z_size >= 32) - { - bigint_comba_mul16(z, x, y); - } - else if(x_sw < BOTAN_KARAT_MUL_THRESHOLD || - y_sw < BOTAN_KARAT_MUL_THRESHOLD || - !workspace) - { - bigint_simple_mul(z, x, x_sw, y, y_sw); - } - else - { - const size_t N = karatsuba_size(z_size, x_size, x_sw, y_size, y_sw); - - if(N) - { - clear_mem(workspace, 2*N); - karatsuba_mul(z, x, y, N, workspace); - } - else - bigint_simple_mul(z, x, x_sw, y, y_sw); - } - } - -/* -* Squaring Algorithm Dispatcher -*/ -void bigint_sqr(word z[], size_t z_size, word workspace[], - const word x[], size_t x_size, size_t x_sw) - { - if(x_sw == 1) - { - bigint_linmul3(z, x, x_sw, x[0]); - } - else if(x_sw <= 4 && x_size >= 4 && z_size >= 8) - { - bigint_comba_sqr4(z, x); - } - else if(x_sw <= 6 && x_size >= 6 && z_size >= 12) - { - bigint_comba_sqr6(z, x); - } - else if(x_sw <= 8 && x_size >= 8 && z_size >= 16) - { - bigint_comba_sqr8(z, x); - } - else if(x_sw <= 16 && x_size >= 16 && z_size >= 32) - { - bigint_comba_sqr16(z, x); - } - else if(x_size < BOTAN_KARAT_SQR_THRESHOLD || !workspace) - { - bigint_simple_sqr(z, x, x_sw); - } - else - { - const size_t N = karatsuba_size(z_size, x_size, x_sw); - - if(N) - { - clear_mem(workspace, 2*N); - karatsuba_sqr(z, x, N, workspace); - } - else - bigint_simple_sqr(z, x, x_sw); - } - } - -} -/* -* MP Misc Functions -* (C) 1999-2008 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -extern "C" { - -/* -* Core Division Operation -*/ -size_t bigint_divcore(word q, word y2, word y1, - word x3, word x2, word x1) - { - // Compute (y2,y1) * q - - word y3 = 0; - y1 = word_madd2(q, y1, &y3); - y2 = word_madd2(q, y2, &y3); - - // Return (y3,y2,y1) >? (x3,x2,x1) - - if(y3 > x3) return 1; - if(y3 < x3) return 0; - if(y2 > x2) return 1; - if(y2 < x2) return 0; - if(y1 > x1) return 1; - if(y1 < x1) return 0; - return 0; - } - -/* -* Compare two MP integers -*/ -s32bit bigint_cmp(const word x[], size_t x_size, - const word y[], size_t y_size) - { - if(x_size < y_size) { return (-bigint_cmp(y, y_size, x, x_size)); } - - while(x_size > y_size) - { - if(x[x_size-1]) - return 1; - x_size--; - } - - for(size_t j = x_size; j > 0; --j) - { - if(x[j-1] > y[j-1]) - return 1; - if(x[j-1] < y[j-1]) - return -1; - } - - return 0; - } - -/* -* Do a 2-word/1-word Division -*/ -word bigint_divop(word n1, word n0, word d) - { - word high = n1 % d, quotient = 0; - - for(size_t j = 0; j != MP_WORD_BITS; ++j) - { - word high_top_bit = (high & MP_WORD_TOP_BIT); - - high <<= 1; - high |= (n0 >> (MP_WORD_BITS-1-j)) & 1; - quotient <<= 1; - - if(high_top_bit || high >= d) - { - high -= d; - quotient |= 1; - } - } - - return quotient; - } - -/* -* Do a 2-word/1-word Modulo -*/ -word bigint_modop(word n1, word n0, word d) - { - word z = bigint_divop(n1, n0, d); - word dummy = 0; - z = word_madd2(z, d, &dummy); - return (n0-z); - } - -} - -} -/* -* Montgomery Reduction -* (C) 1999-2011 Jack Lloyd -* 2006 Luca Piccarreta -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -extern "C" { - -/* -* Montgomery Reduction Algorithm -*/ -void bigint_monty_redc(word z[], size_t z_size, - const word p[], size_t p_size, - word p_dash, word ws[]) - { - const size_t blocks_of_8 = p_size - (p_size % 8); - - for(size_t i = 0; i != p_size; ++i) - { - word* z_i = z + i; - - const word y = z_i[0] * p_dash; - - /* - bigint_linmul3(ws, p, p_size, y); - bigint_add2(z_i, z_size - i, ws, p_size+1); - */ - - word carry = 0; - - for(size_t j = 0; j != blocks_of_8; j += 8) - carry = word8_madd3(z_i + j, p + j, y, carry); - - for(size_t j = blocks_of_8; j != p_size; ++j) - z_i[j] = word_madd3(p[j], y, z_i[j], &carry); - - word z_sum = z_i[p_size] + carry; - carry = (z_sum < z_i[p_size]); - z_i[p_size] = z_sum; - - for(size_t j = p_size + 1; carry && j != z_size - i; ++j) - { - ++z_i[j]; - carry = !z_i[j]; - } - } - - word borrow = 0; - for(size_t i = 0; i != p_size; ++i) - ws[i] = word_sub(z[p_size + i], p[i], &borrow); - - ws[p_size] = word_sub(z[p_size+p_size], 0, &borrow); - - copy_mem(ws + p_size + 1, z + p_size, p_size + 1); - - copy_mem(z, ws + borrow*(p_size+1), p_size + 1); - clear_mem(z + p_size + 1, z_size - p_size - 1); - } - -void bigint_monty_mul(word z[], size_t z_size, - const word x[], size_t x_size, size_t x_sw, - const word y[], size_t y_size, size_t y_sw, - const word p[], size_t p_size, word p_dash, - word ws[]) - { - bigint_mul(&z[0], z_size, &ws[0], - &x[0], x_size, x_sw, - &y[0], y_size, y_sw); - - bigint_monty_redc(&z[0], z_size, - &p[0], p_size, p_dash, - &ws[0]); - } - -void bigint_monty_sqr(word z[], size_t z_size, - const word x[], size_t x_size, size_t x_sw, - const word p[], size_t p_size, word p_dash, - word ws[]) - { - bigint_sqr(&z[0], z_size, &ws[0], - &x[0], x_size, x_sw); - - bigint_monty_redc(&z[0], z_size, - &p[0], p_size, p_dash, - &ws[0]); - } - -} - -} -/* -* Simple O(N^2) Multiplication and Squaring -* (C) 1999-2008 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -extern "C" { - -/* -* Simple O(N^2) Multiplication -*/ -void bigint_simple_mul(word z[], const word x[], size_t x_size, - const word y[], size_t y_size) - { - const size_t x_size_8 = x_size - (x_size % 8); - - clear_mem(z, x_size + y_size); - - for(size_t i = 0; i != y_size; ++i) - { - const word y_i = y[i]; - - word carry = 0; - - for(size_t j = 0; j != x_size_8; j += 8) - carry = word8_madd3(z + i + j, x + j, y_i, carry); - - for(size_t j = x_size_8; j != x_size; ++j) - z[i+j] = word_madd3(x[j], y_i, z[i+j], &carry); - - z[x_size+i] = carry; - } - } - -/* -* Simple O(N^2) Squaring -* -* This is exactly the same algorithm as bigint_simple_mul, however -* because C/C++ compilers suck at alias analysis it is good to have -* the version where the compiler knows that x == y -* -* There is an O(n^1.5) squaring algorithm specified in Handbook of -* Applied Cryptography, chapter 14 -* -*/ -void bigint_simple_sqr(word z[], const word x[], size_t x_size) - { - const size_t x_size_8 = x_size - (x_size % 8); - - clear_mem(z, 2*x_size); - - for(size_t i = 0; i != x_size; ++i) - { - const word x_i = x[i]; - word carry = 0; - - for(size_t j = 0; j != x_size_8; j += 8) - carry = word8_madd3(z + i + j, x + j, x_i, carry); - - for(size_t j = x_size_8; j != x_size; ++j) - z[i+j] = word_madd3(x[j], x_i, z[i+j], &carry); - - z[x_size+i] = carry; - } - } - -} - -} -/* -* MP Shift Algorithms -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -extern "C" { - -/* -* Single Operand Left Shift -*/ -void bigint_shl1(word x[], size_t x_size, size_t word_shift, size_t bit_shift) - { - if(word_shift) - { - for(size_t j = 1; j != x_size + 1; ++j) - x[(x_size - j) + word_shift] = x[x_size - j]; - clear_mem(x, word_shift); - } - - if(bit_shift) - { - word carry = 0; - for(size_t j = word_shift; j != x_size + word_shift + 1; ++j) - { - word temp = x[j]; - x[j] = (temp << bit_shift) | carry; - carry = (temp >> (MP_WORD_BITS - bit_shift)); - } - } - } - -/* -* Single Operand Right Shift -*/ -void bigint_shr1(word x[], size_t x_size, size_t word_shift, size_t bit_shift) - { - if(x_size < word_shift) - { - clear_mem(x, x_size); - return; - } - - if(word_shift) - { - copy_mem(x, x + word_shift, x_size - word_shift); - clear_mem(x + x_size - word_shift, word_shift); - } - - if(bit_shift) - { - word carry = 0; - - size_t top = x_size - word_shift; - - while(top >= 4) - { - word w = x[top-1]; - x[top-1] = (w >> bit_shift) | carry; - carry = (w << (MP_WORD_BITS - bit_shift)); - - w = x[top-2]; - x[top-2] = (w >> bit_shift) | carry; - carry = (w << (MP_WORD_BITS - bit_shift)); - - w = x[top-3]; - x[top-3] = (w >> bit_shift) | carry; - carry = (w << (MP_WORD_BITS - bit_shift)); - - w = x[top-4]; - x[top-4] = (w >> bit_shift) | carry; - carry = (w << (MP_WORD_BITS - bit_shift)); - - top -= 4; - } - - while(top) - { - word w = x[top-1]; - x[top-1] = (w >> bit_shift) | carry; - carry = (w << (MP_WORD_BITS - bit_shift)); - - top--; - } - } - } - -/* -* Two Operand Left Shift -*/ -void bigint_shl2(word y[], const word x[], size_t x_size, - size_t word_shift, size_t bit_shift) - { - for(size_t j = 0; j != x_size; ++j) - y[j + word_shift] = x[j]; - if(bit_shift) - { - word carry = 0; - for(size_t j = word_shift; j != x_size + word_shift + 1; ++j) - { - word w = y[j]; - y[j] = (w << bit_shift) | carry; - carry = (w >> (MP_WORD_BITS - bit_shift)); - } - } - } - -/* -* Two Operand Right Shift -*/ -void bigint_shr2(word y[], const word x[], size_t x_size, - size_t word_shift, size_t bit_shift) - { - if(x_size < word_shift) return; - - for(size_t j = 0; j != x_size - word_shift; ++j) - y[j] = x[j + word_shift]; - if(bit_shift) - { - word carry = 0; - for(size_t j = x_size - word_shift; j > 0; --j) - { - word w = y[j-1]; - y[j-1] = (w >> bit_shift) | carry; - carry = (w << (MP_WORD_BITS - bit_shift)); - } - } - } - -} - -} -/* -* DSA Parameter Generation -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include -#include - -namespace Botan { - -namespace { - -/* -* Check if this size is allowed by FIPS 186-3 -*/ -bool fips186_3_valid_size(size_t pbits, size_t qbits) - { - if(qbits == 160) - return (pbits == 512 || pbits == 768 || pbits == 1024); - - if(qbits == 224) - return (pbits == 2048); - - if(qbits == 256) - return (pbits == 2048 || pbits == 3072); - - return false; - } - -} - -/* -* Attempt DSA prime generation with given seed -*/ -bool generate_dsa_primes(RandomNumberGenerator& rng, - Algorithm_Factory& af, - BigInt& p, BigInt& q, - size_t pbits, size_t qbits, - const MemoryRegion& seed_c) - { - if(!fips186_3_valid_size(pbits, qbits)) - throw Invalid_Argument( - "FIPS 186-3 does not allow DSA domain parameters of " + - to_string(pbits) + "/" + to_string(qbits) + " bits long"); - - if(seed_c.size() * 8 < qbits) - throw Invalid_Argument( - "Generating a DSA parameter set with a " + to_string(qbits) + - "long q requires a seed at least as many bits long"); - - std::unique_ptr hash( - af.make_hash_function("SHA-" + to_string(qbits))); - - const size_t HASH_SIZE = hash->output_length(); - - class Seed - { - public: - Seed(const MemoryRegion& s) : seed(s) {} - - operator MemoryRegion& () { return seed; } - - Seed& operator++() - { - for(size_t j = seed.size(); j > 0; --j) - if(++seed[j-1]) - break; - return (*this); - } - private: - SecureVector seed; - }; - - Seed seed(seed_c); - - q.binary_decode(hash->process(seed)); - q.set_bit(qbits-1); - q.set_bit(0); - - if(!check_prime(q, rng)) - return false; - - const size_t n = (pbits-1) / (HASH_SIZE * 8), - b = (pbits-1) % (HASH_SIZE * 8); - - BigInt X; - SecureVector V(HASH_SIZE * (n+1)); - - for(size_t j = 0; j != 4096; ++j) - { - for(size_t k = 0; k <= n; ++k) - { - ++seed; - hash->update(seed); - hash->final(&V[HASH_SIZE * (n-k)]); - } - - X.binary_decode(&V[HASH_SIZE - 1 - b/8], - V.size() - (HASH_SIZE - 1 - b/8)); - X.set_bit(pbits-1); - - p = X - (X % (2*q) - 1); - - if(p.bits() == pbits && check_prime(p, rng)) - return true; - } - return false; - } - -/* -* Generate DSA Primes -*/ -SecureVector generate_dsa_primes(RandomNumberGenerator& rng, - Algorithm_Factory& af, - BigInt& p, BigInt& q, - size_t pbits, size_t qbits) - { - while(true) - { - SecureVector seed = rng.random_vec(qbits / 8); - - if(generate_dsa_primes(rng, af, p, q, pbits, qbits, seed)) - return seed; - } - } - -} -/* -* Jacobi Function -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -/* -* Calculate the Jacobi symbol -*/ -s32bit 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; - s32bit J = 1; - - while(y > 1) - { - x %= y; - if(x > y / 2) - { - x = y - x; - if(y % 4 == 3) - J = -J; - } - if(x.is_zero()) - return 0; - - size_t shifts = low_zero_bits(x); - x >>= shifts; - if(shifts % 2) - { - word y_mod_8 = y % 8; - if(y_mod_8 == 3 || y_mod_8 == 5) - J = -J; - } - - if(x % 4 == 3 && y % 4 == 3) - J = -J; - std::swap(x, y); - } - return J; - } - -} -/* -* Prime Generation -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include - -namespace Botan { - -/* -* Generate a random prime -*/ -BigInt random_prime(RandomNumberGenerator& rng, - size_t bits, const BigInt& coprime, - size_t equiv, size_t modulo) - { - if(bits <= 1) - throw Invalid_Argument("random_prime: Can't make a prime of " + - to_string(bits) + " bits"); - else if(bits == 2) - return ((rng.next_byte() % 2) ? 2 : 3); - else if(bits == 3) - return ((rng.next_byte() % 2) ? 5 : 7); - else if(bits == 4) - return ((rng.next_byte() % 2) ? 11 : 13); - - if(coprime <= 0) - throw Invalid_Argument("random_prime: coprime must be > 0"); - if(modulo % 2 == 1 || modulo == 0) - throw Invalid_Argument("random_prime: Invalid modulo value"); - if(equiv >= modulo || equiv % 2 == 0) - throw Invalid_Argument("random_prime: equiv must be < modulo, and odd"); - - while(true) - { - BigInt p(rng, bits); - - // Force lowest and two top bits on - p.set_bit(bits - 1); - p.set_bit(bits - 2); - p.set_bit(0); - - if(p % modulo != equiv) - p += (modulo - p % modulo) + equiv; - - const size_t sieve_size = std::min(bits / 2, PRIME_TABLE_SIZE); - SecureVector sieve(sieve_size); - - for(size_t j = 0; j != sieve.size(); ++j) - sieve[j] = p % PRIMES[j]; - - size_t counter = 0; - while(true) - { - if(counter == 4096 || p.bits() > bits) - break; - - bool passes_sieve = true; - ++counter; - p += modulo; - - if(p.bits() > bits) - break; - - for(size_t j = 0; j != sieve.size(); ++j) - { - sieve[j] = (sieve[j] + modulo) % PRIMES[j]; - if(sieve[j] == 0) - passes_sieve = false; - } - - if(!passes_sieve || gcd(p - 1, coprime) != 1) - continue; - if(check_prime(p, rng)) - return p; - } - } - } - -/* -* Generate a random safe prime -*/ -BigInt random_safe_prime(RandomNumberGenerator& rng, size_t bits) - { - if(bits <= 64) - throw Invalid_Argument("random_safe_prime: Can't make a prime of " + - to_string(bits) + " bits"); - - BigInt p; - do - p = (random_prime(rng, bits - 1) << 1) + 1; - while(!check_prime(p, rng)); - return p; - } - -} -/* -* Fused and Important MP Algorithms -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include - -namespace Botan { - -/* -* Square a BigInt -*/ -BigInt square(const BigInt& x) - { - const size_t x_sw = x.sig_words(); - - BigInt z(BigInt::Positive, round_up(2*x_sw, 16)); - SecureVector workspace(z.size()); - - bigint_sqr(z.get_reg(), z.size(), workspace, - x.data(), x.size(), x_sw); - return z; - } - -/* -* Multiply-Add Operation -*/ -BigInt mul_add(const BigInt& a, const BigInt& b, const BigInt& c) - { - if(c.is_negative() || c.is_zero()) - throw Invalid_Argument("mul_add: Third argument must be > 0"); - - BigInt::Sign sign = BigInt::Positive; - if(a.sign() != b.sign()) - sign = BigInt::Negative; - - const size_t a_sw = a.sig_words(); - const size_t b_sw = b.sig_words(); - const size_t c_sw = c.sig_words(); - - BigInt r(sign, std::max(a.size() + b.size(), c_sw) + 1); - SecureVector workspace(r.size()); - - bigint_mul(r.get_reg(), r.size(), workspace, - a.data(), a.size(), a_sw, - b.data(), b.size(), b_sw); - const size_t r_size = std::max(r.sig_words(), c_sw); - bigint_add2(r.get_reg(), r_size, c.data(), c_sw); - return r; - } - -/* -* Subtract-Multiply Operation -*/ -BigInt sub_mul(const BigInt& a, const BigInt& b, const BigInt& c) - { - if(a.is_negative() || b.is_negative()) - throw Invalid_Argument("sub_mul: First two arguments must be >= 0"); - - BigInt r = a; - r -= b; - r *= c; - return r; - } - -} -/* -* Number Theory Functions -* (C) 1999-2011 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include - -namespace Botan { - -namespace { - -/* -* Miller-Rabin Primality Tester -*/ -class MillerRabin_Test - { - public: - bool is_witness(const BigInt& nonce); - MillerRabin_Test(const BigInt& num); - private: - BigInt n, r, n_minus_1; - size_t s; - Fixed_Exponent_Power_Mod pow_mod; - Modular_Reducer reducer; - }; - -/* -* Miller-Rabin Test, as described in Handbook of Applied Cryptography -* section 4.24 -*/ -bool MillerRabin_Test::is_witness(const BigInt& a) - { - if(a < 2 || a >= n_minus_1) - throw Invalid_Argument("Bad size for nonce in Miller-Rabin test"); - - BigInt y = pow_mod(a); - if(y == 1 || y == n_minus_1) - return false; - - for(size_t i = 1; i != s; ++i) - { - y = reducer.square(y); - - if(y == 1) // found a non-trivial square root - return true; - - if(y == n_minus_1) // -1, trivial square root, so give up - return false; - } - - if(y != n_minus_1) // fails Fermat test - return true; - - return false; - } - -/* -* Miller-Rabin Constructor -*/ -MillerRabin_Test::MillerRabin_Test(const BigInt& num) - { - if(num.is_even() || num < 3) - throw Invalid_Argument("MillerRabin_Test: Invalid number for testing"); - - n = num; - n_minus_1 = n - 1; - s = low_zero_bits(n_minus_1); - r = n_minus_1 >> s; - - pow_mod = Fixed_Exponent_Power_Mod(r, n); - reducer = Modular_Reducer(n); - } - -/* -* Miller-Rabin Iterations -*/ -size_t miller_rabin_test_iterations(size_t bits, size_t level) - { - struct mapping { size_t bits; size_t verify_iter; size_t check_iter; }; - - static const mapping tests[] = { - { 50, 55, 25 }, - { 100, 38, 22 }, - { 160, 32, 18 }, - { 163, 31, 17 }, - { 168, 30, 16 }, - { 177, 29, 16 }, - { 181, 28, 15 }, - { 185, 27, 15 }, - { 190, 26, 15 }, - { 195, 25, 14 }, - { 201, 24, 14 }, - { 208, 23, 14 }, - { 215, 22, 13 }, - { 222, 21, 13 }, - { 231, 20, 13 }, - { 241, 19, 12 }, - { 252, 18, 12 }, - { 264, 17, 12 }, - { 278, 16, 11 }, - { 294, 15, 10 }, - { 313, 14, 9 }, - { 334, 13, 8 }, - { 360, 12, 8 }, - { 392, 11, 7 }, - { 430, 10, 7 }, - { 479, 9, 6 }, - { 542, 8, 6 }, - { 626, 7, 5 }, - { 746, 6, 4 }, - { 926, 5, 3 }, - { 1232, 4, 2 }, - { 1853, 3, 2 }, - { 0, 0, 0 } - }; - - for(size_t i = 0; tests[i].bits; ++i) - { - if(bits <= tests[i].bits) - { - if(level >= 2) - return tests[i].verify_iter; - else if(level == 1) - return tests[i].check_iter; - else if(level == 0) - return std::max(tests[i].check_iter / 4, 1); - } - } - - return level > 0 ? 2 : 1; // for large inputs - } - -} - -/* -* Return the number of 0 bits at the end of n -*/ -size_t low_zero_bits(const BigInt& n) - { - size_t low_zero = 0; - - if(n.is_positive() && n.is_nonzero()) - { - for(size_t i = 0; i != n.size(); ++i) - { - word x = n[i]; - - if(x) - { - low_zero += ctz(x); - break; - } - else - low_zero += BOTAN_MP_WORD_BITS; - } - } - - return low_zero; - } - -/* -* Calculate the GCD -*/ -BigInt gcd(const BigInt& a, const BigInt& b) - { - if(a.is_zero() || b.is_zero()) return 0; - if(a == 1 || b == 1) return 1; - - BigInt x = a, y = b; - x.set_sign(BigInt::Positive); - y.set_sign(BigInt::Positive); - size_t shift = std::min(low_zero_bits(x), low_zero_bits(y)); - - x >>= shift; - y >>= shift; - - while(x.is_nonzero()) - { - x >>= low_zero_bits(x); - y >>= low_zero_bits(y); - if(x >= y) { x -= y; x >>= 1; } - else { y -= x; y >>= 1; } - } - - return (y << shift); - } - -/* -* Calculate the LCM -*/ -BigInt lcm(const BigInt& a, const BigInt& b) - { - return ((a * b) / gcd(a, b)); - } - -/* -* Find the Modular Inverse -*/ -BigInt inverse_mod(const BigInt& n, const BigInt& mod) - { - if(mod.is_zero()) - throw BigInt::DivideByZero(); - if(mod.is_negative() || n.is_negative()) - throw Invalid_Argument("inverse_mod: arguments must be non-negative"); - - if(n.is_zero() || (n.is_even() && mod.is_even())) - return 0; - - BigInt x = mod, y = n, u = mod, v = n; - BigInt A = 1, B = 0, C = 0, D = 1; - - while(u.is_nonzero()) - { - size_t zero_bits = low_zero_bits(u); - u >>= zero_bits; - for(size_t i = 0; i != zero_bits; ++i) - { - if(A.is_odd() || B.is_odd()) - { A += y; B -= x; } - A >>= 1; B >>= 1; - } - - zero_bits = low_zero_bits(v); - v >>= zero_bits; - for(size_t i = 0; i != zero_bits; ++i) - { - if(C.is_odd() || D.is_odd()) - { C += y; D -= x; } - C >>= 1; D >>= 1; - } - - if(u >= v) { u -= v; A -= C; B -= D; } - else { v -= u; C -= A; D -= B; } - } - - if(v != 1) - return 0; - - while(D.is_negative()) D += mod; - while(D >= mod) D -= mod; - - return D; - } - -/* -* Modular Exponentiation -*/ -BigInt power_mod(const BigInt& base, const BigInt& exp, const BigInt& mod) - { - Power_Mod pow_mod(mod); - pow_mod.set_base(base); - pow_mod.set_exponent(exp); - return pow_mod.execute(); - } - -/* -* Test for primaility using Miller-Rabin -*/ -bool primality_test(const BigInt& n, - RandomNumberGenerator& rng, - size_t level) - { - const size_t PREF_NONCE_BITS = 64; - - if(n == 2) - return true; - if(n <= 1 || n.is_even()) - return false; - - // Fast path testing for small numbers (<= 65521) - if(n <= PRIMES[PRIME_TABLE_SIZE-1]) - { - const word num = n.word_at(0); - - for(size_t i = 0; PRIMES[i]; ++i) - { - if(num == PRIMES[i]) - return true; - if(num < PRIMES[i]) - return false; - } - - return false; - } - - if(level > 2) - level = 2; - - const size_t NONCE_BITS = std::min(n.bits() - 2, PREF_NONCE_BITS); - - MillerRabin_Test mr(n); - - const size_t tests = miller_rabin_test_iterations(n.bits(), level); - - BigInt nonce; - for(size_t i = 0; i != tests; ++i) - { - while(nonce < 2 || nonce >= (n-1)) - nonce.randomize(rng, NONCE_BITS); - - if(mr.is_witness(nonce)) - return false; - } - return true; - } - -} -/* -* Modular Exponentiation Proxy -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -/* -* Power_Mod Constructor -*/ -Power_Mod::Power_Mod(const BigInt& n, Usage_Hints hints) - { - core = 0; - set_modulus(n, hints); - hints = NO_HINTS; - } - -/* -* Power_Mod Copy Constructor -*/ -Power_Mod::Power_Mod(const Power_Mod& other) - { - Q_UNUSED(hints); - core = 0; - hints = other.hints; - if(other.core) - core = other.core->copy(); - } - -/* -* Power_Mod Assignment Operator -*/ -Power_Mod& Power_Mod::operator=(const Power_Mod& other) - { - delete core; - core = 0; - if(other.core) - core = other.core->copy(); - return (*this); - } - -/* -* Power_Mod Destructor -*/ -Power_Mod::~Power_Mod() - { - delete core; - } - -/* -* Set the modulus -*/ -void Power_Mod::set_modulus(const BigInt& n, Usage_Hints hints) const - { - delete core; - core = 0; - - if(n != 0) - { - Algorithm_Factory::Engine_Iterator i(global_state().algorithm_factory()); - - while(const Engine* engine = i.next()) - { - core = engine->mod_exp(n, hints); - - if(core) - break; - } - - if(!core) - throw Lookup_Error("Power_Mod: Unable to find a working engine"); - } - } - -/* -* Set the base -*/ -void Power_Mod::set_base(const BigInt& b) const - { - if(b.is_zero() || b.is_negative()) - throw Invalid_Argument("Power_Mod::set_base: arg must be > 0"); - - if(!core) - throw Internal_Error("Power_Mod::set_base: core was NULL"); - core->set_base(b); - } - -/* -* Set the exponent -*/ -void Power_Mod::set_exponent(const BigInt& e) const - { - if(e.is_negative()) - throw Invalid_Argument("Power_Mod::set_exponent: arg must be > 0"); - - if(!core) - throw Internal_Error("Power_Mod::set_exponent: core was NULL"); - core->set_exponent(e); - } - -/* -* Compute the result -*/ -BigInt Power_Mod::execute() const - { - if(!core) - throw Internal_Error("Power_Mod::execute: core was NULL"); - return core->execute(); - } - -/* -* Try to choose a good window size -*/ -size_t Power_Mod::window_bits(size_t exp_bits, size_t, - Power_Mod::Usage_Hints hints) - { - static const size_t wsize[][2] = { - { 1434, 7 }, - { 539, 6 }, - { 197, 4 }, - { 70, 3 }, - { 25, 2 }, - { 0, 0 } - }; - - size_t window_bits = 1; - - if(exp_bits) - { - for(size_t j = 0; wsize[j][0]; ++j) - { - if(exp_bits >= wsize[j][0]) - { - window_bits += wsize[j][1]; - break; - } - } - } - - if(hints & Power_Mod::BASE_IS_FIXED) - window_bits += 2; - if(hints & Power_Mod::EXP_IS_LARGE) - ++window_bits; - - return window_bits; - } - -namespace { - -/* -* Choose potentially useful hints -*/ -Power_Mod::Usage_Hints choose_base_hints(const BigInt& b, const BigInt& n) - { - if(b == 2) - return Power_Mod::Usage_Hints(Power_Mod::BASE_IS_2 | - Power_Mod::BASE_IS_SMALL); - - const size_t b_bits = b.bits(); - const size_t n_bits = n.bits(); - - if(b_bits < n_bits / 32) - return Power_Mod::BASE_IS_SMALL; - if(b_bits > n_bits / 4) - return Power_Mod::BASE_IS_LARGE; - - return Power_Mod::NO_HINTS; - } - -/* -* Choose potentially useful hints -*/ -Power_Mod::Usage_Hints choose_exp_hints(const BigInt& e, const BigInt& n) - { - const size_t e_bits = e.bits(); - const size_t n_bits = n.bits(); - - if(e_bits < n_bits / 32) - return Power_Mod::BASE_IS_SMALL; - if(e_bits > n_bits / 4) - return Power_Mod::BASE_IS_LARGE; - return Power_Mod::NO_HINTS; - } - -} - -/* -* Fixed_Exponent_Power_Mod Constructor -*/ -Fixed_Exponent_Power_Mod::Fixed_Exponent_Power_Mod(const BigInt& e, - const BigInt& n, - Usage_Hints hints) : - Power_Mod(n, Usage_Hints(hints | EXP_IS_FIXED | choose_exp_hints(e, n))) - { - set_exponent(e); - } - -/* -* Fixed_Base_Power_Mod Constructor -*/ -Fixed_Base_Power_Mod::Fixed_Base_Power_Mod(const BigInt& b, const BigInt& n, - Usage_Hints hints) : - Power_Mod(n, Usage_Hints(hints | BASE_IS_FIXED | choose_base_hints(b, n))) - { - set_base(b); - } - -} -/* -* Fixed Window Exponentiation -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include - -namespace Botan { - -/* -* Set the exponent -*/ -void Fixed_Window_Exponentiator::set_exponent(const BigInt& e) - { - exp = e; - } - -/* -* Set the base -*/ -void Fixed_Window_Exponentiator::set_base(const BigInt& base) - { - window_bits = Power_Mod::window_bits(exp.bits(), base.bits(), hints); - - g.resize((1 << window_bits) - 1); - g[0] = base; - for(size_t j = 1; j != g.size(); ++j) - g[j] = reducer.multiply(g[j-1], g[0]); - } - -/* -* Compute the result -*/ -BigInt Fixed_Window_Exponentiator::execute() const - { - const size_t exp_nibbles = (exp.bits() + window_bits - 1) / window_bits; - - BigInt x = 1; - for(size_t j = exp_nibbles; j > 0; --j) - { - for(size_t k = 0; k != window_bits; ++k) - x = reducer.square(x); - - if(u32bit nibble = exp.get_substring(window_bits*(j-1), window_bits)) - x = reducer.multiply(x, g[nibble-1]); - } - return x; - } - -/* -* Fixed_Window_Exponentiator Constructor -*/ -Fixed_Window_Exponentiator::Fixed_Window_Exponentiator(const BigInt& n, - Power_Mod::Usage_Hints hints) - { - reducer = Modular_Reducer(n); - this->hints = hints; - window_bits = 0; - } - -} -/* -* Montgomery Exponentiation -* (C) 1999-2010 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -/* -* Set the exponent -*/ -void Montgomery_Exponentiator::set_exponent(const BigInt& exp) - { - this->exp = exp; - exp_bits = exp.bits(); - } - -/* -* Set the base -*/ -void Montgomery_Exponentiator::set_base(const BigInt& base) - { - window_bits = Power_Mod::window_bits(exp.bits(), base.bits(), hints); - - g.resize((1 << window_bits) - 1); - - SecureVector z(2 * (mod_words + 1)); - SecureVector workspace(z.size()); - - g[0] = (base >= modulus) ? (base % modulus) : base; - - bigint_monty_mul(&z[0], z.size(), - g[0].data(), g[0].size(), g[0].sig_words(), - R2.data(), R2.size(), R2.sig_words(), - modulus.data(), mod_words, mod_prime, - &workspace[0]); - - g[0].assign(&z[0], mod_words + 1); - - const BigInt& x = g[0]; - const size_t x_sig = x.sig_words(); - - for(size_t i = 1; i != g.size(); ++i) - { - const BigInt& y = g[i-1]; - const size_t y_sig = y.sig_words(); - - zeroise(z); - bigint_monty_mul(&z[0], z.size(), - x.data(), x.size(), x_sig, - y.data(), y.size(), y_sig, - modulus.data(), mod_words, mod_prime, - &workspace[0]); - - g[i].assign(&z[0], mod_words + 1); - } - } - -/* -* Compute the result -*/ -BigInt Montgomery_Exponentiator::execute() const - { - const size_t exp_nibbles = (exp_bits + window_bits - 1) / window_bits; - - BigInt x = R_mod; - SecureVector z(2 * (mod_words + 1)); - SecureVector workspace(2 * (mod_words + 1)); - - for(size_t i = exp_nibbles; i > 0; --i) - { - for(size_t k = 0; k != window_bits; ++k) - { - zeroise(z); - - bigint_monty_sqr(&z[0], z.size(), - x.data(), x.size(), x.sig_words(), - modulus.data(), mod_words, mod_prime, - &workspace[0]); - - x.assign(&z[0], mod_words + 1); - } - - if(u32bit nibble = exp.get_substring(window_bits*(i-1), window_bits)) - { - const BigInt& y = g[nibble-1]; - - zeroise(z); - bigint_monty_mul(&z[0], z.size(), - x.data(), x.size(), x.sig_words(), - y.data(), y.size(), y.sig_words(), - modulus.data(), mod_words, mod_prime, - &workspace[0]); - - x.assign(&z[0], mod_words + 1); - } - } - - x.get_reg().resize(2*mod_words+1); - - bigint_monty_redc(&x[0], x.size(), - modulus.data(), mod_words, mod_prime, - &workspace[0]); - - x.get_reg().resize(mod_words+1); - - return x; - } - -/* -* Montgomery_Exponentiator Constructor -*/ -Montgomery_Exponentiator::Montgomery_Exponentiator(const BigInt& mod, - Power_Mod::Usage_Hints hints) - { - // Montgomery reduction only works for positive odd moduli - if(!mod.is_positive() || mod.is_even()) - throw Invalid_Argument("Montgomery_Exponentiator: invalid modulus"); - - window_bits = 0; - this->hints = hints; - modulus = mod; - exp_bits = 0; - - mod_words = modulus.sig_words(); - - BigInt r(BigInt::Power2, mod_words * BOTAN_MP_WORD_BITS); - mod_prime = (((r * inverse_mod(r, mod)) - 1) / mod).word_at(0); - - R_mod = r % modulus; - - R2 = (R_mod * R_mod) % modulus; - } - -} -/* -* Small Primes Table -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -const u16bit PRIMES[PRIME_TABLE_SIZE+1] = { - 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, - 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, - 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, - 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, - 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, - 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, - 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, - 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, - 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, - 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, - 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, - 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, - 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, - 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, - 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, - 991, 997, 1009, 1013, 1019, 1021, 1031, 1033, 1039, 1049, 1051, - 1061, 1063, 1069, 1087, 1091, 1093, 1097, 1103, 1109, 1117, 1123, - 1129, 1151, 1153, 1163, 1171, 1181, 1187, 1193, 1201, 1213, 1217, - 1223, 1229, 1231, 1237, 1249, 1259, 1277, 1279, 1283, 1289, 1291, - 1297, 1301, 1303, 1307, 1319, 1321, 1327, 1361, 1367, 1373, 1381, - 1399, 1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451, 1453, 1459, - 1471, 1481, 1483, 1487, 1489, 1493, 1499, 1511, 1523, 1531, 1543, - 1549, 1553, 1559, 1567, 1571, 1579, 1583, 1597, 1601, 1607, 1609, - 1613, 1619, 1621, 1627, 1637, 1657, 1663, 1667, 1669, 1693, 1697, - 1699, 1709, 1721, 1723, 1733, 1741, 1747, 1753, 1759, 1777, 1783, - 1787, 1789, 1801, 1811, 1823, 1831, 1847, 1861, 1867, 1871, 1873, - 1877, 1879, 1889, 1901, 1907, 1913, 1931, 1933, 1949, 1951, 1973, - 1979, 1987, 1993, 1997, 1999, 2003, 2011, 2017, 2027, 2029, 2039, - 2053, 2063, 2069, 2081, 2083, 2087, 2089, 2099, 2111, 2113, 2129, - 2131, 2137, 2141, 2143, 2153, 2161, 2179, 2203, 2207, 2213, 2221, - 2237, 2239, 2243, 2251, 2267, 2269, 2273, 2281, 2287, 2293, 2297, - 2309, 2311, 2333, 2339, 2341, 2347, 2351, 2357, 2371, 2377, 2381, - 2383, 2389, 2393, 2399, 2411, 2417, 2423, 2437, 2441, 2447, 2459, - 2467, 2473, 2477, 2503, 2521, 2531, 2539, 2543, 2549, 2551, 2557, - 2579, 2591, 2593, 2609, 2617, 2621, 2633, 2647, 2657, 2659, 2663, - 2671, 2677, 2683, 2687, 2689, 2693, 2699, 2707, 2711, 2713, 2719, - 2729, 2731, 2741, 2749, 2753, 2767, 2777, 2789, 2791, 2797, 2801, - 2803, 2819, 2833, 2837, 2843, 2851, 2857, 2861, 2879, 2887, 2897, - 2903, 2909, 2917, 2927, 2939, 2953, 2957, 2963, 2969, 2971, 2999, - 3001, 3011, 3019, 3023, 3037, 3041, 3049, 3061, 3067, 3079, 3083, - 3089, 3109, 3119, 3121, 3137, 3163, 3167, 3169, 3181, 3187, 3191, - 3203, 3209, 3217, 3221, 3229, 3251, 3253, 3257, 3259, 3271, 3299, - 3301, 3307, 3313, 3319, 3323, 3329, 3331, 3343, 3347, 3359, 3361, - 3371, 3373, 3389, 3391, 3407, 3413, 3433, 3449, 3457, 3461, 3463, - 3467, 3469, 3491, 3499, 3511, 3517, 3527, 3529, 3533, 3539, 3541, - 3547, 3557, 3559, 3571, 3581, 3583, 3593, 3607, 3613, 3617, 3623, - 3631, 3637, 3643, 3659, 3671, 3673, 3677, 3691, 3697, 3701, 3709, - 3719, 3727, 3733, 3739, 3761, 3767, 3769, 3779, 3793, 3797, 3803, - 3821, 3823, 3833, 3847, 3851, 3853, 3863, 3877, 3881, 3889, 3907, - 3911, 3917, 3919, 3923, 3929, 3931, 3943, 3947, 3967, 3989, 4001, - 4003, 4007, 4013, 4019, 4021, 4027, 4049, 4051, 4057, 4073, 4079, - 4091, 4093, 4099, 4111, 4127, 4129, 4133, 4139, 4153, 4157, 4159, - 4177, 4201, 4211, 4217, 4219, 4229, 4231, 4241, 4243, 4253, 4259, - 4261, 4271, 4273, 4283, 4289, 4297, 4327, 4337, 4339, 4349, 4357, - 4363, 4373, 4391, 4397, 4409, 4421, 4423, 4441, 4447, 4451, 4457, - 4463, 4481, 4483, 4493, 4507, 4513, 4517, 4519, 4523, 4547, 4549, - 4561, 4567, 4583, 4591, 4597, 4603, 4621, 4637, 4639, 4643, 4649, - 4651, 4657, 4663, 4673, 4679, 4691, 4703, 4721, 4723, 4729, 4733, - 4751, 4759, 4783, 4787, 4789, 4793, 4799, 4801, 4813, 4817, 4831, - 4861, 4871, 4877, 4889, 4903, 4909, 4919, 4931, 4933, 4937, 4943, - 4951, 4957, 4967, 4969, 4973, 4987, 4993, 4999, 5003, 5009, 5011, - 5021, 5023, 5039, 5051, 5059, 5077, 5081, 5087, 5099, 5101, 5107, - 5113, 5119, 5147, 5153, 5167, 5171, 5179, 5189, 5197, 5209, 5227, - 5231, 5233, 5237, 5261, 5273, 5279, 5281, 5297, 5303, 5309, 5323, - 5333, 5347, 5351, 5381, 5387, 5393, 5399, 5407, 5413, 5417, 5419, - 5431, 5437, 5441, 5443, 5449, 5471, 5477, 5479, 5483, 5501, 5503, - 5507, 5519, 5521, 5527, 5531, 5557, 5563, 5569, 5573, 5581, 5591, - 5623, 5639, 5641, 5647, 5651, 5653, 5657, 5659, 5669, 5683, 5689, - 5693, 5701, 5711, 5717, 5737, 5741, 5743, 5749, 5779, 5783, 5791, - 5801, 5807, 5813, 5821, 5827, 5839, 5843, 5849, 5851, 5857, 5861, - 5867, 5869, 5879, 5881, 5897, 5903, 5923, 5927, 5939, 5953, 5981, - 5987, 6007, 6011, 6029, 6037, 6043, 6047, 6053, 6067, 6073, 6079, - 6089, 6091, 6101, 6113, 6121, 6131, 6133, 6143, 6151, 6163, 6173, - 6197, 6199, 6203, 6211, 6217, 6221, 6229, 6247, 6257, 6263, 6269, - 6271, 6277, 6287, 6299, 6301, 6311, 6317, 6323, 6329, 6337, 6343, - 6353, 6359, 6361, 6367, 6373, 6379, 6389, 6397, 6421, 6427, 6449, - 6451, 6469, 6473, 6481, 6491, 6521, 6529, 6547, 6551, 6553, 6563, - 6569, 6571, 6577, 6581, 6599, 6607, 6619, 6637, 6653, 6659, 6661, - 6673, 6679, 6689, 6691, 6701, 6703, 6709, 6719, 6733, 6737, 6761, - 6763, 6779, 6781, 6791, 6793, 6803, 6823, 6827, 6829, 6833, 6841, - 6857, 6863, 6869, 6871, 6883, 6899, 6907, 6911, 6917, 6947, 6949, - 6959, 6961, 6967, 6971, 6977, 6983, 6991, 6997, 7001, 7013, 7019, - 7027, 7039, 7043, 7057, 7069, 7079, 7103, 7109, 7121, 7127, 7129, - 7151, 7159, 7177, 7187, 7193, 7207, 7211, 7213, 7219, 7229, 7237, - 7243, 7247, 7253, 7283, 7297, 7307, 7309, 7321, 7331, 7333, 7349, - 7351, 7369, 7393, 7411, 7417, 7433, 7451, 7457, 7459, 7477, 7481, - 7487, 7489, 7499, 7507, 7517, 7523, 7529, 7537, 7541, 7547, 7549, - 7559, 7561, 7573, 7577, 7583, 7589, 7591, 7603, 7607, 7621, 7639, - 7643, 7649, 7669, 7673, 7681, 7687, 7691, 7699, 7703, 7717, 7723, - 7727, 7741, 7753, 7757, 7759, 7789, 7793, 7817, 7823, 7829, 7841, - 7853, 7867, 7873, 7877, 7879, 7883, 7901, 7907, 7919, 7927, 7933, - 7937, 7949, 7951, 7963, 7993, 8009, 8011, 8017, 8039, 8053, 8059, - 8069, 8081, 8087, 8089, 8093, 8101, 8111, 8117, 8123, 8147, 8161, - 8167, 8171, 8179, 8191, 8209, 8219, 8221, 8231, 8233, 8237, 8243, - 8263, 8269, 8273, 8287, 8291, 8293, 8297, 8311, 8317, 8329, 8353, - 8363, 8369, 8377, 8387, 8389, 8419, 8423, 8429, 8431, 8443, 8447, - 8461, 8467, 8501, 8513, 8521, 8527, 8537, 8539, 8543, 8563, 8573, - 8581, 8597, 8599, 8609, 8623, 8627, 8629, 8641, 8647, 8663, 8669, - 8677, 8681, 8689, 8693, 8699, 8707, 8713, 8719, 8731, 8737, 8741, - 8747, 8753, 8761, 8779, 8783, 8803, 8807, 8819, 8821, 8831, 8837, - 8839, 8849, 8861, 8863, 8867, 8887, 8893, 8923, 8929, 8933, 8941, - 8951, 8963, 8969, 8971, 8999, 9001, 9007, 9011, 9013, 9029, 9041, - 9043, 9049, 9059, 9067, 9091, 9103, 9109, 9127, 9133, 9137, 9151, - 9157, 9161, 9173, 9181, 9187, 9199, 9203, 9209, 9221, 9227, 9239, - 9241, 9257, 9277, 9281, 9283, 9293, 9311, 9319, 9323, 9337, 9341, - 9343, 9349, 9371, 9377, 9391, 9397, 9403, 9413, 9419, 9421, 9431, - 9433, 9437, 9439, 9461, 9463, 9467, 9473, 9479, 9491, 9497, 9511, - 9521, 9533, 9539, 9547, 9551, 9587, 9601, 9613, 9619, 9623, 9629, - 9631, 9643, 9649, 9661, 9677, 9679, 9689, 9697, 9719, 9721, 9733, - 9739, 9743, 9749, 9767, 9769, 9781, 9787, 9791, 9803, 9811, 9817, - 9829, 9833, 9839, 9851, 9857, 9859, 9871, 9883, 9887, 9901, 9907, - 9923, 9929, 9931, 9941, 9949, 9967, 9973, 10007, 10009, 10037, 10039, -10061, 10067, 10069, 10079, 10091, 10093, 10099, 10103, 10111, 10133, 10139, -10141, 10151, 10159, 10163, 10169, 10177, 10181, 10193, 10211, 10223, 10243, -10247, 10253, 10259, 10267, 10271, 10273, 10289, 10301, 10303, 10313, 10321, -10331, 10333, 10337, 10343, 10357, 10369, 10391, 10399, 10427, 10429, 10433, -10453, 10457, 10459, 10463, 10477, 10487, 10499, 10501, 10513, 10529, 10531, -10559, 10567, 10589, 10597, 10601, 10607, 10613, 10627, 10631, 10639, 10651, -10657, 10663, 10667, 10687, 10691, 10709, 10711, 10723, 10729, 10733, 10739, -10753, 10771, 10781, 10789, 10799, 10831, 10837, 10847, 10853, 10859, 10861, -10867, 10883, 10889, 10891, 10903, 10909, 10937, 10939, 10949, 10957, 10973, -10979, 10987, 10993, 11003, 11027, 11047, 11057, 11059, 11069, 11071, 11083, -11087, 11093, 11113, 11117, 11119, 11131, 11149, 11159, 11161, 11171, 11173, -11177, 11197, 11213, 11239, 11243, 11251, 11257, 11261, 11273, 11279, 11287, -11299, 11311, 11317, 11321, 11329, 11351, 11353, 11369, 11383, 11393, 11399, -11411, 11423, 11437, 11443, 11447, 11467, 11471, 11483, 11489, 11491, 11497, -11503, 11519, 11527, 11549, 11551, 11579, 11587, 11593, 11597, 11617, 11621, -11633, 11657, 11677, 11681, 11689, 11699, 11701, 11717, 11719, 11731, 11743, -11777, 11779, 11783, 11789, 11801, 11807, 11813, 11821, 11827, 11831, 11833, -11839, 11863, 11867, 11887, 11897, 11903, 11909, 11923, 11927, 11933, 11939, -11941, 11953, 11959, 11969, 11971, 11981, 11987, 12007, 12011, 12037, 12041, -12043, 12049, 12071, 12073, 12097, 12101, 12107, 12109, 12113, 12119, 12143, -12149, 12157, 12161, 12163, 12197, 12203, 12211, 12227, 12239, 12241, 12251, -12253, 12263, 12269, 12277, 12281, 12289, 12301, 12323, 12329, 12343, 12347, -12373, 12377, 12379, 12391, 12401, 12409, 12413, 12421, 12433, 12437, 12451, -12457, 12473, 12479, 12487, 12491, 12497, 12503, 12511, 12517, 12527, 12539, -12541, 12547, 12553, 12569, 12577, 12583, 12589, 12601, 12611, 12613, 12619, -12637, 12641, 12647, 12653, 12659, 12671, 12689, 12697, 12703, 12713, 12721, -12739, 12743, 12757, 12763, 12781, 12791, 12799, 12809, 12821, 12823, 12829, -12841, 12853, 12889, 12893, 12899, 12907, 12911, 12917, 12919, 12923, 12941, -12953, 12959, 12967, 12973, 12979, 12983, 13001, 13003, 13007, 13009, 13033, -13037, 13043, 13049, 13063, 13093, 13099, 13103, 13109, 13121, 13127, 13147, -13151, 13159, 13163, 13171, 13177, 13183, 13187, 13217, 13219, 13229, 13241, -13249, 13259, 13267, 13291, 13297, 13309, 13313, 13327, 13331, 13337, 13339, -13367, 13381, 13397, 13399, 13411, 13417, 13421, 13441, 13451, 13457, 13463, -13469, 13477, 13487, 13499, 13513, 13523, 13537, 13553, 13567, 13577, 13591, -13597, 13613, 13619, 13627, 13633, 13649, 13669, 13679, 13681, 13687, 13691, -13693, 13697, 13709, 13711, 13721, 13723, 13729, 13751, 13757, 13759, 13763, -13781, 13789, 13799, 13807, 13829, 13831, 13841, 13859, 13873, 13877, 13879, -13883, 13901, 13903, 13907, 13913, 13921, 13931, 13933, 13963, 13967, 13997, -13999, 14009, 14011, 14029, 14033, 14051, 14057, 14071, 14081, 14083, 14087, -14107, 14143, 14149, 14153, 14159, 14173, 14177, 14197, 14207, 14221, 14243, -14249, 14251, 14281, 14293, 14303, 14321, 14323, 14327, 14341, 14347, 14369, -14387, 14389, 14401, 14407, 14411, 14419, 14423, 14431, 14437, 14447, 14449, -14461, 14479, 14489, 14503, 14519, 14533, 14537, 14543, 14549, 14551, 14557, -14561, 14563, 14591, 14593, 14621, 14627, 14629, 14633, 14639, 14653, 14657, -14669, 14683, 14699, 14713, 14717, 14723, 14731, 14737, 14741, 14747, 14753, -14759, 14767, 14771, 14779, 14783, 14797, 14813, 14821, 14827, 14831, 14843, -14851, 14867, 14869, 14879, 14887, 14891, 14897, 14923, 14929, 14939, 14947, -14951, 14957, 14969, 14983, 15013, 15017, 15031, 15053, 15061, 15073, 15077, -15083, 15091, 15101, 15107, 15121, 15131, 15137, 15139, 15149, 15161, 15173, -15187, 15193, 15199, 15217, 15227, 15233, 15241, 15259, 15263, 15269, 15271, -15277, 15287, 15289, 15299, 15307, 15313, 15319, 15329, 15331, 15349, 15359, -15361, 15373, 15377, 15383, 15391, 15401, 15413, 15427, 15439, 15443, 15451, -15461, 15467, 15473, 15493, 15497, 15511, 15527, 15541, 15551, 15559, 15569, -15581, 15583, 15601, 15607, 15619, 15629, 15641, 15643, 15647, 15649, 15661, -15667, 15671, 15679, 15683, 15727, 15731, 15733, 15737, 15739, 15749, 15761, -15767, 15773, 15787, 15791, 15797, 15803, 15809, 15817, 15823, 15859, 15877, -15881, 15887, 15889, 15901, 15907, 15913, 15919, 15923, 15937, 15959, 15971, -15973, 15991, 16001, 16007, 16033, 16057, 16061, 16063, 16067, 16069, 16073, -16087, 16091, 16097, 16103, 16111, 16127, 16139, 16141, 16183, 16187, 16189, -16193, 16217, 16223, 16229, 16231, 16249, 16253, 16267, 16273, 16301, 16319, -16333, 16339, 16349, 16361, 16363, 16369, 16381, 16411, 16417, 16421, 16427, -16433, 16447, 16451, 16453, 16477, 16481, 16487, 16493, 16519, 16529, 16547, -16553, 16561, 16567, 16573, 16603, 16607, 16619, 16631, 16633, 16649, 16651, -16657, 16661, 16673, 16691, 16693, 16699, 16703, 16729, 16741, 16747, 16759, -16763, 16787, 16811, 16823, 16829, 16831, 16843, 16871, 16879, 16883, 16889, -16901, 16903, 16921, 16927, 16931, 16937, 16943, 16963, 16979, 16981, 16987, -16993, 17011, 17021, 17027, 17029, 17033, 17041, 17047, 17053, 17077, 17093, -17099, 17107, 17117, 17123, 17137, 17159, 17167, 17183, 17189, 17191, 17203, -17207, 17209, 17231, 17239, 17257, 17291, 17293, 17299, 17317, 17321, 17327, -17333, 17341, 17351, 17359, 17377, 17383, 17387, 17389, 17393, 17401, 17417, -17419, 17431, 17443, 17449, 17467, 17471, 17477, 17483, 17489, 17491, 17497, -17509, 17519, 17539, 17551, 17569, 17573, 17579, 17581, 17597, 17599, 17609, -17623, 17627, 17657, 17659, 17669, 17681, 17683, 17707, 17713, 17729, 17737, -17747, 17749, 17761, 17783, 17789, 17791, 17807, 17827, 17837, 17839, 17851, -17863, 17881, 17891, 17903, 17909, 17911, 17921, 17923, 17929, 17939, 17957, -17959, 17971, 17977, 17981, 17987, 17989, 18013, 18041, 18043, 18047, 18049, -18059, 18061, 18077, 18089, 18097, 18119, 18121, 18127, 18131, 18133, 18143, -18149, 18169, 18181, 18191, 18199, 18211, 18217, 18223, 18229, 18233, 18251, -18253, 18257, 18269, 18287, 18289, 18301, 18307, 18311, 18313, 18329, 18341, -18353, 18367, 18371, 18379, 18397, 18401, 18413, 18427, 18433, 18439, 18443, -18451, 18457, 18461, 18481, 18493, 18503, 18517, 18521, 18523, 18539, 18541, -18553, 18583, 18587, 18593, 18617, 18637, 18661, 18671, 18679, 18691, 18701, -18713, 18719, 18731, 18743, 18749, 18757, 18773, 18787, 18793, 18797, 18803, -18839, 18859, 18869, 18899, 18911, 18913, 18917, 18919, 18947, 18959, 18973, -18979, 19001, 19009, 19013, 19031, 19037, 19051, 19069, 19073, 19079, 19081, -19087, 19121, 19139, 19141, 19157, 19163, 19181, 19183, 19207, 19211, 19213, -19219, 19231, 19237, 19249, 19259, 19267, 19273, 19289, 19301, 19309, 19319, -19333, 19373, 19379, 19381, 19387, 19391, 19403, 19417, 19421, 19423, 19427, -19429, 19433, 19441, 19447, 19457, 19463, 19469, 19471, 19477, 19483, 19489, -19501, 19507, 19531, 19541, 19543, 19553, 19559, 19571, 19577, 19583, 19597, -19603, 19609, 19661, 19681, 19687, 19697, 19699, 19709, 19717, 19727, 19739, -19751, 19753, 19759, 19763, 19777, 19793, 19801, 19813, 19819, 19841, 19843, -19853, 19861, 19867, 19889, 19891, 19913, 19919, 19927, 19937, 19949, 19961, -19963, 19973, 19979, 19991, 19993, 19997, 20011, 20021, 20023, 20029, 20047, -20051, 20063, 20071, 20089, 20101, 20107, 20113, 20117, 20123, 20129, 20143, -20147, 20149, 20161, 20173, 20177, 20183, 20201, 20219, 20231, 20233, 20249, -20261, 20269, 20287, 20297, 20323, 20327, 20333, 20341, 20347, 20353, 20357, -20359, 20369, 20389, 20393, 20399, 20407, 20411, 20431, 20441, 20443, 20477, -20479, 20483, 20507, 20509, 20521, 20533, 20543, 20549, 20551, 20563, 20593, -20599, 20611, 20627, 20639, 20641, 20663, 20681, 20693, 20707, 20717, 20719, -20731, 20743, 20747, 20749, 20753, 20759, 20771, 20773, 20789, 20807, 20809, -20849, 20857, 20873, 20879, 20887, 20897, 20899, 20903, 20921, 20929, 20939, -20947, 20959, 20963, 20981, 20983, 21001, 21011, 21013, 21017, 21019, 21023, -21031, 21059, 21061, 21067, 21089, 21101, 21107, 21121, 21139, 21143, 21149, -21157, 21163, 21169, 21179, 21187, 21191, 21193, 21211, 21221, 21227, 21247, -21269, 21277, 21283, 21313, 21317, 21319, 21323, 21341, 21347, 21377, 21379, -21383, 21391, 21397, 21401, 21407, 21419, 21433, 21467, 21481, 21487, 21491, -21493, 21499, 21503, 21517, 21521, 21523, 21529, 21557, 21559, 21563, 21569, -21577, 21587, 21589, 21599, 21601, 21611, 21613, 21617, 21647, 21649, 21661, -21673, 21683, 21701, 21713, 21727, 21737, 21739, 21751, 21757, 21767, 21773, -21787, 21799, 21803, 21817, 21821, 21839, 21841, 21851, 21859, 21863, 21871, -21881, 21893, 21911, 21929, 21937, 21943, 21961, 21977, 21991, 21997, 22003, -22013, 22027, 22031, 22037, 22039, 22051, 22063, 22067, 22073, 22079, 22091, -22093, 22109, 22111, 22123, 22129, 22133, 22147, 22153, 22157, 22159, 22171, -22189, 22193, 22229, 22247, 22259, 22271, 22273, 22277, 22279, 22283, 22291, -22303, 22307, 22343, 22349, 22367, 22369, 22381, 22391, 22397, 22409, 22433, -22441, 22447, 22453, 22469, 22481, 22483, 22501, 22511, 22531, 22541, 22543, -22549, 22567, 22571, 22573, 22613, 22619, 22621, 22637, 22639, 22643, 22651, -22669, 22679, 22691, 22697, 22699, 22709, 22717, 22721, 22727, 22739, 22741, -22751, 22769, 22777, 22783, 22787, 22807, 22811, 22817, 22853, 22859, 22861, -22871, 22877, 22901, 22907, 22921, 22937, 22943, 22961, 22963, 22973, 22993, -23003, 23011, 23017, 23021, 23027, 23029, 23039, 23041, 23053, 23057, 23059, -23063, 23071, 23081, 23087, 23099, 23117, 23131, 23143, 23159, 23167, 23173, -23189, 23197, 23201, 23203, 23209, 23227, 23251, 23269, 23279, 23291, 23293, -23297, 23311, 23321, 23327, 23333, 23339, 23357, 23369, 23371, 23399, 23417, -23431, 23447, 23459, 23473, 23497, 23509, 23531, 23537, 23539, 23549, 23557, -23561, 23563, 23567, 23581, 23593, 23599, 23603, 23609, 23623, 23627, 23629, -23633, 23663, 23669, 23671, 23677, 23687, 23689, 23719, 23741, 23743, 23747, -23753, 23761, 23767, 23773, 23789, 23801, 23813, 23819, 23827, 23831, 23833, -23857, 23869, 23873, 23879, 23887, 23893, 23899, 23909, 23911, 23917, 23929, -23957, 23971, 23977, 23981, 23993, 24001, 24007, 24019, 24023, 24029, 24043, -24049, 24061, 24071, 24077, 24083, 24091, 24097, 24103, 24107, 24109, 24113, -24121, 24133, 24137, 24151, 24169, 24179, 24181, 24197, 24203, 24223, 24229, -24239, 24247, 24251, 24281, 24317, 24329, 24337, 24359, 24371, 24373, 24379, -24391, 24407, 24413, 24419, 24421, 24439, 24443, 24469, 24473, 24481, 24499, -24509, 24517, 24527, 24533, 24547, 24551, 24571, 24593, 24611, 24623, 24631, -24659, 24671, 24677, 24683, 24691, 24697, 24709, 24733, 24749, 24763, 24767, -24781, 24793, 24799, 24809, 24821, 24841, 24847, 24851, 24859, 24877, 24889, -24907, 24917, 24919, 24923, 24943, 24953, 24967, 24971, 24977, 24979, 24989, -25013, 25031, 25033, 25037, 25057, 25073, 25087, 25097, 25111, 25117, 25121, -25127, 25147, 25153, 25163, 25169, 25171, 25183, 25189, 25219, 25229, 25237, -25243, 25247, 25253, 25261, 25301, 25303, 25307, 25309, 25321, 25339, 25343, -25349, 25357, 25367, 25373, 25391, 25409, 25411, 25423, 25439, 25447, 25453, -25457, 25463, 25469, 25471, 25523, 25537, 25541, 25561, 25577, 25579, 25583, -25589, 25601, 25603, 25609, 25621, 25633, 25639, 25643, 25657, 25667, 25673, -25679, 25693, 25703, 25717, 25733, 25741, 25747, 25759, 25763, 25771, 25793, -25799, 25801, 25819, 25841, 25847, 25849, 25867, 25873, 25889, 25903, 25913, -25919, 25931, 25933, 25939, 25943, 25951, 25969, 25981, 25997, 25999, 26003, -26017, 26021, 26029, 26041, 26053, 26083, 26099, 26107, 26111, 26113, 26119, -26141, 26153, 26161, 26171, 26177, 26183, 26189, 26203, 26209, 26227, 26237, -26249, 26251, 26261, 26263, 26267, 26293, 26297, 26309, 26317, 26321, 26339, -26347, 26357, 26371, 26387, 26393, 26399, 26407, 26417, 26423, 26431, 26437, -26449, 26459, 26479, 26489, 26497, 26501, 26513, 26539, 26557, 26561, 26573, -26591, 26597, 26627, 26633, 26641, 26647, 26669, 26681, 26683, 26687, 26693, -26699, 26701, 26711, 26713, 26717, 26723, 26729, 26731, 26737, 26759, 26777, -26783, 26801, 26813, 26821, 26833, 26839, 26849, 26861, 26863, 26879, 26881, -26891, 26893, 26903, 26921, 26927, 26947, 26951, 26953, 26959, 26981, 26987, -26993, 27011, 27017, 27031, 27043, 27059, 27061, 27067, 27073, 27077, 27091, -27103, 27107, 27109, 27127, 27143, 27179, 27191, 27197, 27211, 27239, 27241, -27253, 27259, 27271, 27277, 27281, 27283, 27299, 27329, 27337, 27361, 27367, -27397, 27407, 27409, 27427, 27431, 27437, 27449, 27457, 27479, 27481, 27487, -27509, 27527, 27529, 27539, 27541, 27551, 27581, 27583, 27611, 27617, 27631, -27647, 27653, 27673, 27689, 27691, 27697, 27701, 27733, 27737, 27739, 27743, -27749, 27751, 27763, 27767, 27773, 27779, 27791, 27793, 27799, 27803, 27809, -27817, 27823, 27827, 27847, 27851, 27883, 27893, 27901, 27917, 27919, 27941, -27943, 27947, 27953, 27961, 27967, 27983, 27997, 28001, 28019, 28027, 28031, -28051, 28057, 28069, 28081, 28087, 28097, 28099, 28109, 28111, 28123, 28151, -28163, 28181, 28183, 28201, 28211, 28219, 28229, 28277, 28279, 28283, 28289, -28297, 28307, 28309, 28319, 28349, 28351, 28387, 28393, 28403, 28409, 28411, -28429, 28433, 28439, 28447, 28463, 28477, 28493, 28499, 28513, 28517, 28537, -28541, 28547, 28549, 28559, 28571, 28573, 28579, 28591, 28597, 28603, 28607, -28619, 28621, 28627, 28631, 28643, 28649, 28657, 28661, 28663, 28669, 28687, -28697, 28703, 28711, 28723, 28729, 28751, 28753, 28759, 28771, 28789, 28793, -28807, 28813, 28817, 28837, 28843, 28859, 28867, 28871, 28879, 28901, 28909, -28921, 28927, 28933, 28949, 28961, 28979, 29009, 29017, 29021, 29023, 29027, -29033, 29059, 29063, 29077, 29101, 29123, 29129, 29131, 29137, 29147, 29153, -29167, 29173, 29179, 29191, 29201, 29207, 29209, 29221, 29231, 29243, 29251, -29269, 29287, 29297, 29303, 29311, 29327, 29333, 29339, 29347, 29363, 29383, -29387, 29389, 29399, 29401, 29411, 29423, 29429, 29437, 29443, 29453, 29473, -29483, 29501, 29527, 29531, 29537, 29567, 29569, 29573, 29581, 29587, 29599, -29611, 29629, 29633, 29641, 29663, 29669, 29671, 29683, 29717, 29723, 29741, -29753, 29759, 29761, 29789, 29803, 29819, 29833, 29837, 29851, 29863, 29867, -29873, 29879, 29881, 29917, 29921, 29927, 29947, 29959, 29983, 29989, 30011, -30013, 30029, 30047, 30059, 30071, 30089, 30091, 30097, 30103, 30109, 30113, -30119, 30133, 30137, 30139, 30161, 30169, 30181, 30187, 30197, 30203, 30211, -30223, 30241, 30253, 30259, 30269, 30271, 30293, 30307, 30313, 30319, 30323, -30341, 30347, 30367, 30389, 30391, 30403, 30427, 30431, 30449, 30467, 30469, -30491, 30493, 30497, 30509, 30517, 30529, 30539, 30553, 30557, 30559, 30577, -30593, 30631, 30637, 30643, 30649, 30661, 30671, 30677, 30689, 30697, 30703, -30707, 30713, 30727, 30757, 30763, 30773, 30781, 30803, 30809, 30817, 30829, -30839, 30841, 30851, 30853, 30859, 30869, 30871, 30881, 30893, 30911, 30931, -30937, 30941, 30949, 30971, 30977, 30983, 31013, 31019, 31033, 31039, 31051, -31063, 31069, 31079, 31081, 31091, 31121, 31123, 31139, 31147, 31151, 31153, -31159, 31177, 31181, 31183, 31189, 31193, 31219, 31223, 31231, 31237, 31247, -31249, 31253, 31259, 31267, 31271, 31277, 31307, 31319, 31321, 31327, 31333, -31337, 31357, 31379, 31387, 31391, 31393, 31397, 31469, 31477, 31481, 31489, -31511, 31513, 31517, 31531, 31541, 31543, 31547, 31567, 31573, 31583, 31601, -31607, 31627, 31643, 31649, 31657, 31663, 31667, 31687, 31699, 31721, 31723, -31727, 31729, 31741, 31751, 31769, 31771, 31793, 31799, 31817, 31847, 31849, -31859, 31873, 31883, 31891, 31907, 31957, 31963, 31973, 31981, 31991, 32003, -32009, 32027, 32029, 32051, 32057, 32059, 32063, 32069, 32077, 32083, 32089, -32099, 32117, 32119, 32141, 32143, 32159, 32173, 32183, 32189, 32191, 32203, -32213, 32233, 32237, 32251, 32257, 32261, 32297, 32299, 32303, 32309, 32321, -32323, 32327, 32341, 32353, 32359, 32363, 32369, 32371, 32377, 32381, 32401, -32411, 32413, 32423, 32429, 32441, 32443, 32467, 32479, 32491, 32497, 32503, -32507, 32531, 32533, 32537, 32561, 32563, 32569, 32573, 32579, 32587, 32603, -32609, 32611, 32621, 32633, 32647, 32653, 32687, 32693, 32707, 32713, 32717, -32719, 32749, 32771, 32779, 32783, 32789, 32797, 32801, 32803, 32831, 32833, -32839, 32843, 32869, 32887, 32909, 32911, 32917, 32933, 32939, 32941, 32957, -32969, 32971, 32983, 32987, 32993, 32999, 33013, 33023, 33029, 33037, 33049, -33053, 33071, 33073, 33083, 33091, 33107, 33113, 33119, 33149, 33151, 33161, -33179, 33181, 33191, 33199, 33203, 33211, 33223, 33247, 33287, 33289, 33301, -33311, 33317, 33329, 33331, 33343, 33347, 33349, 33353, 33359, 33377, 33391, -33403, 33409, 33413, 33427, 33457, 33461, 33469, 33479, 33487, 33493, 33503, -33521, 33529, 33533, 33547, 33563, 33569, 33577, 33581, 33587, 33589, 33599, -33601, 33613, 33617, 33619, 33623, 33629, 33637, 33641, 33647, 33679, 33703, -33713, 33721, 33739, 33749, 33751, 33757, 33767, 33769, 33773, 33791, 33797, -33809, 33811, 33827, 33829, 33851, 33857, 33863, 33871, 33889, 33893, 33911, -33923, 33931, 33937, 33941, 33961, 33967, 33997, 34019, 34031, 34033, 34039, -34057, 34061, 34123, 34127, 34129, 34141, 34147, 34157, 34159, 34171, 34183, -34211, 34213, 34217, 34231, 34253, 34259, 34261, 34267, 34273, 34283, 34297, -34301, 34303, 34313, 34319, 34327, 34337, 34351, 34361, 34367, 34369, 34381, -34403, 34421, 34429, 34439, 34457, 34469, 34471, 34483, 34487, 34499, 34501, -34511, 34513, 34519, 34537, 34543, 34549, 34583, 34589, 34591, 34603, 34607, -34613, 34631, 34649, 34651, 34667, 34673, 34679, 34687, 34693, 34703, 34721, -34729, 34739, 34747, 34757, 34759, 34763, 34781, 34807, 34819, 34841, 34843, -34847, 34849, 34871, 34877, 34883, 34897, 34913, 34919, 34939, 34949, 34961, -34963, 34981, 35023, 35027, 35051, 35053, 35059, 35069, 35081, 35083, 35089, -35099, 35107, 35111, 35117, 35129, 35141, 35149, 35153, 35159, 35171, 35201, -35221, 35227, 35251, 35257, 35267, 35279, 35281, 35291, 35311, 35317, 35323, -35327, 35339, 35353, 35363, 35381, 35393, 35401, 35407, 35419, 35423, 35437, -35447, 35449, 35461, 35491, 35507, 35509, 35521, 35527, 35531, 35533, 35537, -35543, 35569, 35573, 35591, 35593, 35597, 35603, 35617, 35671, 35677, 35729, -35731, 35747, 35753, 35759, 35771, 35797, 35801, 35803, 35809, 35831, 35837, -35839, 35851, 35863, 35869, 35879, 35897, 35899, 35911, 35923, 35933, 35951, -35963, 35969, 35977, 35983, 35993, 35999, 36007, 36011, 36013, 36017, 36037, -36061, 36067, 36073, 36083, 36097, 36107, 36109, 36131, 36137, 36151, 36161, -36187, 36191, 36209, 36217, 36229, 36241, 36251, 36263, 36269, 36277, 36293, -36299, 36307, 36313, 36319, 36341, 36343, 36353, 36373, 36383, 36389, 36433, -36451, 36457, 36467, 36469, 36473, 36479, 36493, 36497, 36523, 36527, 36529, -36541, 36551, 36559, 36563, 36571, 36583, 36587, 36599, 36607, 36629, 36637, -36643, 36653, 36671, 36677, 36683, 36691, 36697, 36709, 36713, 36721, 36739, -36749, 36761, 36767, 36779, 36781, 36787, 36791, 36793, 36809, 36821, 36833, -36847, 36857, 36871, 36877, 36887, 36899, 36901, 36913, 36919, 36923, 36929, -36931, 36943, 36947, 36973, 36979, 36997, 37003, 37013, 37019, 37021, 37039, -37049, 37057, 37061, 37087, 37097, 37117, 37123, 37139, 37159, 37171, 37181, -37189, 37199, 37201, 37217, 37223, 37243, 37253, 37273, 37277, 37307, 37309, -37313, 37321, 37337, 37339, 37357, 37361, 37363, 37369, 37379, 37397, 37409, -37423, 37441, 37447, 37463, 37483, 37489, 37493, 37501, 37507, 37511, 37517, -37529, 37537, 37547, 37549, 37561, 37567, 37571, 37573, 37579, 37589, 37591, -37607, 37619, 37633, 37643, 37649, 37657, 37663, 37691, 37693, 37699, 37717, -37747, 37781, 37783, 37799, 37811, 37813, 37831, 37847, 37853, 37861, 37871, -37879, 37889, 37897, 37907, 37951, 37957, 37963, 37967, 37987, 37991, 37993, -37997, 38011, 38039, 38047, 38053, 38069, 38083, 38113, 38119, 38149, 38153, -38167, 38177, 38183, 38189, 38197, 38201, 38219, 38231, 38237, 38239, 38261, -38273, 38281, 38287, 38299, 38303, 38317, 38321, 38327, 38329, 38333, 38351, -38371, 38377, 38393, 38431, 38447, 38449, 38453, 38459, 38461, 38501, 38543, -38557, 38561, 38567, 38569, 38593, 38603, 38609, 38611, 38629, 38639, 38651, -38653, 38669, 38671, 38677, 38693, 38699, 38707, 38711, 38713, 38723, 38729, -38737, 38747, 38749, 38767, 38783, 38791, 38803, 38821, 38833, 38839, 38851, -38861, 38867, 38873, 38891, 38903, 38917, 38921, 38923, 38933, 38953, 38959, -38971, 38977, 38993, 39019, 39023, 39041, 39043, 39047, 39079, 39089, 39097, -39103, 39107, 39113, 39119, 39133, 39139, 39157, 39161, 39163, 39181, 39191, -39199, 39209, 39217, 39227, 39229, 39233, 39239, 39241, 39251, 39293, 39301, -39313, 39317, 39323, 39341, 39343, 39359, 39367, 39371, 39373, 39383, 39397, -39409, 39419, 39439, 39443, 39451, 39461, 39499, 39503, 39509, 39511, 39521, -39541, 39551, 39563, 39569, 39581, 39607, 39619, 39623, 39631, 39659, 39667, -39671, 39679, 39703, 39709, 39719, 39727, 39733, 39749, 39761, 39769, 39779, -39791, 39799, 39821, 39827, 39829, 39839, 39841, 39847, 39857, 39863, 39869, -39877, 39883, 39887, 39901, 39929, 39937, 39953, 39971, 39979, 39983, 39989, -40009, 40013, 40031, 40037, 40039, 40063, 40087, 40093, 40099, 40111, 40123, -40127, 40129, 40151, 40153, 40163, 40169, 40177, 40189, 40193, 40213, 40231, -40237, 40241, 40253, 40277, 40283, 40289, 40343, 40351, 40357, 40361, 40387, -40423, 40427, 40429, 40433, 40459, 40471, 40483, 40487, 40493, 40499, 40507, -40519, 40529, 40531, 40543, 40559, 40577, 40583, 40591, 40597, 40609, 40627, -40637, 40639, 40693, 40697, 40699, 40709, 40739, 40751, 40759, 40763, 40771, -40787, 40801, 40813, 40819, 40823, 40829, 40841, 40847, 40849, 40853, 40867, -40879, 40883, 40897, 40903, 40927, 40933, 40939, 40949, 40961, 40973, 40993, -41011, 41017, 41023, 41039, 41047, 41051, 41057, 41077, 41081, 41113, 41117, -41131, 41141, 41143, 41149, 41161, 41177, 41179, 41183, 41189, 41201, 41203, -41213, 41221, 41227, 41231, 41233, 41243, 41257, 41263, 41269, 41281, 41299, -41333, 41341, 41351, 41357, 41381, 41387, 41389, 41399, 41411, 41413, 41443, -41453, 41467, 41479, 41491, 41507, 41513, 41519, 41521, 41539, 41543, 41549, -41579, 41593, 41597, 41603, 41609, 41611, 41617, 41621, 41627, 41641, 41647, -41651, 41659, 41669, 41681, 41687, 41719, 41729, 41737, 41759, 41761, 41771, -41777, 41801, 41809, 41813, 41843, 41849, 41851, 41863, 41879, 41887, 41893, -41897, 41903, 41911, 41927, 41941, 41947, 41953, 41957, 41959, 41969, 41981, -41983, 41999, 42013, 42017, 42019, 42023, 42043, 42061, 42071, 42073, 42083, -42089, 42101, 42131, 42139, 42157, 42169, 42179, 42181, 42187, 42193, 42197, -42209, 42221, 42223, 42227, 42239, 42257, 42281, 42283, 42293, 42299, 42307, -42323, 42331, 42337, 42349, 42359, 42373, 42379, 42391, 42397, 42403, 42407, -42409, 42433, 42437, 42443, 42451, 42457, 42461, 42463, 42467, 42473, 42487, -42491, 42499, 42509, 42533, 42557, 42569, 42571, 42577, 42589, 42611, 42641, -42643, 42649, 42667, 42677, 42683, 42689, 42697, 42701, 42703, 42709, 42719, -42727, 42737, 42743, 42751, 42767, 42773, 42787, 42793, 42797, 42821, 42829, -42839, 42841, 42853, 42859, 42863, 42899, 42901, 42923, 42929, 42937, 42943, -42953, 42961, 42967, 42979, 42989, 43003, 43013, 43019, 43037, 43049, 43051, -43063, 43067, 43093, 43103, 43117, 43133, 43151, 43159, 43177, 43189, 43201, -43207, 43223, 43237, 43261, 43271, 43283, 43291, 43313, 43319, 43321, 43331, -43391, 43397, 43399, 43403, 43411, 43427, 43441, 43451, 43457, 43481, 43487, -43499, 43517, 43541, 43543, 43573, 43577, 43579, 43591, 43597, 43607, 43609, -43613, 43627, 43633, 43649, 43651, 43661, 43669, 43691, 43711, 43717, 43721, -43753, 43759, 43777, 43781, 43783, 43787, 43789, 43793, 43801, 43853, 43867, -43889, 43891, 43913, 43933, 43943, 43951, 43961, 43963, 43969, 43973, 43987, -43991, 43997, 44017, 44021, 44027, 44029, 44041, 44053, 44059, 44071, 44087, -44089, 44101, 44111, 44119, 44123, 44129, 44131, 44159, 44171, 44179, 44189, -44201, 44203, 44207, 44221, 44249, 44257, 44263, 44267, 44269, 44273, 44279, -44281, 44293, 44351, 44357, 44371, 44381, 44383, 44389, 44417, 44449, 44453, -44483, 44491, 44497, 44501, 44507, 44519, 44531, 44533, 44537, 44543, 44549, -44563, 44579, 44587, 44617, 44621, 44623, 44633, 44641, 44647, 44651, 44657, -44683, 44687, 44699, 44701, 44711, 44729, 44741, 44753, 44771, 44773, 44777, -44789, 44797, 44809, 44819, 44839, 44843, 44851, 44867, 44879, 44887, 44893, -44909, 44917, 44927, 44939, 44953, 44959, 44963, 44971, 44983, 44987, 45007, -45013, 45053, 45061, 45077, 45083, 45119, 45121, 45127, 45131, 45137, 45139, -45161, 45179, 45181, 45191, 45197, 45233, 45247, 45259, 45263, 45281, 45289, -45293, 45307, 45317, 45319, 45329, 45337, 45341, 45343, 45361, 45377, 45389, -45403, 45413, 45427, 45433, 45439, 45481, 45491, 45497, 45503, 45523, 45533, -45541, 45553, 45557, 45569, 45587, 45589, 45599, 45613, 45631, 45641, 45659, -45667, 45673, 45677, 45691, 45697, 45707, 45737, 45751, 45757, 45763, 45767, -45779, 45817, 45821, 45823, 45827, 45833, 45841, 45853, 45863, 45869, 45887, -45893, 45943, 45949, 45953, 45959, 45971, 45979, 45989, 46021, 46027, 46049, -46051, 46061, 46073, 46091, 46093, 46099, 46103, 46133, 46141, 46147, 46153, -46171, 46181, 46183, 46187, 46199, 46219, 46229, 46237, 46261, 46271, 46273, -46279, 46301, 46307, 46309, 46327, 46337, 46349, 46351, 46381, 46399, 46411, -46439, 46441, 46447, 46451, 46457, 46471, 46477, 46489, 46499, 46507, 46511, -46523, 46549, 46559, 46567, 46573, 46589, 46591, 46601, 46619, 46633, 46639, -46643, 46649, 46663, 46679, 46681, 46687, 46691, 46703, 46723, 46727, 46747, -46751, 46757, 46769, 46771, 46807, 46811, 46817, 46819, 46829, 46831, 46853, -46861, 46867, 46877, 46889, 46901, 46919, 46933, 46957, 46993, 46997, 47017, -47041, 47051, 47057, 47059, 47087, 47093, 47111, 47119, 47123, 47129, 47137, -47143, 47147, 47149, 47161, 47189, 47207, 47221, 47237, 47251, 47269, 47279, -47287, 47293, 47297, 47303, 47309, 47317, 47339, 47351, 47353, 47363, 47381, -47387, 47389, 47407, 47417, 47419, 47431, 47441, 47459, 47491, 47497, 47501, -47507, 47513, 47521, 47527, 47533, 47543, 47563, 47569, 47581, 47591, 47599, -47609, 47623, 47629, 47639, 47653, 47657, 47659, 47681, 47699, 47701, 47711, -47713, 47717, 47737, 47741, 47743, 47777, 47779, 47791, 47797, 47807, 47809, -47819, 47837, 47843, 47857, 47869, 47881, 47903, 47911, 47917, 47933, 47939, -47947, 47951, 47963, 47969, 47977, 47981, 48017, 48023, 48029, 48049, 48073, -48079, 48091, 48109, 48119, 48121, 48131, 48157, 48163, 48179, 48187, 48193, -48197, 48221, 48239, 48247, 48259, 48271, 48281, 48299, 48311, 48313, 48337, -48341, 48353, 48371, 48383, 48397, 48407, 48409, 48413, 48437, 48449, 48463, -48473, 48479, 48481, 48487, 48491, 48497, 48523, 48527, 48533, 48539, 48541, -48563, 48571, 48589, 48593, 48611, 48619, 48623, 48647, 48649, 48661, 48673, -48677, 48679, 48731, 48733, 48751, 48757, 48761, 48767, 48779, 48781, 48787, -48799, 48809, 48817, 48821, 48823, 48847, 48857, 48859, 48869, 48871, 48883, -48889, 48907, 48947, 48953, 48973, 48989, 48991, 49003, 49009, 49019, 49031, -49033, 49037, 49043, 49057, 49069, 49081, 49103, 49109, 49117, 49121, 49123, -49139, 49157, 49169, 49171, 49177, 49193, 49199, 49201, 49207, 49211, 49223, -49253, 49261, 49277, 49279, 49297, 49307, 49331, 49333, 49339, 49363, 49367, -49369, 49391, 49393, 49409, 49411, 49417, 49429, 49433, 49451, 49459, 49463, -49477, 49481, 49499, 49523, 49529, 49531, 49537, 49547, 49549, 49559, 49597, -49603, 49613, 49627, 49633, 49639, 49663, 49667, 49669, 49681, 49697, 49711, -49727, 49739, 49741, 49747, 49757, 49783, 49787, 49789, 49801, 49807, 49811, -49823, 49831, 49843, 49853, 49871, 49877, 49891, 49919, 49921, 49927, 49937, -49939, 49943, 49957, 49991, 49993, 49999, 50021, 50023, 50033, 50047, 50051, -50053, 50069, 50077, 50087, 50093, 50101, 50111, 50119, 50123, 50129, 50131, -50147, 50153, 50159, 50177, 50207, 50221, 50227, 50231, 50261, 50263, 50273, -50287, 50291, 50311, 50321, 50329, 50333, 50341, 50359, 50363, 50377, 50383, -50387, 50411, 50417, 50423, 50441, 50459, 50461, 50497, 50503, 50513, 50527, -50539, 50543, 50549, 50551, 50581, 50587, 50591, 50593, 50599, 50627, 50647, -50651, 50671, 50683, 50707, 50723, 50741, 50753, 50767, 50773, 50777, 50789, -50821, 50833, 50839, 50849, 50857, 50867, 50873, 50891, 50893, 50909, 50923, -50929, 50951, 50957, 50969, 50971, 50989, 50993, 51001, 51031, 51043, 51047, -51059, 51061, 51071, 51109, 51131, 51133, 51137, 51151, 51157, 51169, 51193, -51197, 51199, 51203, 51217, 51229, 51239, 51241, 51257, 51263, 51283, 51287, -51307, 51329, 51341, 51343, 51347, 51349, 51361, 51383, 51407, 51413, 51419, -51421, 51427, 51431, 51437, 51439, 51449, 51461, 51473, 51479, 51481, 51487, -51503, 51511, 51517, 51521, 51539, 51551, 51563, 51577, 51581, 51593, 51599, -51607, 51613, 51631, 51637, 51647, 51659, 51673, 51679, 51683, 51691, 51713, -51719, 51721, 51749, 51767, 51769, 51787, 51797, 51803, 51817, 51827, 51829, -51839, 51853, 51859, 51869, 51871, 51893, 51899, 51907, 51913, 51929, 51941, -51949, 51971, 51973, 51977, 51991, 52009, 52021, 52027, 52051, 52057, 52067, -52069, 52081, 52103, 52121, 52127, 52147, 52153, 52163, 52177, 52181, 52183, -52189, 52201, 52223, 52237, 52249, 52253, 52259, 52267, 52289, 52291, 52301, -52313, 52321, 52361, 52363, 52369, 52379, 52387, 52391, 52433, 52453, 52457, -52489, 52501, 52511, 52517, 52529, 52541, 52543, 52553, 52561, 52567, 52571, -52579, 52583, 52609, 52627, 52631, 52639, 52667, 52673, 52691, 52697, 52709, -52711, 52721, 52727, 52733, 52747, 52757, 52769, 52783, 52807, 52813, 52817, -52837, 52859, 52861, 52879, 52883, 52889, 52901, 52903, 52919, 52937, 52951, -52957, 52963, 52967, 52973, 52981, 52999, 53003, 53017, 53047, 53051, 53069, -53077, 53087, 53089, 53093, 53101, 53113, 53117, 53129, 53147, 53149, 53161, -53171, 53173, 53189, 53197, 53201, 53231, 53233, 53239, 53267, 53269, 53279, -53281, 53299, 53309, 53323, 53327, 53353, 53359, 53377, 53381, 53401, 53407, -53411, 53419, 53437, 53441, 53453, 53479, 53503, 53507, 53527, 53549, 53551, -53569, 53591, 53593, 53597, 53609, 53611, 53617, 53623, 53629, 53633, 53639, -53653, 53657, 53681, 53693, 53699, 53717, 53719, 53731, 53759, 53773, 53777, -53783, 53791, 53813, 53819, 53831, 53849, 53857, 53861, 53881, 53887, 53891, -53897, 53899, 53917, 53923, 53927, 53939, 53951, 53959, 53987, 53993, 54001, -54011, 54013, 54037, 54049, 54059, 54083, 54091, 54101, 54121, 54133, 54139, -54151, 54163, 54167, 54181, 54193, 54217, 54251, 54269, 54277, 54287, 54293, -54311, 54319, 54323, 54331, 54347, 54361, 54367, 54371, 54377, 54401, 54403, -54409, 54413, 54419, 54421, 54437, 54443, 54449, 54469, 54493, 54497, 54499, -54503, 54517, 54521, 54539, 54541, 54547, 54559, 54563, 54577, 54581, 54583, -54601, 54617, 54623, 54629, 54631, 54647, 54667, 54673, 54679, 54709, 54713, -54721, 54727, 54751, 54767, 54773, 54779, 54787, 54799, 54829, 54833, 54851, -54869, 54877, 54881, 54907, 54917, 54919, 54941, 54949, 54959, 54973, 54979, -54983, 55001, 55009, 55021, 55049, 55051, 55057, 55061, 55073, 55079, 55103, -55109, 55117, 55127, 55147, 55163, 55171, 55201, 55207, 55213, 55217, 55219, -55229, 55243, 55249, 55259, 55291, 55313, 55331, 55333, 55337, 55339, 55343, -55351, 55373, 55381, 55399, 55411, 55439, 55441, 55457, 55469, 55487, 55501, -55511, 55529, 55541, 55547, 55579, 55589, 55603, 55609, 55619, 55621, 55631, -55633, 55639, 55661, 55663, 55667, 55673, 55681, 55691, 55697, 55711, 55717, -55721, 55733, 55763, 55787, 55793, 55799, 55807, 55813, 55817, 55819, 55823, -55829, 55837, 55843, 55849, 55871, 55889, 55897, 55901, 55903, 55921, 55927, -55931, 55933, 55949, 55967, 55987, 55997, 56003, 56009, 56039, 56041, 56053, -56081, 56087, 56093, 56099, 56101, 56113, 56123, 56131, 56149, 56167, 56171, -56179, 56197, 56207, 56209, 56237, 56239, 56249, 56263, 56267, 56269, 56299, -56311, 56333, 56359, 56369, 56377, 56383, 56393, 56401, 56417, 56431, 56437, -56443, 56453, 56467, 56473, 56477, 56479, 56489, 56501, 56503, 56509, 56519, -56527, 56531, 56533, 56543, 56569, 56591, 56597, 56599, 56611, 56629, 56633, -56659, 56663, 56671, 56681, 56687, 56701, 56711, 56713, 56731, 56737, 56747, -56767, 56773, 56779, 56783, 56807, 56809, 56813, 56821, 56827, 56843, 56857, -56873, 56891, 56893, 56897, 56909, 56911, 56921, 56923, 56929, 56941, 56951, -56957, 56963, 56983, 56989, 56993, 56999, 57037, 57041, 57047, 57059, 57073, -57077, 57089, 57097, 57107, 57119, 57131, 57139, 57143, 57149, 57163, 57173, -57179, 57191, 57193, 57203, 57221, 57223, 57241, 57251, 57259, 57269, 57271, -57283, 57287, 57301, 57329, 57331, 57347, 57349, 57367, 57373, 57383, 57389, -57397, 57413, 57427, 57457, 57467, 57487, 57493, 57503, 57527, 57529, 57557, -57559, 57571, 57587, 57593, 57601, 57637, 57641, 57649, 57653, 57667, 57679, -57689, 57697, 57709, 57713, 57719, 57727, 57731, 57737, 57751, 57773, 57781, -57787, 57791, 57793, 57803, 57809, 57829, 57839, 57847, 57853, 57859, 57881, -57899, 57901, 57917, 57923, 57943, 57947, 57973, 57977, 57991, 58013, 58027, -58031, 58043, 58049, 58057, 58061, 58067, 58073, 58099, 58109, 58111, 58129, -58147, 58151, 58153, 58169, 58171, 58189, 58193, 58199, 58207, 58211, 58217, -58229, 58231, 58237, 58243, 58271, 58309, 58313, 58321, 58337, 58363, 58367, -58369, 58379, 58391, 58393, 58403, 58411, 58417, 58427, 58439, 58441, 58451, -58453, 58477, 58481, 58511, 58537, 58543, 58549, 58567, 58573, 58579, 58601, -58603, 58613, 58631, 58657, 58661, 58679, 58687, 58693, 58699, 58711, 58727, -58733, 58741, 58757, 58763, 58771, 58787, 58789, 58831, 58889, 58897, 58901, -58907, 58909, 58913, 58921, 58937, 58943, 58963, 58967, 58979, 58991, 58997, -59009, 59011, 59021, 59023, 59029, 59051, 59053, 59063, 59069, 59077, 59083, -59093, 59107, 59113, 59119, 59123, 59141, 59149, 59159, 59167, 59183, 59197, -59207, 59209, 59219, 59221, 59233, 59239, 59243, 59263, 59273, 59281, 59333, -59341, 59351, 59357, 59359, 59369, 59377, 59387, 59393, 59399, 59407, 59417, -59419, 59441, 59443, 59447, 59453, 59467, 59471, 59473, 59497, 59509, 59513, -59539, 59557, 59561, 59567, 59581, 59611, 59617, 59621, 59627, 59629, 59651, -59659, 59663, 59669, 59671, 59693, 59699, 59707, 59723, 59729, 59743, 59747, -59753, 59771, 59779, 59791, 59797, 59809, 59833, 59863, 59879, 59887, 59921, -59929, 59951, 59957, 59971, 59981, 59999, 60013, 60017, 60029, 60037, 60041, -60077, 60083, 60089, 60091, 60101, 60103, 60107, 60127, 60133, 60139, 60149, -60161, 60167, 60169, 60209, 60217, 60223, 60251, 60257, 60259, 60271, 60289, -60293, 60317, 60331, 60337, 60343, 60353, 60373, 60383, 60397, 60413, 60427, -60443, 60449, 60457, 60493, 60497, 60509, 60521, 60527, 60539, 60589, 60601, -60607, 60611, 60617, 60623, 60631, 60637, 60647, 60649, 60659, 60661, 60679, -60689, 60703, 60719, 60727, 60733, 60737, 60757, 60761, 60763, 60773, 60779, -60793, 60811, 60821, 60859, 60869, 60887, 60889, 60899, 60901, 60913, 60917, -60919, 60923, 60937, 60943, 60953, 60961, 61001, 61007, 61027, 61031, 61043, -61051, 61057, 61091, 61099, 61121, 61129, 61141, 61151, 61153, 61169, 61211, -61223, 61231, 61253, 61261, 61283, 61291, 61297, 61331, 61333, 61339, 61343, -61357, 61363, 61379, 61381, 61403, 61409, 61417, 61441, 61463, 61469, 61471, -61483, 61487, 61493, 61507, 61511, 61519, 61543, 61547, 61553, 61559, 61561, -61583, 61603, 61609, 61613, 61627, 61631, 61637, 61643, 61651, 61657, 61667, -61673, 61681, 61687, 61703, 61717, 61723, 61729, 61751, 61757, 61781, 61813, -61819, 61837, 61843, 61861, 61871, 61879, 61909, 61927, 61933, 61949, 61961, -61967, 61979, 61981, 61987, 61991, 62003, 62011, 62017, 62039, 62047, 62053, -62057, 62071, 62081, 62099, 62119, 62129, 62131, 62137, 62141, 62143, 62171, -62189, 62191, 62201, 62207, 62213, 62219, 62233, 62273, 62297, 62299, 62303, -62311, 62323, 62327, 62347, 62351, 62383, 62401, 62417, 62423, 62459, 62467, -62473, 62477, 62483, 62497, 62501, 62507, 62533, 62539, 62549, 62563, 62581, -62591, 62597, 62603, 62617, 62627, 62633, 62639, 62653, 62659, 62683, 62687, -62701, 62723, 62731, 62743, 62753, 62761, 62773, 62791, 62801, 62819, 62827, -62851, 62861, 62869, 62873, 62897, 62903, 62921, 62927, 62929, 62939, 62969, -62971, 62981, 62983, 62987, 62989, 63029, 63031, 63059, 63067, 63073, 63079, -63097, 63103, 63113, 63127, 63131, 63149, 63179, 63197, 63199, 63211, 63241, -63247, 63277, 63281, 63299, 63311, 63313, 63317, 63331, 63337, 63347, 63353, -63361, 63367, 63377, 63389, 63391, 63397, 63409, 63419, 63421, 63439, 63443, -63463, 63467, 63473, 63487, 63493, 63499, 63521, 63527, 63533, 63541, 63559, -63577, 63587, 63589, 63599, 63601, 63607, 63611, 63617, 63629, 63647, 63649, -63659, 63667, 63671, 63689, 63691, 63697, 63703, 63709, 63719, 63727, 63737, -63743, 63761, 63773, 63781, 63793, 63799, 63803, 63809, 63823, 63839, 63841, -63853, 63857, 63863, 63901, 63907, 63913, 63929, 63949, 63977, 63997, 64007, -64013, 64019, 64033, 64037, 64063, 64067, 64081, 64091, 64109, 64123, 64151, -64153, 64157, 64171, 64187, 64189, 64217, 64223, 64231, 64237, 64271, 64279, -64283, 64301, 64303, 64319, 64327, 64333, 64373, 64381, 64399, 64403, 64433, -64439, 64451, 64453, 64483, 64489, 64499, 64513, 64553, 64567, 64577, 64579, -64591, 64601, 64609, 64613, 64621, 64627, 64633, 64661, 64663, 64667, 64679, -64693, 64709, 64717, 64747, 64763, 64781, 64783, 64793, 64811, 64817, 64849, -64853, 64871, 64877, 64879, 64891, 64901, 64919, 64921, 64927, 64937, 64951, -64969, 64997, 65003, 65011, 65027, 65029, 65033, 65053, 65063, 65071, 65089, -65099, 65101, 65111, 65119, 65123, 65129, 65141, 65147, 65167, 65171, 65173, -65179, 65183, 65203, 65213, 65239, 65257, 65267, 65269, 65287, 65293, 65309, -65323, 65327, 65353, 65357, 65371, 65381, 65393, 65407, 65413, 65419, 65423, -65437, 65447, 65449, 65479, 65497, 65519, 65521, 0 }; - -} -/* -* Modular Reducer -* (C) 1999-2011 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -/* -* Modular_Reducer Constructor -*/ -Modular_Reducer::Modular_Reducer(const BigInt& mod) - { - if(mod <= 0) - throw Invalid_Argument("Modular_Reducer: modulus must be positive"); - - modulus = mod; - mod_words = modulus.sig_words(); - - modulus_2 = Botan::square(modulus); - - mu = BigInt(BigInt::Power2, 2 * MP_WORD_BITS * mod_words) / modulus; - } - -/* -* Barrett Reduction -*/ -BigInt Modular_Reducer::reduce(const BigInt& x) const - { - if(mod_words == 0) - throw Invalid_State("Modular_Reducer: Never initalized"); - - if(x.cmp(modulus, false) < 0) - { - if(x.is_negative()) - return x + modulus; // make positive - return x; - } - else if(x.cmp(modulus_2, false) < 0) - { - BigInt t1 = x; - t1.set_sign(BigInt::Positive); - t1 >>= (MP_WORD_BITS * (mod_words - 1)); - t1 *= mu; - - t1 >>= (MP_WORD_BITS * (mod_words + 1)); - t1 *= modulus; - - t1.mask_bits(MP_WORD_BITS * (mod_words + 1)); - - BigInt t2 = x; - t2.set_sign(BigInt::Positive); - t2.mask_bits(MP_WORD_BITS * (mod_words + 1)); - - t2 -= t1; - - if(t2.is_negative()) - { - BigInt b_to_k1(BigInt::Power2, MP_WORD_BITS * (mod_words + 1)); - t2 += b_to_k1; - } - - while(t2 >= modulus) - t2 -= modulus; - - if(x.is_positive()) - return t2; - else - return (modulus - t2); - } - else - { - // too big, fall back to normal division - return (x % modulus); - } - } - -} -/* -* Shanks-Tonnelli (RESSOL) -* (C) 2007-2008 Falko Strenzke, FlexSecure GmbH -* (C) 2008 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -/* -* Shanks-Tonnelli algorithm -*/ -BigInt ressol(const BigInt& a, const BigInt& p) - { - if(a < 0) - throw Invalid_Argument("ressol(): a to solve for must be positive"); - if(p <= 1) - throw Invalid_Argument("ressol(): prime must be > 1"); - - if(a == 0) - return 0; - if(p == 2) - return a; - - if(jacobi(a, p) != 1) // not a quadratic residue - return -BigInt(1); - - if(p % 4 == 3) - return power_mod(a, ((p+1) >> 2), p); - - size_t s = low_zero_bits(p - 1); - BigInt q = p >> s; - - q -= 1; - q >>= 1; - - Modular_Reducer mod_p(p); - - BigInt r = power_mod(a, q, p); - BigInt n = mod_p.multiply(a, mod_p.square(r)); - r = mod_p.multiply(r, a); - - if(n == 1) - return r; - - // find random non quadratic residue z - BigInt z = 2; - while(jacobi(z, p) == 1) // while z quadratic residue - ++z; - - BigInt c = power_mod(z, (q << 1) + 1, p); - - while(n > 1) - { - q = n; - - size_t i = 0; - while(q != 1) - { - q = mod_p.square(q); - ++i; - } - - if(s <= i) - return -BigInt(1); - - c = power_mod(c, BigInt(BigInt::Power2, s-i-1), p); - r = mod_p.multiply(r, c); - c = mod_p.square(c); - n = mod_p.multiply(n, c); - s = i; - } - - return r; - } - -} -/* -* No-Op Mutex Factory -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -/* -* No-Op Mutex Factory -*/ -Mutex* Noop_Mutex_Factory::make() - { - class Noop_Mutex : public Mutex - { - public: - class Mutex_State_Error : public Internal_Error - { - public: - Mutex_State_Error(const std::string& where) : - Internal_Error("Noop_Mutex::" + where + ": " + - "Mutex is already " + where + "ed") {} - }; - - void lock() - { - if(locked) - throw Mutex_State_Error("lock"); - locked = true; - } - - void unlock() - { - if(!locked) - throw Mutex_State_Error("unlock"); - locked = false; - } - - Noop_Mutex() { locked = false; } - private: - bool locked; - }; - - return new Noop_Mutex; - } - -} - -#ifdef Q_OS_WIN -/* -* Win32 Mutex -* (C) 2006 Luca Piccarreta -* 2006-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include - -namespace Botan { - -/* -* Win32 Mutex Factory -*/ -Mutex* Win32_Mutex_Factory::make() - { - class Win32_Mutex : public Mutex - { - public: - void lock() { EnterCriticalSection(&mutex); } - void unlock() { LeaveCriticalSection(&mutex); } - - Win32_Mutex() { InitializeCriticalSection(&mutex); } - ~Win32_Mutex() { DeleteCriticalSection(&mutex); } - private: - CRITICAL_SECTION mutex; - }; - - return new Win32_Mutex(); - } - -} -#endif - -#ifdef Q_OS_UNIX -/* -* Pthread Mutex -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -#ifndef _POSIX_C_SOURCE - #define _POSIX_C_SOURCE 199506 -#endif - -#include - -namespace Botan { - -/* -* Pthread Mutex Factory -*/ -Mutex* Pthread_Mutex_Factory::make() - { - - class Pthread_Mutex : public Mutex - { - public: - void lock() - { - if(pthread_mutex_lock(&mutex) != 0) - throw Invalid_State("Pthread_Mutex::lock: Error occured"); - } - - void unlock() - { - if(pthread_mutex_unlock(&mutex) != 0) - throw Invalid_State("Pthread_Mutex::unlock: Error occured"); - } - - Pthread_Mutex() - { - if(pthread_mutex_init(&mutex, 0) != 0) - throw Invalid_State("Pthread_Mutex: initialization failed"); - } - - ~Pthread_Mutex() - { - if(pthread_mutex_destroy(&mutex) != 0) - throw Invalid_State("~Pthread_Mutex: mutex is still locked"); - } - private: - pthread_mutex_t mutex; - }; - - return new Pthread_Mutex(); - } - -} -#endif - -/* -* Bcrypt Password Hashing -* (C) 2010 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -namespace { - -std::string bcrypt_base64_encode(const byte input[], size_t length) - { - // Bcrypt uses a non-standard base64 alphabet - const byte OPENBSD_BASE64_SUB[256] = { - 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x38, 0x80, 0x80, 0x80, 0x39, - 0x79, 0x7A, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x2E, 0x2F, 0x41, 0x42, 0x43, 0x44, 0x45, - 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, - 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x59, 0x5A, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, - 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, - 0x76, 0x77, 0x78, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80 - }; - - std::string b64 = base64_encode(input, length); - - while(b64.size() && b64[b64.size()-1] == '=') - b64 = b64.substr(0, b64.size() - 1); - - for(size_t i = 0; i != b64.size(); ++i) - b64[i] = OPENBSD_BASE64_SUB[static_cast(b64[i])]; - - return b64; - } - -MemoryVector bcrypt_base64_decode(std::string input) - { - const byte OPENBSD_BASE64_SUB[256] = { - 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x41, 0x42, - 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2B, 0x2F, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, - 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, - 0x56, 0x57, 0x58, 0x59, 0x5A, 0x61, 0x62, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, - 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, - 0x7A, 0x30, 0x31, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80 - }; - - for(size_t i = 0; i != input.size(); ++i) - input[i] = OPENBSD_BASE64_SUB[static_cast(input[i])]; - - return base64_decode(input); - } - -std::string make_bcrypt(const std::string& pass, - const MemoryRegion& salt, - u16bit work_factor) - { - const byte magic[24] = { - 0x4F, 0x72, 0x70, 0x68, 0x65, 0x61, 0x6E, 0x42, - 0x65, 0x68, 0x6F, 0x6C, 0x64, 0x65, 0x72, 0x53, - 0x63, 0x72, 0x79, 0x44, 0x6F, 0x75, 0x62, 0x74 - }; - - MemoryVector ctext(magic, 24); - - Blowfish blowfish; - - // Include the trailing NULL byte - blowfish.eks_key_schedule(reinterpret_cast(pass.c_str()), - pass.length() + 1, - salt, - work_factor); - - for(size_t i = 0; i != 64; ++i) - blowfish.encrypt_n(&ctext[0], &ctext[0], 3); - - std::string salt_b64 = bcrypt_base64_encode(&salt[0], salt.size()); - - return "$2a$" + to_string(work_factor, 2) + "$" + salt_b64.substr(0, 22) + - bcrypt_base64_encode(&ctext[0], ctext.size() - 1); - } - -} - -std::string generate_bcrypt(const std::string& pass, - RandomNumberGenerator& rng, - u16bit work_factor) - { - return make_bcrypt(pass, rng.random_vec(16), work_factor); - } - -bool check_bcrypt(const std::string& pass, const std::string& hash) - { - if(hash.size() != 60 || - hash[0] != '$' || hash[1] != '2' || hash[2] != 'a' || - hash[3] != '$' || hash[6] != '$') - { - return false; - } - - const u16bit workfactor = to_u32bit(hash.substr(4, 2)); - - MemoryVector salt = bcrypt_base64_decode(hash.substr(7, 22)); - - const std::string compare = make_bcrypt(pass, salt, workfactor); - - return (hash == compare); - } - -} -/* -* Passhash9 Password Hashing -* (C) 2010 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -namespace { - -const std::string MAGIC_PREFIX = "$9$"; - -const size_t WORKFACTOR_BYTES = 2; -const size_t ALGID_BYTES = 1; -const size_t SALT_BYTES = 12; // 96 bits of salt -const size_t PASSHASH9_PBKDF_OUTPUT_LEN = 24; // 192 bits output - -const size_t WORK_FACTOR_SCALE = 10000; - -MessageAuthenticationCode* get_pbkdf_prf(byte alg_id) - { - Algorithm_Factory& af = global_state().algorithm_factory(); - - try - { - if(alg_id == 0) - return af.make_mac("HMAC(SHA-1)"); - else if(alg_id == 1) - return af.make_mac("HMAC(SHA-256)"); - else if(alg_id == 2) - return af.make_mac("CMAC(Blowfish)"); - } - catch(Algorithm_Not_Found) {} - - return 0; - } - -} - -std::string generate_passhash9(const std::string& pass, - RandomNumberGenerator& rng, - u16bit work_factor, - byte alg_id) - { - MessageAuthenticationCode* prf = get_pbkdf_prf(alg_id); - - if(!prf) - throw Invalid_Argument("Passhash9: Algorithm id " + to_string(alg_id) + - " is not defined"); - - PKCS5_PBKDF2 kdf(prf); // takes ownership of pointer - - SecureVector salt(SALT_BYTES); - rng.randomize(&salt[0], salt.size()); - - const size_t kdf_iterations = WORK_FACTOR_SCALE * work_factor; - - SecureVector pbkdf2_output = - kdf.derive_key(PASSHASH9_PBKDF_OUTPUT_LEN, - pass, - &salt[0], salt.size(), - kdf_iterations).bits_of(); - - Pipe pipe(new Base64_Encoder); - pipe.start_msg(); - pipe.write(alg_id); - pipe.write(get_byte(0, work_factor)); - pipe.write(get_byte(1, work_factor)); - pipe.write(salt); - pipe.write(pbkdf2_output); - pipe.end_msg(); - - return MAGIC_PREFIX + pipe.read_all_as_string(); - } - -bool check_passhash9(const std::string& pass, const std::string& hash) - { - const size_t BINARY_LENGTH = - ALGID_BYTES + - WORKFACTOR_BYTES + - PASSHASH9_PBKDF_OUTPUT_LEN + - SALT_BYTES; - - const size_t BASE64_LENGTH = - MAGIC_PREFIX.size() + (BINARY_LENGTH * 8) / 6; - - if(hash.size() != BASE64_LENGTH) - return false; - - for(size_t i = 0; i != MAGIC_PREFIX.size(); ++i) - if(hash[i] != MAGIC_PREFIX[i]) - return false; - - Pipe pipe(new Base64_Decoder); - pipe.start_msg(); - pipe.write(hash.c_str() + MAGIC_PREFIX.size()); - pipe.end_msg(); - - SecureVector bin = pipe.read_all(); - - if(bin.size() != BINARY_LENGTH) - return false; - - byte alg_id = bin[0]; - - const size_t kdf_iterations = - WORK_FACTOR_SCALE * load_be(&bin[ALGID_BYTES], 0); - - if(kdf_iterations == 0) - return false; - - MessageAuthenticationCode* pbkdf_prf = get_pbkdf_prf(alg_id); - - if(pbkdf_prf == 0) - return false; // unknown algorithm, reject - - PKCS5_PBKDF2 kdf(pbkdf_prf); // takes ownership of pointer - - SecureVector cmp = kdf.derive_key( - PASSHASH9_PBKDF_OUTPUT_LEN, - pass, - &bin[ALGID_BYTES + WORKFACTOR_BYTES], SALT_BYTES, - kdf_iterations).bits_of(); - - return same_mem(&cmp[0], - &bin[ALGID_BYTES + WORKFACTOR_BYTES + SALT_BYTES], - PASSHASH9_PBKDF_OUTPUT_LEN); - } - -} -/* -* PBE Retrieval -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -#if defined(BOTAN_HAS_PBE_PKCS_V15) -#endif - -#if defined(BOTAN_HAS_PBE_PKCS_V20) -#endif - -namespace Botan { - -/* -* Get an encryption PBE, set new parameters -*/ -PBE* get_pbe(const std::string& algo_spec) - { - SCAN_Name request(algo_spec); - - const std::string pbe = request.algo_name(); - std::string digest_name = request.arg(0); - const std::string cipher = request.arg(1); - - std::vector cipher_spec = split_on(cipher, '/'); - if(cipher_spec.size() != 2) - throw Invalid_Argument("PBE: Invalid cipher spec " + cipher); - - const std::string cipher_algo = global_state().deref_alias(cipher_spec[0]); - const std::string cipher_mode = cipher_spec[1]; - - if(cipher_mode != "CBC") - throw Invalid_Argument("PBE: Invalid cipher mode " + cipher); - - Algorithm_Factory& af = global_state().algorithm_factory(); - - const BlockCipher* block_cipher = af.prototype_block_cipher(cipher_algo); - if(!block_cipher) - throw Algorithm_Not_Found(cipher_algo); - - const HashFunction* hash_function = af.prototype_hash_function(digest_name); - if(!hash_function) - throw Algorithm_Not_Found(digest_name); - - if(request.arg_count() != 2) - throw Invalid_Algorithm_Name(algo_spec); - -#if defined(BOTAN_HAS_PBE_PKCS_V15) - if(pbe == "PBE-PKCS5v15") - return new PBE_PKCS5v15(block_cipher->clone(), - hash_function->clone(), - ENCRYPTION); -#endif - -#if defined(BOTAN_HAS_PBE_PKCS_V20) - if(pbe == "PBE-PKCS5v20") - return new PBE_PKCS5v20(block_cipher->clone(), - hash_function->clone()); -#endif - - throw Algorithm_Not_Found(algo_spec); - } - -/* -* Get a decryption PBE, decode parameters -*/ -PBE* get_pbe(const OID& pbe_oid, DataSource& params) - { - SCAN_Name request(OIDS::lookup(pbe_oid)); - - const std::string pbe = request.algo_name(); - -#if defined(BOTAN_HAS_PBE_PKCS_V15) - if(pbe == "PBE-PKCS5v15") - { - if(request.arg_count() != 2) - throw Invalid_Algorithm_Name(request.as_string()); - - std::string digest_name = request.arg(0); - const std::string cipher = request.arg(1); - - std::vector cipher_spec = split_on(cipher, '/'); - if(cipher_spec.size() != 2) - throw Invalid_Argument("PBE: Invalid cipher spec " + cipher); - - const std::string cipher_algo = global_state().deref_alias(cipher_spec[0]); - const std::string cipher_mode = cipher_spec[1]; - - if(cipher_mode != "CBC") - throw Invalid_Argument("PBE: Invalid cipher mode " + cipher); - - Algorithm_Factory& af = global_state().algorithm_factory(); - - const BlockCipher* block_cipher = af.prototype_block_cipher(cipher_algo); - if(!block_cipher) - throw Algorithm_Not_Found(cipher_algo); - - const HashFunction* hash_function = - af.prototype_hash_function(digest_name); - - if(!hash_function) - throw Algorithm_Not_Found(digest_name); - - PBE* pbe = new PBE_PKCS5v15(block_cipher->clone(), - hash_function->clone(), - DECRYPTION); - pbe->decode_params(params); - return pbe; - } -#endif - -#if defined(BOTAN_HAS_PBE_PKCS_V20) - if(pbe == "PBE-PKCS5v20") - return new PBE_PKCS5v20(params); -#endif - - throw Algorithm_Not_Found(pbe_oid.as_string()); - } - -} -/* -* PKCS #5 PBES1 -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include - -namespace Botan { - -/* -* Encrypt some bytes using PBES1 -*/ -void PBE_PKCS5v15::write(const byte input[], size_t length) - { - pipe.write(input, length); - flush_pipe(true); - } - -/* -* Start encrypting with PBES1 -*/ -void PBE_PKCS5v15::start_msg() - { - if(direction == ENCRYPTION) - pipe.append(new CBC_Encryption(block_cipher->clone(), - new PKCS7_Padding, - key, iv)); - else - pipe.append(new CBC_Decryption(block_cipher->clone(), - new PKCS7_Padding, - key, iv)); - - pipe.start_msg(); - if(pipe.message_count() > 1) - pipe.set_default_msg(pipe.default_msg() + 1); - } - -/* -* Finish encrypting with PBES1 -*/ -void PBE_PKCS5v15::end_msg() - { - pipe.end_msg(); - flush_pipe(false); - pipe.reset(); - } - -/* -* Flush the pipe -*/ -void PBE_PKCS5v15::flush_pipe(bool safe_to_skip) - { - if(safe_to_skip && pipe.remaining() < 64) - return; - - SecureVector buffer(DEFAULT_BUFFERSIZE); - while(pipe.remaining()) - { - size_t got = pipe.read(&buffer[0], buffer.size()); - send(buffer, got); - } - } - -/* -* Set the passphrase to use -*/ -void PBE_PKCS5v15::set_key(const std::string& passphrase) - { - PKCS5_PBKDF1 pbkdf(hash_function->clone()); - - SecureVector key_and_iv = pbkdf.derive_key(16, passphrase, - &salt[0], salt.size(), - iterations).bits_of(); - - key.resize(8); - iv.resize(8); - copy_mem(&key[0], &key_and_iv[0], 8); - copy_mem(&iv[0], &key_and_iv[8], 8); - } - -/* -* Create a new set of PBES1 parameters -*/ -void PBE_PKCS5v15::new_params(RandomNumberGenerator& rng) - { - iterations = 50000; - salt = rng.random_vec(8); - } - -/* -* Encode PKCS#5 PBES1 parameters -*/ -MemoryVector PBE_PKCS5v15::encode_params() const - { - return DER_Encoder() - .start_cons(SEQUENCE) - .encode(salt, OCTET_STRING) - .encode(iterations) - .end_cons() - .get_contents(); - } - -/* -* Decode PKCS#5 PBES1 parameters -*/ -void PBE_PKCS5v15::decode_params(DataSource& source) - { - BER_Decoder(source) - .start_cons(SEQUENCE) - .decode(salt, OCTET_STRING) - .decode(iterations) - .verify_end() - .end_cons(); - - if(salt.size() != 8) - throw Decoding_Error("PBES1: Encoded salt is not 8 octets"); - } - -/* -* Return an OID for this PBES1 type -*/ -OID PBE_PKCS5v15::get_oid() const - { - const OID base_pbes1_oid("1.2.840.113549.1.5"); - - const std::string cipher = block_cipher->name(); - const std::string digest = hash_function->name(); - - if(cipher == "DES" && digest == "MD2") - return (base_pbes1_oid + 1); - else if(cipher == "DES" && digest == "MD5") - return (base_pbes1_oid + 3); - else if(cipher == "DES" && digest == "SHA-160") - return (base_pbes1_oid + 10); - else if(cipher == "RC2" && digest == "MD2") - return (base_pbes1_oid + 4); - else if(cipher == "RC2" && digest == "MD5") - return (base_pbes1_oid + 6); - else if(cipher == "RC2" && digest == "SHA-160") - return (base_pbes1_oid + 11); - else - throw Internal_Error("PBE-PKCS5 v1.5: get_oid() has run out of options"); - } - -std::string PBE_PKCS5v15::name() const - { - return "PBE-PKCS5v15(" + block_cipher->name() + "," + - hash_function->name() + ")"; - } - -/* -* PKCS#5 v1.5 PBE Constructor -*/ -PBE_PKCS5v15::PBE_PKCS5v15(BlockCipher* cipher, - HashFunction* hash, - Cipher_Dir dir) : - direction(dir), block_cipher(cipher), hash_function(hash), iterations(0) - { - if(cipher->name() != "DES" && cipher->name() != "RC2") - { - throw Invalid_Argument("PBE_PKCS5v1.5: Unknown cipher " + - cipher->name()); - } - - if(hash->name() != "MD2" && hash->name() != "MD5" && - hash->name() != "SHA-160") - { - throw Invalid_Argument("PBE_PKCS5v1.5: Unknown hash " + - hash->name()); - } - } - -PBE_PKCS5v15::~PBE_PKCS5v15() - { - delete block_cipher; - delete hash_function; - } - -} -/* -* PKCS #5 PBES2 -* (C) 1999-2008 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include -#include - -namespace Botan { - -/* -* Encrypt some bytes using PBES2 -*/ -void PBE_PKCS5v20::write(const byte input[], size_t length) - { - pipe.write(input, length); - flush_pipe(true); - } - -/* -* Start encrypting with PBES2 -*/ -void PBE_PKCS5v20::start_msg() - { - if(direction == ENCRYPTION) - pipe.append(new CBC_Encryption(block_cipher->clone(), - new PKCS7_Padding, - key, iv)); - else - pipe.append(new CBC_Decryption(block_cipher->clone(), - new PKCS7_Padding, - key, iv)); - - pipe.start_msg(); - if(pipe.message_count() > 1) - pipe.set_default_msg(pipe.default_msg() + 1); - } - -/* -* Finish encrypting with PBES2 -*/ -void PBE_PKCS5v20::end_msg() - { - pipe.end_msg(); - flush_pipe(false); - pipe.reset(); - } - -/* -* Flush the pipe -*/ -void PBE_PKCS5v20::flush_pipe(bool safe_to_skip) - { - if(safe_to_skip && pipe.remaining() < 64) - return; - - SecureVector buffer(DEFAULT_BUFFERSIZE); - while(pipe.remaining()) - { - size_t got = pipe.read(&buffer[0], buffer.size()); - send(buffer, got); - } - } - -/* -* Set the passphrase to use -*/ -void PBE_PKCS5v20::set_key(const std::string& passphrase) - { - PKCS5_PBKDF2 pbkdf(new HMAC(hash_function->clone())); - - key = pbkdf.derive_key(key_length, passphrase, - &salt[0], salt.size(), - iterations).bits_of(); - } - -/* -* Create a new set of PBES2 parameters -*/ -void PBE_PKCS5v20::new_params(RandomNumberGenerator& rng) - { - iterations = 50000; - key_length = block_cipher->maximum_keylength(); - - salt = rng.random_vec(12); - iv = rng.random_vec(block_cipher->block_size()); - } - -/* -* Encode PKCS#5 PBES2 parameters -*/ -MemoryVector PBE_PKCS5v20::encode_params() const - { - return DER_Encoder() - .start_cons(SEQUENCE) - .encode( - AlgorithmIdentifier("PKCS5.PBKDF2", - DER_Encoder() - .start_cons(SEQUENCE) - .encode(salt, OCTET_STRING) - .encode(iterations) - .encode(key_length) - .end_cons() - .get_contents() - ) - ) - .encode( - AlgorithmIdentifier(block_cipher->name() + "/CBC", - DER_Encoder() - .encode(iv, OCTET_STRING) - .get_contents() - ) - ) - .end_cons() - .get_contents(); - } - -/* -* Decode PKCS#5 PBES2 parameters -*/ -void PBE_PKCS5v20::decode_params(DataSource& source) - { - AlgorithmIdentifier kdf_algo, enc_algo; - - BER_Decoder(source) - .start_cons(SEQUENCE) - .decode(kdf_algo) - .decode(enc_algo) - .verify_end() - .end_cons(); - - if(kdf_algo.oid == OIDS::lookup("PKCS5.PBKDF2")) - { - BER_Decoder(kdf_algo.parameters) - .start_cons(SEQUENCE) - .decode(salt, OCTET_STRING) - .decode(iterations) - .decode_optional(key_length, INTEGER, UNIVERSAL) - .verify_end() - .end_cons(); - } - else - throw Decoding_Error("PBE-PKCS5 v2.0: Unknown KDF algorithm " + - kdf_algo.oid.as_string()); - - Algorithm_Factory& af = global_state().algorithm_factory(); - - std::string cipher = OIDS::lookup(enc_algo.oid); - std::vector cipher_spec = split_on(cipher, '/'); - if(cipher_spec.size() != 2) - throw Decoding_Error("PBE-PKCS5 v2.0: Invalid cipher spec " + cipher); - - if(!known_cipher(cipher_spec[0]) || cipher_spec[1] != "CBC") - throw Decoding_Error("PBE-PKCS5 v2.0: Don't know param format for " + - cipher); - - BER_Decoder(enc_algo.parameters).decode(iv, OCTET_STRING).verify_end(); - - block_cipher = af.make_block_cipher(cipher_spec[0]); - hash_function = af.make_hash_function("SHA-160"); - - if(key_length == 0) - key_length = block_cipher->maximum_keylength(); - - if(salt.size() < 8) - throw Decoding_Error("PBE-PKCS5 v2.0: Encoded salt is too small"); - } - -/* -* Return an OID for PBES2 -*/ -OID PBE_PKCS5v20::get_oid() const - { - return OIDS::lookup("PBE-PKCS5v20"); - } - -/* -* Check if this is a known PBES2 cipher -*/ -bool PBE_PKCS5v20::known_cipher(const std::string& algo) - { - if(algo == "AES-128" || algo == "AES-192" || algo == "AES-256") - return true; - if(algo == "DES" || algo == "TripleDES") - return true; - return false; - } - -std::string PBE_PKCS5v20::name() const - { - return "PBE-PKCS5v20(" + block_cipher->name() + "," + - hash_function->name() + ")"; - } - -/* -* PKCS#5 v2.0 PBE Constructor -*/ -PBE_PKCS5v20::PBE_PKCS5v20(BlockCipher* cipher, - HashFunction* digest) : - direction(ENCRYPTION), - block_cipher(cipher), - hash_function(digest), - iterations(0), - key_length(0) - { - if(!known_cipher(block_cipher->name())) - throw Invalid_Argument("PBE-PKCS5 v2.0: Invalid cipher " + cipher->name()); - if(hash_function->name() != "SHA-160") - throw Invalid_Argument("PBE-PKCS5 v2.0: Invalid digest " + digest->name()); - } - -/* -* PKCS#5 v2.0 PBE Constructor -*/ -PBE_PKCS5v20::PBE_PKCS5v20(DataSource& params) : direction(DECRYPTION) - { - hash_function = 0; - block_cipher = 0; - decode_params(params); - } - -PBE_PKCS5v20::~PBE_PKCS5v20() - { - delete hash_function; - delete block_cipher; - } - -} -/* -* PBKDF1 -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -/* -* Return a PKCS#5 PBKDF1 derived key -*/ -OctetString PKCS5_PBKDF1::derive_key(size_t key_len, - const std::string& passphrase, - const byte salt[], size_t salt_size, - size_t iterations) const - { - if(iterations == 0) - throw Invalid_Argument("PKCS5_PBKDF1: Invalid iteration count"); - - if(key_len > hash->output_length()) - throw Invalid_Argument("PKCS5_PBKDF1: Requested output length too long"); - - hash->update(passphrase); - hash->update(salt, salt_size); - SecureVector key = hash->final(); - - for(size_t j = 1; j != iterations; ++j) - { - hash->update(key); - hash->final(&key[0]); - } - - return OctetString(&key[0], std::min(key_len, key.size())); - } - -} -/* -* PBKDF2 -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -/* -* Return a PKCS #5 PBKDF2 derived key -*/ -OctetString PKCS5_PBKDF2::derive_key(size_t key_len, - const std::string& passphrase, - const byte salt[], size_t salt_size, - size_t iterations) const - { - if(iterations == 0) - throw Invalid_Argument("PKCS#5 PBKDF2: Invalid iteration count"); - - try - { - mac->set_key(reinterpret_cast(passphrase.data()), - passphrase.length()); - } - catch(Invalid_Key_Length) - { - throw Exception(name() + " cannot accept passphrases of length " + - to_string(passphrase.length())); - } - - SecureVector key(key_len); - - byte* T = &key[0]; - - SecureVector U(mac->output_length()); - - u32bit counter = 1; - while(key_len) - { - size_t T_size = std::min(mac->output_length(), key_len); - - mac->update(salt, salt_size); - mac->update_be(counter); - mac->final(&U[0]); - - xor_buf(T, U, T_size); - - for(size_t j = 1; j != iterations; ++j) - { - mac->update(U); - mac->final(&U[0]); - xor_buf(T, U, T_size); - } - - key_len -= T_size; - T += T_size; - ++counter; - } - - return key; - } - -} -/* -* OpenPGP S2K -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -/* -* Derive a key using the OpenPGP S2K algorithm -*/ -OctetString OpenPGP_S2K::derive_key(size_t key_len, - const std::string& passphrase, - const byte salt_buf[], size_t salt_size, - size_t iterations) const - { - SecureVector key(key_len), hash_buf; - - size_t pass = 0, generated = 0, - total_size = passphrase.size() + salt_size; - size_t to_hash = std::max(iterations, total_size); - - hash->clear(); - while(key_len > generated) - { - for(size_t j = 0; j != pass; ++j) - hash->update(0); - - size_t left = to_hash; - while(left >= total_size) - { - hash->update(salt_buf, salt_size); - hash->update(passphrase); - left -= total_size; - } - if(left <= salt_size) - hash->update(salt_buf, left); - else - { - hash->update(salt_buf, salt_size); - left -= salt_size; - hash->update(reinterpret_cast(passphrase.data()), left); - } - - hash_buf = hash->final(); - key.copy(generated, &hash_buf[0], hash->output_length()); - generated += hash->output_length(); - ++pass; - } - - return key; - } - -} -/* -* EME Base Class -* (C) 1999-2008 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -/* -* Encode a message -*/ -SecureVector EME::encode(const byte msg[], size_t msg_len, - size_t key_bits, - RandomNumberGenerator& rng) const - { - return pad(msg, msg_len, key_bits, rng); - } - -/* -* Encode a message -*/ -SecureVector EME::encode(const MemoryRegion& msg, - size_t key_bits, - RandomNumberGenerator& rng) const - { - return pad(&msg[0], msg.size(), key_bits, rng); - } - -/* -* Decode a message -*/ -SecureVector EME::decode(const byte msg[], size_t msg_len, - size_t key_bits) const - { - return unpad(msg, msg_len, key_bits); - } - -/* -* Decode a message -*/ -SecureVector EME::decode(const MemoryRegion& msg, - size_t key_bits) const - { - return unpad(&msg[0], msg.size(), key_bits); - } - -} -/* -* EME1 (aka OAEP) -* (C) 1999-2010 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include - -namespace Botan { - -/* -* EME1 Pad Operation -*/ -SecureVector EME1::pad(const byte in[], size_t in_length, - size_t key_length, - RandomNumberGenerator& rng) const - { - key_length /= 8; - - if(in_length > key_length - 2*Phash.size() - 1) - throw Invalid_Argument("EME1: Input is too large"); - - SecureVector out(key_length); - - rng.randomize(&out[0], Phash.size()); - - out.copy(Phash.size(), &Phash[0], Phash.size()); - out[out.size() - in_length - 1] = 0x01; - out.copy(out.size() - in_length, in, in_length); - - mgf->mask(&out[0], Phash.size(), - &out[Phash.size()], out.size() - Phash.size()); - - mgf->mask(&out[Phash.size()], out.size() - Phash.size(), - &out[0], Phash.size()); - - return out; - } - -/* -* EME1 Unpad Operation -*/ -SecureVector EME1::unpad(const byte in[], size_t in_length, - size_t key_length) const - { - /* - Must be careful about error messages here; if an attacker can - distinguish them, it is easy to use the differences as an oracle to - find the secret key, as described in "A Chosen Ciphertext Attack on - RSA Optimal Asymmetric Encryption Padding (OAEP) as Standardized in - PKCS #1 v2.0", James Manger, Crypto 2001 - - Also have to be careful about timing attacks! Pointed out by Falko - Strenzke. - */ - - key_length /= 8; - - // Invalid input: truncate to zero length input, causing later - // checks to fail - if(in_length > key_length) - in_length = 0; - - SecureVector input(key_length); - input.copy(key_length - in_length, in, in_length); - - mgf->mask(&input[Phash.size()], input.size() - Phash.size(), - &input[0], Phash.size()); - mgf->mask(&input[0], Phash.size(), - &input[Phash.size()], input.size() - Phash.size()); - - bool waiting_for_delim = true; - bool bad_input = false; - size_t delim_idx = 2 * Phash.size(); - - /* - * GCC 4.5 on x86-64 compiles this in a way that is still vunerable - * to timing analysis. Other compilers, or GCC on other platforms, - * may or may not. - */ - for(size_t i = delim_idx; i != input.size(); ++i) - { - const bool zero_p = !input[i]; - const bool one_p = input[i] == 0x01; - - const bool add_1 = waiting_for_delim && zero_p; - - bad_input |= waiting_for_delim && !(zero_p || one_p); - - delim_idx += add_1; - - waiting_for_delim &= zero_p; - } - - // If we never saw any non-zero byte, then it's not valid input - bad_input |= waiting_for_delim; - - bad_input |= !same_mem(&input[Phash.size()], &Phash[0], Phash.size()); - - if(bad_input) - throw Decoding_Error("Invalid EME1 encoding"); - - return SecureVector(input + delim_idx + 1, - input.size() - delim_idx - 1); - } - -/* -* Return the max input size for a given key size -*/ -size_t EME1::maximum_input_size(size_t keybits) const - { - if(keybits / 8 > 2*Phash.size() + 1) - return ((keybits / 8) - 2*Phash.size() - 1); - else - return 0; - } - -/* -* EME1 Constructor -*/ -EME1::EME1(HashFunction* hash, const std::string& P) - { - Phash = hash->process(P); - mgf = new MGF1(hash); - } - -} -/* -* PKCS1 EME -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -/* -* PKCS1 Pad Operation -*/ -SecureVector EME_PKCS1v15::pad(const byte in[], size_t inlen, - size_t olen, - RandomNumberGenerator& rng) const - { - olen /= 8; - - if(olen < 10) - throw Encoding_Error("PKCS1: Output space too small"); - if(inlen > olen - 10) - throw Encoding_Error("PKCS1: Input is too large"); - - SecureVector out(olen); - - out[0] = 0x02; - for(size_t j = 1; j != olen - inlen - 1; ++j) - while(out[j] == 0) - out[j] = rng.next_byte(); - out.copy(olen - inlen, in, inlen); - - return out; - } - -/* -* PKCS1 Unpad Operation -*/ -SecureVector EME_PKCS1v15::unpad(const byte in[], size_t inlen, - size_t key_len) const - { - if(inlen != key_len / 8 || inlen < 10 || in[0] != 0x02) - throw Decoding_Error("PKCS1::unpad"); - - size_t seperator = 0; - for(size_t j = 0; j != inlen; ++j) - if(in[j] == 0) - { - seperator = j; - break; - } - if(seperator < 9) - throw Decoding_Error("PKCS1::unpad"); - - return SecureVector(in + seperator + 1, inlen - seperator - 1); - } - -/* -* Return the max input size for a given key size -*/ -size_t EME_PKCS1v15::maximum_input_size(size_t keybits) const - { - if(keybits / 8 > 10) - return ((keybits / 8) - 10); - else - return 0; - } - -} -/* -* EMSA1 -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -namespace { - -SecureVector emsa1_encoding(const MemoryRegion& msg, - size_t output_bits) - { - if(8*msg.size() <= output_bits) - return msg; - - size_t shift = 8*msg.size() - output_bits; - - size_t byte_shift = shift / 8, bit_shift = shift % 8; - SecureVector digest(msg.size() - byte_shift); - - for(size_t j = 0; j != msg.size() - byte_shift; ++j) - digest[j] = msg[j]; - - if(bit_shift) - { - byte carry = 0; - for(size_t j = 0; j != digest.size(); ++j) - { - byte temp = digest[j]; - digest[j] = (temp >> bit_shift) | carry; - carry = (temp << (8 - bit_shift)); - } - } - return digest; - } - -} - -/* -* EMSA1 Update Operation -*/ -void EMSA1::update(const byte input[], size_t length) - { - hash->update(input, length); - } - -/* -* Return the raw (unencoded) data -*/ -SecureVector EMSA1::raw_data() - { - return hash->final(); - } - -/* -* EMSA1 Encode Operation -*/ -SecureVector EMSA1::encoding_of(const MemoryRegion& msg, - size_t output_bits, - RandomNumberGenerator&) - { - if(msg.size() != hash->output_length()) - throw Encoding_Error("EMSA1::encoding_of: Invalid size for input"); - return emsa1_encoding(msg, output_bits); - } - -/* -* EMSA1 Decode/Verify Operation -*/ -bool EMSA1::verify(const MemoryRegion& coded, - const MemoryRegion& raw, size_t key_bits) - { - try { - if(raw.size() != hash->output_length()) - throw Encoding_Error("EMSA1::encoding_of: Invalid size for input"); - - SecureVector our_coding = emsa1_encoding(raw, key_bits); - - if(our_coding == coded) return true; - if(our_coding[0] != 0) return false; - if(our_coding.size() <= coded.size()) return false; - - size_t offset = 0; - while(our_coding[offset] == 0 && offset < our_coding.size()) - ++offset; - if(our_coding.size() - offset != coded.size()) - return false; - - for(size_t j = 0; j != coded.size(); ++j) - if(coded[j] != our_coding[j+offset]) - return false; - - return true; - } - catch(Invalid_Argument) - { - return false; - } - } - -} -/* -* EMSA1 BSI -* (C) 1999-2008 Jack Lloyd -* 2008 Falko Strenzke, FlexSecure GmbH -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -/* -* EMSA1 BSI Encode Operation -*/ -SecureVector EMSA1_BSI::encoding_of(const MemoryRegion& msg, - size_t output_bits, - RandomNumberGenerator&) - { - if(msg.size() != hash_ptr()->output_length()) - throw Encoding_Error("EMSA1_BSI::encoding_of: Invalid size for input"); - - if(8*msg.size() <= output_bits) - return msg; - - throw Encoding_Error("EMSA1_BSI::encoding_of: max key input size exceeded"); - } - -} -/* -* EMSA2 -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -namespace { - -/* -* EMSA2 Encode Operation -*/ -SecureVector emsa2_encoding(const MemoryRegion& msg, - size_t output_bits, - const MemoryRegion& empty_hash, - byte hash_id) - { - const size_t HASH_SIZE = empty_hash.size(); - - size_t output_length = (output_bits + 1) / 8; - - if(msg.size() != HASH_SIZE) - throw Encoding_Error("EMSA2::encoding_of: Bad input length"); - if(output_length < HASH_SIZE + 4) - throw Encoding_Error("EMSA2::encoding_of: Output length is too small"); - - bool empty = true; - for(size_t j = 0; j != HASH_SIZE; ++j) - if(empty_hash[j] != msg[j]) - empty = false; - - SecureVector output(output_length); - - output[0] = (empty ? 0x4B : 0x6B); - output[output_length - 3 - HASH_SIZE] = 0xBA; - set_mem(&output[1], output_length - 4 - HASH_SIZE, 0xBB); - output.copy(output_length - (HASH_SIZE + 2), &msg[0], msg.size()); - output[output_length-2] = hash_id; - output[output_length-1] = 0xCC; - - return output; - } - -} - -/* -* EMSA2 Update Operation -*/ -void EMSA2::update(const byte input[], size_t length) - { - hash->update(input, length); - } - -/* -* Return the raw (unencoded) data -*/ -SecureVector EMSA2::raw_data() - { - return hash->final(); - } - -/* -* EMSA2 Encode Operation -*/ -SecureVector EMSA2::encoding_of(const MemoryRegion& msg, - size_t output_bits, - RandomNumberGenerator&) - { - return emsa2_encoding(msg, output_bits, empty_hash, hash_id); - } - -/* -* EMSA2 Verify Operation -*/ -bool EMSA2::verify(const MemoryRegion& coded, - const MemoryRegion& raw, - size_t key_bits) - { - try - { - return (coded == emsa2_encoding(raw, key_bits, - empty_hash, hash_id)); - } - catch(...) - { - return false; - } - } - -/* -* EMSA2 Constructor -*/ -EMSA2::EMSA2(HashFunction* hash_in) : hash(hash_in) - { - empty_hash = hash->final(); - - hash_id = ieee1363_hash_id(hash->name()); - - if(hash_id == 0) - { - const std::string hashName = hash->name(); - delete hash; - throw Encoding_Error("EMSA2 cannot be used with " + hashName); - } - } - -} -/* -* EMSA3 and EMSA3_Raw -* (C) 1999-2008 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -namespace { - -/* -* EMSA3 Encode Operation -*/ -SecureVector emsa3_encoding(const MemoryRegion& msg, - size_t output_bits, - const byte hash_id[], - size_t hash_id_length) - { - size_t output_length = output_bits / 8; - if(output_length < hash_id_length + msg.size() + 10) - throw Encoding_Error("emsa3_encoding: Output length is too small"); - - SecureVector T(output_length); - const size_t P_LENGTH = output_length - msg.size() - hash_id_length - 2; - - T[0] = 0x01; - set_mem(&T[1], P_LENGTH, 0xFF); - T[P_LENGTH+1] = 0x00; - T.copy(P_LENGTH+2, hash_id, hash_id_length); - T.copy(output_length-msg.size(), &msg[0], msg.size()); - return T; - } - -} - -/* -* EMSA3 Update Operation -*/ -void EMSA3::update(const byte input[], size_t length) - { - hash->update(input, length); - } - -/* -* Return the raw (unencoded) data -*/ -SecureVector EMSA3::raw_data() - { - return hash->final(); - } - -/* -* EMSA3 Encode Operation -*/ -SecureVector EMSA3::encoding_of(const MemoryRegion& msg, - size_t output_bits, - RandomNumberGenerator&) - { - if(msg.size() != hash->output_length()) - throw Encoding_Error("EMSA3::encoding_of: Bad input length"); - - return emsa3_encoding(msg, output_bits, - &hash_id[0], hash_id.size()); - } - -/* -* Default signature decoding -*/ -bool EMSA3::verify(const MemoryRegion& coded, - const MemoryRegion& raw, - size_t key_bits) - { - if(raw.size() != hash->output_length()) - return false; - - try - { - return (coded == emsa3_encoding(raw, key_bits, - &hash_id[0], hash_id.size())); - } - catch(...) - { - return false; - } - } - -/* -* EMSA3 Constructor -*/ -EMSA3::EMSA3(HashFunction* hash_in) : hash(hash_in) - { - hash_id = pkcs_hash_id(hash->name()); - } - -/* -* EMSA3 Destructor -*/ -EMSA3::~EMSA3() - { - delete hash; - } - -/* -* EMSA3_Raw Update Operation -*/ -void EMSA3_Raw::update(const byte input[], size_t length) - { - message += std::make_pair(input, length); - } - -/* -* Return the raw (unencoded) data -*/ -SecureVector EMSA3_Raw::raw_data() - { - SecureVector ret; - std::swap(ret, message); - return ret; - } - -/* -* EMSA3_Raw Encode Operation -*/ -SecureVector EMSA3_Raw::encoding_of(const MemoryRegion& msg, - size_t output_bits, - RandomNumberGenerator&) - { - return emsa3_encoding(msg, output_bits, 0, 0); - } - -/* -* Default signature decoding -*/ -bool EMSA3_Raw::verify(const MemoryRegion& coded, - const MemoryRegion& raw, - size_t key_bits) - { - try - { - return (coded == emsa3_encoding(raw, key_bits, 0, 0)); - } - catch(...) - { - return false; - } - } - -} -/* -* EMSA4 -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -/* -* EMSA4 Update Operation -*/ -void EMSA4::update(const byte input[], size_t length) - { - hash->update(input, length); - } - -/* -* Return the raw (unencoded) data -*/ -SecureVector EMSA4::raw_data() - { - return hash->final(); - } - -/* -* EMSA4 Encode Operation -*/ -SecureVector EMSA4::encoding_of(const MemoryRegion& msg, - size_t output_bits, - RandomNumberGenerator& rng) - { - const size_t HASH_SIZE = hash->output_length(); - - if(msg.size() != HASH_SIZE) - throw Encoding_Error("EMSA4::encoding_of: Bad input length"); - if(output_bits < 8*HASH_SIZE + 8*SALT_SIZE + 9) - throw Encoding_Error("EMSA4::encoding_of: Output length is too small"); - - const size_t output_length = (output_bits + 7) / 8; - - SecureVector salt = rng.random_vec(SALT_SIZE); - - for(size_t j = 0; j != 8; ++j) - hash->update(0); - hash->update(msg); - hash->update(salt, SALT_SIZE); - SecureVector H = hash->final(); - - SecureVector EM(output_length); - - EM[output_length - HASH_SIZE - SALT_SIZE - 2] = 0x01; - EM.copy(output_length - 1 - HASH_SIZE - SALT_SIZE, salt, SALT_SIZE); - mgf->mask(H, HASH_SIZE, EM, output_length - HASH_SIZE - 1); - EM[0] &= 0xFF >> (8 * ((output_bits + 7) / 8) - output_bits); - EM.copy(output_length - 1 - HASH_SIZE, H, HASH_SIZE); - EM[output_length-1] = 0xBC; - - return EM; - } - -/* -* EMSA4 Decode/Verify Operation -*/ -bool EMSA4::verify(const MemoryRegion& const_coded, - const MemoryRegion& raw, size_t key_bits) - { - const size_t HASH_SIZE = hash->output_length(); - const size_t KEY_BYTES = (key_bits + 7) / 8; - - if(key_bits < 8*HASH_SIZE + 9) - return false; - - if(raw.size() != HASH_SIZE) - return false; - - if(const_coded.size() > KEY_BYTES || const_coded.size() <= 1) - return false; - - if(const_coded[const_coded.size()-1] != 0xBC) - return false; - - SecureVector coded = const_coded; - if(coded.size() < KEY_BYTES) - { - SecureVector temp(KEY_BYTES); - temp.copy(KEY_BYTES - coded.size(), coded, coded.size()); - coded = temp; - } - - const size_t TOP_BITS = 8 * ((key_bits + 7) / 8) - key_bits; - if(TOP_BITS > 8 - high_bit(coded[0])) - return false; - - SecureVector DB(&coded[0], coded.size() - HASH_SIZE - 1); - SecureVector H(&coded[coded.size() - HASH_SIZE - 1], HASH_SIZE); - - mgf->mask(H, H.size(), DB, coded.size() - H.size() - 1); - DB[0] &= 0xFF >> TOP_BITS; - - size_t salt_offset = 0; - for(size_t j = 0; j != DB.size(); ++j) - { - if(DB[j] == 0x01) - { salt_offset = j + 1; break; } - if(DB[j]) - return false; - } - if(salt_offset == 0) - return false; - - SecureVector salt(&DB[salt_offset], DB.size() - salt_offset); - - for(size_t j = 0; j != 8; ++j) - hash->update(0); - hash->update(raw); - hash->update(salt); - SecureVector H2 = hash->final(); - - return (H == H2); - } - -/* -* EMSA4 Constructor -*/ -EMSA4::EMSA4(HashFunction* h) : - SALT_SIZE(h->output_length()), hash(h) - { - mgf = new MGF1(hash->clone()); - } - -/* -* EMSA4 Constructor -*/ -EMSA4::EMSA4(HashFunction* h, size_t salt_size) : - SALT_SIZE(salt_size), hash(h) - { - mgf = new MGF1(hash->clone()); - } - -} -/* -* EMSA-Raw -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -/* -* EMSA-Raw Encode Operation -*/ -void EMSA_Raw::update(const byte input[], size_t length) - { - message += std::make_pair(input, length); - } - -/* -* Return the raw (unencoded) data -*/ -SecureVector EMSA_Raw::raw_data() - { - SecureVector output; - std::swap(message, output); - return output; - } - -/* -* EMSA-Raw Encode Operation -*/ -SecureVector EMSA_Raw::encoding_of(const MemoryRegion& msg, - size_t, - RandomNumberGenerator&) - { - return msg; - } - -/* -* EMSA-Raw Verify Operation -*/ -bool EMSA_Raw::verify(const MemoryRegion& coded, - const MemoryRegion& raw, - size_t) - { - if(coded.size() == raw.size()) - return (coded == raw); - - if(coded.size() > raw.size()) - return false; - - // handle zero padding differences - const size_t leading_zeros_expected = raw.size() - coded.size(); - - bool same_modulo_leading_zeros = true; - - for(size_t i = 0; i != leading_zeros_expected; ++i) - if(raw[i]) - same_modulo_leading_zeros = false; - - if(!same_mem(&coded[0], &raw[leading_zeros_expected], coded.size())) - same_modulo_leading_zeros = false; - - return same_modulo_leading_zeros; - } - -} -/* -* Hash Function Identification -* (C) 1999-2008 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -namespace { - -const byte MD2_PKCS_ID[] = { -0x30, 0x20, 0x30, 0x0C, 0x06, 0x08, 0x2A, 0x86, 0x48, 0x86, -0xF7, 0x0D, 0x02, 0x02, 0x05, 0x00, 0x04, 0x10 }; - -const byte MD5_PKCS_ID[] = { -0x30, 0x20, 0x30, 0x0C, 0x06, 0x08, 0x2A, 0x86, 0x48, 0x86, -0xF7, 0x0D, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10 }; - -const byte RIPEMD_128_PKCS_ID[] = { -0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x24, 0x03, 0x02, -0x02, 0x05, 0x00, 0x04, 0x14 }; - -const byte RIPEMD_160_PKCS_ID[] = { -0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x24, 0x03, 0x02, -0x01, 0x05, 0x00, 0x04, 0x14 }; - -const byte SHA_160_PKCS_ID[] = { -0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x0E, 0x03, 0x02, -0x1A, 0x05, 0x00, 0x04, 0x14 }; - -const byte SHA_224_PKCS_ID[] = { -0x30, 0x2D, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, -0x65, 0x03, 0x04, 0x02, 0x04, 0x05, 0x00, 0x04, 0x1C }; - -const byte SHA_256_PKCS_ID[] = { -0x30, 0x31, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, -0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20 }; - -const byte SHA_384_PKCS_ID[] = { -0x30, 0x41, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, -0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30 }; - -const byte SHA_512_PKCS_ID[] = { -0x30, 0x51, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, -0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40 }; - -const byte TIGER_PKCS_ID[] = { -0x30, 0x29, 0x30, 0x0D, 0x06, 0x09, 0x2B, 0x06, 0x01, 0x04, -0x01, 0xDA, 0x47, 0x0C, 0x02, 0x05, 0x00, 0x04, 0x18 }; - -} - -/* -* HashID as specified by PKCS -*/ -MemoryVector pkcs_hash_id(const std::string& name) - { - // Special case for SSL/TLS RSA signatures - if(name == "Parallel(MD5,SHA-160)") - return MemoryVector(); - - if(name == "MD2") - return MemoryVector(MD2_PKCS_ID, sizeof(MD2_PKCS_ID)); - if(name == "MD5") - return MemoryVector(MD5_PKCS_ID, sizeof(MD5_PKCS_ID)); - if(name == "RIPEMD-128") - return MemoryVector(RIPEMD_128_PKCS_ID, sizeof(RIPEMD_128_PKCS_ID)); - if(name == "RIPEMD-160") - return MemoryVector(RIPEMD_160_PKCS_ID, sizeof(RIPEMD_160_PKCS_ID)); - if(name == "SHA-160") - return MemoryVector(SHA_160_PKCS_ID, sizeof(SHA_160_PKCS_ID)); - if(name == "SHA-224") - return MemoryVector(SHA_224_PKCS_ID, sizeof(SHA_224_PKCS_ID)); - if(name == "SHA-256") - return MemoryVector(SHA_256_PKCS_ID, sizeof(SHA_256_PKCS_ID)); - if(name == "SHA-384") - return MemoryVector(SHA_384_PKCS_ID, sizeof(SHA_384_PKCS_ID)); - if(name == "SHA-512") - return MemoryVector(SHA_512_PKCS_ID, sizeof(SHA_512_PKCS_ID)); - if(name == "Tiger(24,3)") - return MemoryVector(TIGER_PKCS_ID, sizeof(TIGER_PKCS_ID)); - - throw Invalid_Argument("No PKCS #1 identifier for " + name); - } - -/* -* HashID as specified by IEEE 1363/X9.31 -*/ -byte ieee1363_hash_id(const std::string& name) - { - if(name == "SHA-160") return 0x33; - - if(name == "SHA-224") return 0x38; - if(name == "SHA-256") return 0x34; - if(name == "SHA-384") return 0x36; - if(name == "SHA-512") return 0x35; - - if(name == "RIPEMD-160") return 0x31; - if(name == "RIPEMD-128") return 0x32; - - if(name == "Whirlpool") return 0x37; - - return 0; - } - -} -/* -* Blinding for public key operations -* (C) 1999-2010 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -/* -* Blinder Constructor -*/ -Blinder::Blinder(const BigInt& e, const BigInt& d, const BigInt& n) - { - if(e < 1 || d < 1 || n < 1) - throw Invalid_Argument("Blinder: Arguments too small"); - - reducer = Modular_Reducer(n); - this->e = e; - this->d = d; - } - -/* -* Blind a number -*/ -BigInt Blinder::blind(const BigInt& i) const - { - if(!reducer.initialized()) - return i; - - e = reducer.square(e); - d = reducer.square(d); - return reducer.multiply(i, e); - } - -/* -* Unblind a number -*/ -BigInt Blinder::unblind(const BigInt& i) const - { - if(!reducer.initialized()) - return i; - return reducer.multiply(i, d); - } - -} -/* -* Diffie-Hellman -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -/* -* DH_PublicKey Constructor -*/ -DH_PublicKey::DH_PublicKey(const DL_Group& grp, const BigInt& y1) - { - group = grp; - y = y1; - } - -/* -* Return the public value for key agreement -*/ -MemoryVector DH_PublicKey::public_value() const - { - return BigInt::encode_1363(y, group_p().bytes()); - } - -/* -* Create a DH private key -*/ -DH_PrivateKey::DH_PrivateKey(RandomNumberGenerator& rng, - const DL_Group& grp, - const BigInt& x_arg) - { - group = grp; - x = x_arg; - - if(x == 0) - { - const BigInt& p = group_p(); - x.randomize(rng, 2 * dl_work_factor(p.bits())); - } - - if(y == 0) - y = power_mod(group_g(), x, group_p()); - - if(x == 0) - gen_check(rng); - else - load_check(rng); - } - -/* -* Load a DH private key -*/ -DH_PrivateKey::DH_PrivateKey(const AlgorithmIdentifier& alg_id, - const MemoryRegion& key_bits, - RandomNumberGenerator& rng) : - DL_Scheme_PrivateKey(alg_id, key_bits, DL_Group::ANSI_X9_42) - { - if(y == 0) - y = power_mod(group_g(), x, group_p()); - - load_check(rng); - } - -/* -* Return the public value for key agreement -*/ -MemoryVector DH_PrivateKey::public_value() const - { - return DH_PublicKey::public_value(); - } - -DH_KA_Operation::DH_KA_Operation(const DH_PrivateKey& dh) : - p(dh.group_p()), powermod_x_p(dh.get_x(), p) - { - BigInt k(global_state().global_rng(), p.bits() - 1); - blinder = Blinder(k, powermod_x_p(inverse_mod(k, p)), p); - } - -SecureVector DH_KA_Operation::agree(const byte w[], size_t w_len) - { - BigInt input = BigInt::decode(w, w_len); - - BigInt r = blinder.unblind(powermod_x_p(blinder.blind(input))); - - return BigInt::encode_1363(r, p.bytes()); - } - -} -/* -* DL Scheme -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -AlgorithmIdentifier DL_Scheme_PublicKey::algorithm_identifier() const - { - return AlgorithmIdentifier(get_oid(), - group.DER_encode(group_format())); - } - -MemoryVector DL_Scheme_PublicKey::x509_subject_public_key() const - { - return DER_Encoder().encode(y).get_contents(); - } - -DL_Scheme_PublicKey::DL_Scheme_PublicKey(const AlgorithmIdentifier& alg_id, - const MemoryRegion& key_bits, - DL_Group::Format format) - { - DataSource_Memory source(alg_id.parameters); - group.BER_decode(source, format); - - BER_Decoder(key_bits).decode(y); - } - -MemoryVector DL_Scheme_PrivateKey::pkcs8_private_key() const - { - return DER_Encoder().encode(x).get_contents(); - } - -DL_Scheme_PrivateKey::DL_Scheme_PrivateKey(const AlgorithmIdentifier& alg_id, - const MemoryRegion& key_bits, - DL_Group::Format format) - { - DataSource_Memory source(alg_id.parameters); - group.BER_decode(source, format); - - BER_Decoder(key_bits).decode(x); - } - -/* -* Check Public DL Parameters -*/ -bool DL_Scheme_PublicKey::check_key(RandomNumberGenerator& rng, - bool strong) const - { - if(y < 2 || y >= group_p()) - return false; - if(!group.verify_group(rng, strong)) - return false; - return true; - } - -/* -* Check DL Scheme Private Parameters -*/ -bool DL_Scheme_PrivateKey::check_key(RandomNumberGenerator& rng, - bool strong) const - { - const BigInt& p = group_p(); - const BigInt& g = group_g(); - - if(y < 2 || y >= p || x < 2 || x >= p) - return false; - if(!group.verify_group(rng, strong)) - return false; - - if(!strong) - return true; - - if(y != power_mod(g, x, p)) - return false; - - return true; - } - -} -/* -* Discrete Logarithm Parameters -* (C) 1999-2008 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -/* -* DL_Group Constructor -*/ -DL_Group::DL_Group() - { - initialized = false; - } - -/* -* DL_Group Constructor -*/ -DL_Group::DL_Group(const std::string& type) - { - std::string grp_contents = global_state().get("dl", type); - - if(grp_contents == "") - throw Invalid_Argument("DL_Group: Unknown group " + type); - - DataSource_Memory pem(grp_contents); - PEM_decode(pem); - } - -/* -* DL_Group Constructor -*/ -DL_Group::DL_Group(RandomNumberGenerator& rng, - PrimeType type, size_t pbits, size_t qbits) - { - if(pbits < 512) - throw Invalid_Argument("DL_Group: prime size " + to_string(pbits) + - " is too small"); - - if(type == Strong) - { - p = random_safe_prime(rng, pbits); - q = (p - 1) / 2; - g = 2; - } - else if(type == Prime_Subgroup) - { - if(!qbits) - qbits = 2 * dl_work_factor(pbits); - - q = random_prime(rng, qbits); - BigInt X; - while(p.bits() != pbits || !check_prime(p, rng)) - { - X.randomize(rng, pbits); - p = X - (X % (2*q) - 1); - } - - g = make_dsa_generator(p, q); - } - else if(type == DSA_Kosherizer) - { - qbits = qbits ? qbits : ((pbits <= 1024) ? 160 : 256); - - generate_dsa_primes(rng, - global_state().algorithm_factory(), - p, q, - pbits, qbits); - - g = make_dsa_generator(p, q); - } - - initialized = true; - } - -/* -* DL_Group Constructor -*/ -DL_Group::DL_Group(RandomNumberGenerator& rng, - const MemoryRegion& seed, size_t pbits, size_t qbits) - { - if(!generate_dsa_primes(rng, - global_state().algorithm_factory(), - p, q, pbits, qbits, seed)) - throw Invalid_Argument("DL_Group: The seed given does not " - "generate a DSA group"); - - g = make_dsa_generator(p, q); - - initialized = true; - } - -/* -* DL_Group Constructor -*/ -DL_Group::DL_Group(const BigInt& p1, const BigInt& g1) - { - initialize(p1, 0, g1); - } - -/* -* DL_Group Constructor -*/ -DL_Group::DL_Group(const BigInt& p1, const BigInt& q1, const BigInt& g1) - { - initialize(p1, q1, g1); - } - -/* -* DL_Group Initializer -*/ -void DL_Group::initialize(const BigInt& p1, const BigInt& q1, const BigInt& g1) - { - if(p1 < 3) - throw Invalid_Argument("DL_Group: Prime invalid"); - if(g1 < 2 || g1 >= p1) - throw Invalid_Argument("DL_Group: Generator invalid"); - if(q1 < 0 || q1 >= p1) - throw Invalid_Argument("DL_Group: Subgroup invalid"); - - p = p1; - g = g1; - q = q1; - - initialized = true; - } - -/* -* Verify that the group has been set -*/ -void DL_Group::init_check() const - { - if(!initialized) - throw Invalid_State("DLP group cannot be used uninitialized"); - } - -/* -* Verify the parameters -*/ -bool DL_Group::verify_group(RandomNumberGenerator& rng, - bool strong) const - { - init_check(); - - if(g < 2 || p < 3 || q < 0) - return false; - if((q != 0) && ((p - 1) % q != 0)) - return false; - - if(!strong) - return true; - - if(!check_prime(p, rng)) - return false; - if((q > 0) && !check_prime(q, rng)) - return false; - return true; - } - -/* -* Return the prime -*/ -const BigInt& DL_Group::get_p() const - { - init_check(); - return p; - } - -/* -* Return the generator -*/ -const BigInt& DL_Group::get_g() const - { - init_check(); - return g; - } - -/* -* Return the subgroup -*/ -const BigInt& DL_Group::get_q() const - { - init_check(); - if(q == 0) - throw Invalid_State("DLP group has no q prime specified"); - return q; - } - -/* -* DER encode the parameters -*/ -SecureVector DL_Group::DER_encode(Format format) const - { - init_check(); - - if((q == 0) && (format != PKCS_3)) - throw Encoding_Error("The ANSI DL parameter formats require a subgroup"); - - if(format == ANSI_X9_57) - { - return DER_Encoder() - .start_cons(SEQUENCE) - .encode(p) - .encode(q) - .encode(g) - .end_cons() - .get_contents(); - } - else if(format == ANSI_X9_42) - { - return DER_Encoder() - .start_cons(SEQUENCE) - .encode(p) - .encode(g) - .encode(q) - .end_cons() - .get_contents(); - } - else if(format == PKCS_3) - { - return DER_Encoder() - .start_cons(SEQUENCE) - .encode(p) - .encode(g) - .end_cons() - .get_contents(); - } - - throw Invalid_Argument("Unknown DL_Group encoding " + to_string(format)); - } - -/* -* PEM encode the parameters -*/ -std::string DL_Group::PEM_encode(Format format) const - { - SecureVector encoding = DER_encode(format); - if(format == PKCS_3) - return PEM_Code::encode(encoding, "DH PARAMETERS"); - else if(format == ANSI_X9_57) - return PEM_Code::encode(encoding, "DSA PARAMETERS"); - else if(format == ANSI_X9_42) - return PEM_Code::encode(encoding, "X942 DH PARAMETERS"); - else - throw Invalid_Argument("Unknown DL_Group encoding " + to_string(format)); - } - -/* -* Decode BER encoded parameters -*/ -void DL_Group::BER_decode(DataSource& source, Format format) - { - BigInt new_p, new_q, new_g; - - BER_Decoder decoder(source); - BER_Decoder ber = decoder.start_cons(SEQUENCE); - - if(format == ANSI_X9_57) - { - ber.decode(new_p) - .decode(new_q) - .decode(new_g) - .verify_end(); - } - else if(format == ANSI_X9_42) - { - ber.decode(new_p) - .decode(new_g) - .decode(new_q) - .discard_remaining(); - } - else if(format == PKCS_3) - { - ber.decode(new_p) - .decode(new_g) - .discard_remaining(); - } - else - throw Invalid_Argument("Unknown DL_Group encoding " + to_string(format)); - - initialize(new_p, new_q, new_g); - } - -/* -* Decode PEM encoded parameters -*/ -void DL_Group::PEM_decode(DataSource& source) - { - std::string label; - DataSource_Memory ber(PEM_Code::decode(source, label)); - - if(label == "DH PARAMETERS") - BER_decode(ber, PKCS_3); - else if(label == "DSA PARAMETERS") - BER_decode(ber, ANSI_X9_57); - else if(label == "X942 DH PARAMETERS") - BER_decode(ber, ANSI_X9_42); - else - throw Decoding_Error("DL_Group: Invalid PEM label " + label); - } - -/* -* Create generator of the q-sized subgroup (DSA style generator) -*/ -BigInt DL_Group::make_dsa_generator(const BigInt& p, const BigInt& q) - { - BigInt g, e = (p - 1) / q; - - BOTAN_ASSERT(e > 0, "q does not divide p, invalid group"); - - for(size_t i = 0; i != PRIME_TABLE_SIZE; ++i) - { - g = power_mod(PRIMES[i], e, p); - if(g > 1) - return g; - } - - throw Internal_Error("DL_Group: Couldn't create a suitable generator"); - } - -} -/* -* DLIES -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -/* -* DLIES_Encryptor Constructor -*/ -DLIES_Encryptor::DLIES_Encryptor(const PK_Key_Agreement_Key& key, - KDF* kdf_obj, - MessageAuthenticationCode* mac_obj, - size_t mac_kl) : - ka(key, "Raw"), - kdf(kdf_obj), - mac(mac_obj), - mac_keylen(mac_kl) - { - my_key = key.public_value(); - } - -DLIES_Encryptor::~DLIES_Encryptor() - { - delete kdf; - delete mac; - } - -/* -* DLIES Encryption -*/ -SecureVector DLIES_Encryptor::enc(const byte in[], size_t length, - RandomNumberGenerator&) const - { - if(length > maximum_input_size()) - throw Invalid_Argument("DLIES: Plaintext too large"); - if(other_key.empty()) - throw Invalid_State("DLIES: The other key was never set"); - - SecureVector out(my_key.size() + length + mac->output_length()); - out.copy(&my_key[0], my_key.size()); - out.copy(my_key.size(), in, length); - - SecureVector vz = my_key; - vz += ka.derive_key(0, other_key).bits_of(); - - const size_t K_LENGTH = length + mac_keylen; - OctetString K = kdf->derive_key(K_LENGTH, vz); - - if(K.length() != K_LENGTH) - throw Encoding_Error("DLIES: KDF did not provide sufficient output"); - byte* C = &out[my_key.size()]; - - xor_buf(C, K.begin() + mac_keylen, length); - mac->set_key(K.begin(), mac_keylen); - - mac->update(C, length); - for(size_t j = 0; j != 8; ++j) - mac->update(0); - - mac->final(C + length); - - return out; - } - -/* -* Set the other parties public key -*/ -void DLIES_Encryptor::set_other_key(const MemoryRegion& ok) - { - other_key = ok; - } - -/* -* Return the max size, in bytes, of a message -*/ -size_t DLIES_Encryptor::maximum_input_size() const - { - return 32; - } - -/* -* DLIES_Decryptor Constructor -*/ -DLIES_Decryptor::DLIES_Decryptor(const PK_Key_Agreement_Key& key, - KDF* kdf_obj, - MessageAuthenticationCode* mac_obj, - size_t mac_kl) : - ka(key, "Raw"), - kdf(kdf_obj), - mac(mac_obj), - mac_keylen(mac_kl) - { - my_key = key.public_value(); - } - -DLIES_Decryptor::~DLIES_Decryptor() - { - delete kdf; - delete mac; - } - -/* -* DLIES Decryption -*/ -SecureVector DLIES_Decryptor::dec(const byte msg[], size_t length) const - { - if(length < my_key.size() + mac->output_length()) - throw Decoding_Error("DLIES decryption: ciphertext is too short"); - - const size_t CIPHER_LEN = length - my_key.size() - mac->output_length(); - - SecureVector v(msg, my_key.size()); - SecureVector C(msg + my_key.size(), CIPHER_LEN); - SecureVector T(msg + my_key.size() + CIPHER_LEN, mac->output_length()); - - SecureVector vz(msg, my_key.size()); - vz += ka.derive_key(0, v).bits_of(); - - const size_t K_LENGTH = C.size() + mac_keylen; - OctetString K = kdf->derive_key(K_LENGTH, vz); - if(K.length() != K_LENGTH) - throw Encoding_Error("DLIES: KDF did not provide sufficient output"); - - mac->set_key(K.begin(), mac_keylen); - mac->update(C); - for(size_t j = 0; j != 8; ++j) - mac->update(0); - SecureVector T2 = mac->final(); - if(T != T2) - throw Decoding_Error("DLIES: message authentication failed"); - - xor_buf(C, K.begin() + mac_keylen, C.size()); - - return C; - } - -} -/* -* DSA -* (C) 1999-2010 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -/* -* DSA_PublicKey Constructor -*/ -DSA_PublicKey::DSA_PublicKey(const DL_Group& grp, const BigInt& y1) - { - group = grp; - y = y1; - } - -/* -* Create a DSA private key -*/ -DSA_PrivateKey::DSA_PrivateKey(RandomNumberGenerator& rng, - const DL_Group& grp, - const BigInt& x_arg) - { - group = grp; - x = x_arg; - - if(x == 0) - x = BigInt::random_integer(rng, 2, group_q() - 1); - - y = power_mod(group_g(), x, group_p()); - - if(x_arg == 0) - gen_check(rng); - else - load_check(rng); - } - -DSA_PrivateKey::DSA_PrivateKey(const AlgorithmIdentifier& alg_id, - const MemoryRegion& key_bits, - RandomNumberGenerator& rng) : - DL_Scheme_PrivateKey(alg_id, key_bits, DL_Group::ANSI_X9_57) - { - y = power_mod(group_g(), x, group_p()); - - load_check(rng); - } - -/* -* Check Private DSA Parameters -*/ -bool DSA_PrivateKey::check_key(RandomNumberGenerator& rng, bool strong) const - { - if(!DL_Scheme_PrivateKey::check_key(rng, strong) || x >= group_q()) - return false; - - if(!strong) - return true; - - return KeyPair::signature_consistency_check(rng, *this, "EMSA1(SHA-1)"); - } - -DSA_Signature_Operation::DSA_Signature_Operation(const DSA_PrivateKey& dsa) : - q(dsa.group_q()), - x(dsa.get_x()), - powermod_g_p(dsa.group_g(), dsa.group_p()), - mod_q(dsa.group_q()) - { - } - -SecureVector -DSA_Signature_Operation::sign(const byte msg[], size_t msg_len, - RandomNumberGenerator& rng) - { - rng.add_entropy(msg, msg_len); - - BigInt i(msg, msg_len); - BigInt r = 0, s = 0; - - while(r == 0 || s == 0) - { - BigInt k; - do - k.randomize(rng, q.bits()); - while(k >= q); - - r = mod_q.reduce(powermod_g_p(k)); - s = mod_q.multiply(inverse_mod(k, q), mul_add(x, r, i)); - } - - SecureVector output(2*q.bytes()); - r.binary_encode(&output[output.size() / 2 - r.bytes()]); - s.binary_encode(&output[output.size() - s.bytes()]); - return output; - } - -DSA_Verification_Operation::DSA_Verification_Operation(const DSA_PublicKey& dsa) : - q(dsa.group_q()), y(dsa.get_y()) - { - powermod_g_p = Fixed_Base_Power_Mod(dsa.group_g(), dsa.group_p()); - powermod_y_p = Fixed_Base_Power_Mod(y, dsa.group_p()); - mod_p = Modular_Reducer(dsa.group_p()); - mod_q = Modular_Reducer(dsa.group_q()); - } - -bool DSA_Verification_Operation::verify(const byte msg[], size_t msg_len, - const byte sig[], size_t sig_len) - { - const BigInt& q = mod_q.get_modulus(); - - if(sig_len != 2*q.bytes() || msg_len > q.bytes()) - return false; - - BigInt r(sig, q.bytes()); - BigInt s(sig + q.bytes(), q.bytes()); - BigInt i(msg, msg_len); - - if(r <= 0 || r >= q || s <= 0 || s >= q) - return false; - - s = inverse_mod(s, q); - s = mod_p.multiply(powermod_g_p(mod_q.multiply(s, i)), - powermod_y_p(mod_q.multiply(s, r))); - - return (mod_q.reduce(s) == r); - } - -} -/* -* ECC Domain Parameters -* -* (C) 2007 Falko Strenzke, FlexSecure GmbH -* 2008 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -EC_Group::EC_Group(const OID& domain_oid) - { - std::string pem = - global_state().get("ec", OIDS::lookup(domain_oid)); - - if(pem == "") - throw Lookup_Error("No ECC domain data for " + domain_oid.as_string()); - - *this = EC_Group(pem); - oid = domain_oid.as_string(); - } - -EC_Group::EC_Group(const std::string& str) - { - if(str == "") - return; // no initialization / uninitialized - - try - { - DataSource_Memory input(str); - - SecureVector ber = - PEM_Code::decode_check_label(input, "EC PARAMETERS"); - - *this = EC_Group(ber); - } - catch(Decoding_Error) // hmm, not PEM? - { - *this = EC_Group(OIDS::lookup(str)); - } - } - -EC_Group::EC_Group(const MemoryRegion& ber_data) - { - BER_Decoder ber(ber_data); - BER_Object obj = ber.get_next_object(); - - if(obj.type_tag == NULL_TAG) - throw Decoding_Error("Cannot handle ImplicitCA ECDSA parameters"); - else if(obj.type_tag == OBJECT_ID) - { - OID dom_par_oid; - BER_Decoder(ber_data).decode(dom_par_oid); - *this = EC_Group(dom_par_oid); - } - else if(obj.type_tag == SEQUENCE) - { - BigInt p, a, b; - SecureVector sv_base_point; - - BER_Decoder(ber_data) - .start_cons(SEQUENCE) - .decode_and_check(1, "Unknown ECC param version code") - .start_cons(SEQUENCE) - .decode_and_check(OID("1.2.840.10045.1.1"), - "Only prime ECC fields supported") - .decode(p) - .end_cons() - .start_cons(SEQUENCE) - .decode_octet_string_bigint(a) - .decode_octet_string_bigint(b) - .end_cons() - .decode(sv_base_point, OCTET_STRING) - .decode(order) - .decode(cofactor) - .end_cons() - .verify_end(); - - curve = CurveGFp(p, a, b); - base_point = OS2ECP(sv_base_point, curve); - } - else - throw Decoding_Error("Unexpected tag while decoding ECC domain params"); - } - -SecureVector -EC_Group::DER_encode(EC_Group_Encoding form) const - { - if(form == EC_DOMPAR_ENC_EXPLICIT) - { - const size_t ecpVers1 = 1; - OID curve_type("1.2.840.10045.1.1"); - - const size_t p_bytes = curve.get_p().bytes(); - - return DER_Encoder() - .start_cons(SEQUENCE) - .encode(ecpVers1) - .start_cons(SEQUENCE) - .encode(curve_type) - .encode(curve.get_p()) - .end_cons() - .start_cons(SEQUENCE) - .encode(BigInt::encode_1363(curve.get_a(), p_bytes), - OCTET_STRING) - .encode(BigInt::encode_1363(curve.get_b(), p_bytes), - OCTET_STRING) - .end_cons() - .encode(EC2OSP(base_point, PointGFp::UNCOMPRESSED), OCTET_STRING) - .encode(order) - .encode(cofactor) - .end_cons() - .get_contents(); - } - else if(form == EC_DOMPAR_ENC_OID) - return DER_Encoder().encode(get_oid()).get_contents(); - else if(form == EC_DOMPAR_ENC_IMPLICITCA) - return DER_Encoder().encode_null().get_contents(); - else - throw Internal_Error("EC_Group::DER_encode: Unknown encoding"); - } - -std::string EC_Group::PEM_encode() const - { - SecureVector der = DER_encode(EC_DOMPAR_ENC_EXPLICIT); - return PEM_Code::encode(der, "EC PARAMETERS"); - } - -} -/* -* ECC Key implemenation -* (C) 2007 Manuel Hartl, FlexSecure GmbH -* Falko Strenzke, FlexSecure GmbH -* 2008-2010 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -EC_PublicKey::EC_PublicKey(const EC_Group& dom_par, - const PointGFp& pub_point) : - domain_params(dom_par), public_key(pub_point), - domain_encoding(EC_DOMPAR_ENC_EXPLICIT) - { - if(domain().get_curve() != public_point().get_curve()) - throw Invalid_Argument("EC_PublicKey: curve mismatch in constructor"); - } - -EC_PublicKey::EC_PublicKey(const AlgorithmIdentifier& alg_id, - const MemoryRegion& key_bits) - { - domain_params = EC_Group(alg_id.parameters); - domain_encoding = EC_DOMPAR_ENC_EXPLICIT; - - public_key = OS2ECP(key_bits, domain().get_curve()); - } - -bool EC_PublicKey::check_key(RandomNumberGenerator&, - bool) const - { - return public_point().on_the_curve(); - } - -AlgorithmIdentifier EC_PublicKey::algorithm_identifier() const - { - return AlgorithmIdentifier(get_oid(), DER_domain()); - } - -MemoryVector EC_PublicKey::x509_subject_public_key() const - { - return EC2OSP(public_point(), PointGFp::COMPRESSED); - } - -void EC_PublicKey::set_parameter_encoding(EC_Group_Encoding form) - { - if(form != EC_DOMPAR_ENC_EXPLICIT && - form != EC_DOMPAR_ENC_IMPLICITCA && - form != EC_DOMPAR_ENC_OID) - throw Invalid_Argument("Invalid encoding form for EC-key object specified"); - - if((form == EC_DOMPAR_ENC_OID) && (domain_params.get_oid() == "")) - throw Invalid_Argument("Invalid encoding form OID specified for " - "EC-key object whose corresponding domain " - "parameters are without oid"); - - domain_encoding = form; - } - -const BigInt& EC_PrivateKey::private_value() const - { - if(private_key == 0) - throw Invalid_State("EC_PrivateKey::private_value - uninitialized"); - - return private_key; - } - -/** -* EC_PrivateKey constructor -*/ -EC_PrivateKey::EC_PrivateKey(RandomNumberGenerator& rng, - const EC_Group& ec_group, - const BigInt& x) - { - domain_params = ec_group; - domain_encoding = EC_DOMPAR_ENC_EXPLICIT; - - if(x == 0) - private_key = BigInt::random_integer(rng, 1, domain().get_order()); - else - private_key = x; - - public_key = domain().get_base_point() * private_key; - - BOTAN_ASSERT(public_key.on_the_curve(), - "ECC private key was not on the curve"); - } - -MemoryVector EC_PrivateKey::pkcs8_private_key() const - { - return DER_Encoder() - .start_cons(SEQUENCE) - .encode(static_cast(1)) - .encode(BigInt::encode_1363(private_key, private_key.bytes()), - OCTET_STRING) - .end_cons() - .get_contents(); - } - -EC_PrivateKey::EC_PrivateKey(const AlgorithmIdentifier& alg_id, - const MemoryRegion& key_bits) - { - domain_params = EC_Group(alg_id.parameters); - domain_encoding = EC_DOMPAR_ENC_EXPLICIT; - - BER_Decoder(key_bits) - .start_cons(SEQUENCE) - .decode_and_check(1, "Unknown version code for ECC key") - .decode_octet_string_bigint(private_key) - .verify_end() - .end_cons(); - - public_key = domain().get_base_point() * private_key; - - BOTAN_ASSERT(public_key.on_the_curve(), - "Loaded ECC private key not on the curve"); - } - -} -/* -* ECDH implemenation -* (C) 2007 Manuel Hartl, FlexSecure GmbH -* 2007 Falko Strenzke, FlexSecure GmbH -* 2008-2010 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -ECDH_KA_Operation::ECDH_KA_Operation(const ECDH_PrivateKey& key) : - curve(key.domain().get_curve()), - cofactor(key.domain().get_cofactor()) - { - l_times_priv = inverse_mod(cofactor, key.domain().get_order()) * - key.private_value(); - } - -SecureVector ECDH_KA_Operation::agree(const byte w[], size_t w_len) - { - PointGFp point = OS2ECP(w, w_len, curve); - - PointGFp S = (cofactor * point) * l_times_priv; - - BOTAN_ASSERT(S.on_the_curve(), - "ECDH agreed value not on the curve"); - - return BigInt::encode_1363(S.get_affine_x(), - curve.get_p().bytes()); - } - -} -/* -* ECDSA implemenation -* (C) 2007 Manuel Hartl, FlexSecure GmbH -* 2007 Falko Strenzke, FlexSecure GmbH -* 2008-2010 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -bool ECDSA_PrivateKey::check_key(RandomNumberGenerator& rng, - bool strong) const - { - if(!public_point().on_the_curve()) - return false; - - if(!strong) - return true; - - return KeyPair::signature_consistency_check(rng, *this, "EMSA1(SHA-1)"); - } - -ECDSA_Signature_Operation::ECDSA_Signature_Operation(const ECDSA_PrivateKey& ecdsa) : - base_point(ecdsa.domain().get_base_point()), - order(ecdsa.domain().get_order()), - x(ecdsa.private_value()), - mod_order(order) - { - } - -SecureVector -ECDSA_Signature_Operation::sign(const byte msg[], size_t msg_len, - RandomNumberGenerator& rng) - { - rng.add_entropy(msg, msg_len); - - BigInt m(msg, msg_len); - - BigInt r = 0, s = 0; - - while(r == 0 || s == 0) - { - // This contortion is necessary for the tests - BigInt k; - k.randomize(rng, order.bits()); - - while(k >= order) - k.randomize(rng, order.bits() - 1); - - PointGFp k_times_P = base_point * k; - r = mod_order.reduce(k_times_P.get_affine_x()); - s = mod_order.multiply(inverse_mod(k, order), mul_add(x, r, m)); - } - - SecureVector output(2*order.bytes()); - r.binary_encode(&output[output.size() / 2 - r.bytes()]); - s.binary_encode(&output[output.size() - s.bytes()]); - return output; - } - -ECDSA_Verification_Operation::ECDSA_Verification_Operation(const ECDSA_PublicKey& ecdsa) : - base_point(ecdsa.domain().get_base_point()), - public_point(ecdsa.public_point()), - order(ecdsa.domain().get_order()) - { - } - -bool ECDSA_Verification_Operation::verify(const byte msg[], size_t msg_len, - const byte sig[], size_t sig_len) - { - if(sig_len != order.bytes()*2) - return false; - - BigInt e(msg, msg_len); - - BigInt r(sig, sig_len / 2); - BigInt s(sig + sig_len / 2, sig_len / 2); - - if(r <= 0 || r >= order || s <= 0 || s >= order) - return false; - - BigInt w = inverse_mod(s, order); - - PointGFp R = w * multi_exponentiate(base_point, e, - public_point, r); - - if(R.is_zero()) - return false; - - return (R.get_affine_x() % order == r); - } - -} -/* -* ElGamal -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -/* -* ElGamal_PublicKey Constructor -*/ -ElGamal_PublicKey::ElGamal_PublicKey(const DL_Group& grp, const BigInt& y1) - { - group = grp; - y = y1; - } - -/* -* ElGamal_PrivateKey Constructor -*/ -ElGamal_PrivateKey::ElGamal_PrivateKey(RandomNumberGenerator& rng, - const DL_Group& grp, - const BigInt& x_arg) - { - group = grp; - x = x_arg; - - if(x == 0) - x.randomize(rng, 2 * dl_work_factor(group_p().bits())); - - y = power_mod(group_g(), x, group_p()); - - if(x_arg == 0) - gen_check(rng); - else - load_check(rng); - } - -ElGamal_PrivateKey::ElGamal_PrivateKey(const AlgorithmIdentifier& alg_id, - const MemoryRegion& key_bits, - RandomNumberGenerator& rng) : - DL_Scheme_PrivateKey(alg_id, key_bits, DL_Group::ANSI_X9_42) - { - y = power_mod(group_g(), x, group_p()); - load_check(rng); - } - -/* -* Check Private ElGamal Parameters -*/ -bool ElGamal_PrivateKey::check_key(RandomNumberGenerator& rng, - bool strong) const - { - if(!DL_Scheme_PrivateKey::check_key(rng, strong)) - return false; - - if(!strong) - return true; - - return KeyPair::encryption_consistency_check(rng, *this, "EME1(SHA-1)"); - } - -ElGamal_Encryption_Operation::ElGamal_Encryption_Operation(const ElGamal_PublicKey& key) - { - const BigInt& p = key.group_p(); - - powermod_g_p = Fixed_Base_Power_Mod(key.group_g(), p); - powermod_y_p = Fixed_Base_Power_Mod(key.get_y(), p); - mod_p = Modular_Reducer(p); - } - -SecureVector -ElGamal_Encryption_Operation::encrypt(const byte msg[], size_t msg_len, - RandomNumberGenerator& rng) - { - const BigInt& p = mod_p.get_modulus(); - - BigInt m(msg, msg_len); - - if(m >= p) - throw Invalid_Argument("ElGamal encryption: Input is too large"); - - BigInt k(rng, 2 * dl_work_factor(p.bits())); - - BigInt a = powermod_g_p(k); - BigInt b = mod_p.multiply(m, powermod_y_p(k)); - - SecureVector output(2*p.bytes()); - a.binary_encode(&output[p.bytes() - a.bytes()]); - b.binary_encode(&output[output.size() / 2 + (p.bytes() - b.bytes())]); - return output; - } - -ElGamal_Decryption_Operation::ElGamal_Decryption_Operation(const ElGamal_PrivateKey& key) - { - const BigInt& p = key.group_p(); - - powermod_x_p = Fixed_Exponent_Power_Mod(key.get_x(), p); - mod_p = Modular_Reducer(p); - - BigInt k(global_state().global_rng(), p.bits() - 1); - blinder = Blinder(k, powermod_x_p(k), p); - } - -SecureVector -ElGamal_Decryption_Operation::decrypt(const byte msg[], size_t msg_len) - { - const BigInt& p = mod_p.get_modulus(); - - const size_t p_bytes = p.bytes(); - - if(msg_len != 2 * p_bytes) - throw Invalid_Argument("ElGamal decryption: Invalid message"); - - BigInt a(msg, p_bytes); - BigInt b(msg + p_bytes, p_bytes); - - if(a >= p || b >= p) - throw Invalid_Argument("ElGamal decryption: Invalid message"); - - a = blinder.blind(a); - - BigInt r = mod_p.multiply(b, inverse_mod(powermod_x_p(a), p)); - - return BigInt::encode(blinder.unblind(r)); - } - -} -/* -* GOST 34.10-2001 implemenation -* (C) 2007 Falko Strenzke, FlexSecure GmbH -* Manuel Hartl, FlexSecure GmbH -* (C) 2008-2010 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -MemoryVector GOST_3410_PublicKey::x509_subject_public_key() const - { - // Trust CryptoPro to come up with something obnoxious - const BigInt x = public_point().get_affine_x(); - const BigInt y = public_point().get_affine_y(); - - size_t part_size = std::max(x.bytes(), y.bytes()); - - MemoryVector bits(2*part_size); - - x.binary_encode(&bits[part_size - x.bytes()]); - y.binary_encode(&bits[2*part_size - y.bytes()]); - - // Keys are stored in little endian format (WTF) - for(size_t i = 0; i != part_size / 2; ++i) - { - std::swap(bits[i], bits[part_size-1-i]); - std::swap(bits[part_size+i], bits[2*part_size-1-i]); - } - - return DER_Encoder().encode(bits, OCTET_STRING).get_contents(); - } - -AlgorithmIdentifier GOST_3410_PublicKey::algorithm_identifier() const - { - MemoryVector params = - DER_Encoder().start_cons(SEQUENCE) - .encode(OID(domain().get_oid())) - .end_cons() - .get_contents(); - - return AlgorithmIdentifier(get_oid(), params); - } - -GOST_3410_PublicKey::GOST_3410_PublicKey(const AlgorithmIdentifier& alg_id, - const MemoryRegion& key_bits) - { - OID ecc_param_id; - - // Also includes hash and cipher OIDs... brilliant design guys - BER_Decoder(alg_id.parameters).start_cons(SEQUENCE).decode(ecc_param_id); - - domain_params = EC_Group(ecc_param_id); - - SecureVector bits; - BER_Decoder(key_bits).decode(bits, OCTET_STRING); - - const size_t part_size = bits.size() / 2; - - // Keys are stored in little endian format (WTF) - for(size_t i = 0; i != part_size / 2; ++i) - { - std::swap(bits[i], bits[part_size-1-i]); - std::swap(bits[part_size+i], bits[2*part_size-1-i]); - } - - BigInt x(&bits[0], part_size); - BigInt y(&bits[part_size], part_size); - - public_key = PointGFp(domain().get_curve(), x, y); - - BOTAN_ASSERT(public_key.on_the_curve(), - "Loaded GOST 34.10 public key not on the curve"); - } - -namespace { - -BigInt decode_le(const byte msg[], size_t msg_len) - { - SecureVector msg_le(msg, msg_len); - - for(size_t i = 0; i != msg_le.size() / 2; ++i) - std::swap(msg_le[i], msg_le[msg_le.size()-1-i]); - - return BigInt(&msg_le[0], msg_le.size()); - } - -} - -GOST_3410_Signature_Operation::GOST_3410_Signature_Operation( - const GOST_3410_PrivateKey& gost_3410) : - - base_point(gost_3410.domain().get_base_point()), - order(gost_3410.domain().get_order()), - x(gost_3410.private_value()) - { - } - -SecureVector -GOST_3410_Signature_Operation::sign(const byte msg[], size_t msg_len, - RandomNumberGenerator& rng) - { - BigInt k; - do - k.randomize(rng, order.bits()-1); - while(k >= order); - - BigInt e = decode_le(msg, msg_len); - - e %= order; - if(e == 0) - e = 1; - - PointGFp k_times_P = base_point * k; - - BOTAN_ASSERT(k_times_P.on_the_curve(), - "GOST 34.10 k*g not on the curve"); - - BigInt r = k_times_P.get_affine_x() % order; - - BigInt s = (r*x + k*e) % order; - - if(r == 0 || s == 0) - throw Invalid_State("GOST 34.10: r == 0 || s == 0"); - - SecureVector output(2*order.bytes()); - s.binary_encode(&output[output.size() / 2 - s.bytes()]); - r.binary_encode(&output[output.size() - r.bytes()]); - return output; - } - -GOST_3410_Verification_Operation::GOST_3410_Verification_Operation(const GOST_3410_PublicKey& gost) : - base_point(gost.domain().get_base_point()), - public_point(gost.public_point()), - order(gost.domain().get_order()) - { - } - -bool GOST_3410_Verification_Operation::verify(const byte msg[], size_t msg_len, - const byte sig[], size_t sig_len) - { - if(sig_len != order.bytes()*2) - return false; - - BigInt e = decode_le(msg, msg_len); - - BigInt s(sig, sig_len / 2); - BigInt r(sig + sig_len / 2, sig_len / 2); - - if(r <= 0 || r >= order || s <= 0 || s >= order) - return false; - - e %= order; - if(e == 0) - e = 1; - - BigInt v = inverse_mod(e, order); - - BigInt z1 = (s*v) % order; - BigInt z2 = (-r*v) % order; - - PointGFp R = multi_exponentiate(base_point, z1, - public_point, z2); - - if(R.is_zero()) - return false; - - return (R.get_affine_x() == r); - } - -} -/* -* IF Scheme -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -AlgorithmIdentifier IF_Scheme_PublicKey::algorithm_identifier() const - { - return AlgorithmIdentifier(get_oid(), - AlgorithmIdentifier::USE_NULL_PARAM); - } - -MemoryVector IF_Scheme_PublicKey::x509_subject_public_key() const - { - return DER_Encoder() - .start_cons(SEQUENCE) - .encode(n) - .encode(e) - .end_cons() - .get_contents(); - } - -IF_Scheme_PublicKey::IF_Scheme_PublicKey(const AlgorithmIdentifier&, - const MemoryRegion& key_bits) - { - BER_Decoder(key_bits) - .start_cons(SEQUENCE) - .decode(n) - .decode(e) - .verify_end() - .end_cons(); - } - -/* -* Check IF Scheme Public Parameters -*/ -bool IF_Scheme_PublicKey::check_key(RandomNumberGenerator&, bool) const - { - if(n < 35 || n.is_even() || e < 2) - return false; - return true; - } - -MemoryVector IF_Scheme_PrivateKey::pkcs8_private_key() const - { - return DER_Encoder() - .start_cons(SEQUENCE) - .encode(static_cast(0)) - .encode(n) - .encode(e) - .encode(d) - .encode(p) - .encode(q) - .encode(d1) - .encode(d2) - .encode(c) - .end_cons() - .get_contents(); - } - -IF_Scheme_PrivateKey::IF_Scheme_PrivateKey(RandomNumberGenerator& rng, - const AlgorithmIdentifier&, - const MemoryRegion& key_bits) - { - BER_Decoder(key_bits) - .start_cons(SEQUENCE) - .decode_and_check(0, "Unknown PKCS #1 key format version") - .decode(n) - .decode(e) - .decode(d) - .decode(p) - .decode(q) - .decode(d1) - .decode(d2) - .decode(c) - .end_cons(); - - load_check(rng); - } - -IF_Scheme_PrivateKey::IF_Scheme_PrivateKey(RandomNumberGenerator& rng, - const BigInt& prime1, - const BigInt& prime2, - const BigInt& exp, - const BigInt& d_exp, - const BigInt& mod) - { - p = prime1; - q = prime2; - e = exp; - d = d_exp; - n = mod.is_nonzero() ? mod : p * q; - - if(d == 0) - { - BigInt inv_for_d = lcm(p - 1, q - 1); - if(e.is_even()) - inv_for_d >>= 1; - - d = inverse_mod(e, inv_for_d); - } - - d1 = d % (p - 1); - d2 = d % (q - 1); - c = inverse_mod(q, p); - - load_check(rng); - } - -/* -* Check IF Scheme Private Parameters -*/ -bool IF_Scheme_PrivateKey::check_key(RandomNumberGenerator& rng, - bool strong) const - { - if(n < 35 || n.is_even() || e < 2 || d < 2 || p < 3 || q < 3 || p*q != n) - return false; - - if(!strong) - return true; - - if(d1 != d % (p - 1) || d2 != d % (q - 1) || c != inverse_mod(q, p)) - return false; - if(!check_prime(p, rng) || !check_prime(q, rng)) - return false; - return true; - } - -} -/* -* Keypair Checks -* (C) 1999-2010 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -namespace KeyPair { - -/* -* Check an encryption key pair for consistency -*/ -bool encryption_consistency_check(RandomNumberGenerator& rng, - const Private_Key& key, - const std::string& padding) - { - PK_Encryptor_EME encryptor(key, padding); - PK_Decryptor_EME decryptor(key, padding); - - /* - Weird corner case, if the key is too small to encrypt anything at - all. This can happen with very small RSA keys with PSS - */ - if(encryptor.maximum_input_size() == 0) - return true; - - SecureVector plaintext = - rng.random_vec(encryptor.maximum_input_size() - 1); - - SecureVector ciphertext = encryptor.encrypt(plaintext, rng); - if(ciphertext == plaintext) - return false; - - SecureVector decrypted = decryptor.decrypt(ciphertext); - - return (plaintext == decrypted); - } - -/* -* Check a signature key pair for consistency -*/ -bool signature_consistency_check(RandomNumberGenerator& rng, - const Private_Key& key, - const std::string& padding) - { - PK_Signer signer(key, padding); - PK_Verifier verifier(key, padding); - - SecureVector message = rng.random_vec(16); - - SecureVector signature; - - try - { - signature = signer.sign_message(message, rng); - } - catch(Encoding_Error) - { - return false; - } - - if(!verifier.verify_message(message, signature)) - return false; - - // Now try to check a corrupt signature, ensure it does not succeed - ++message[0]; - - if(verifier.verify_message(message, signature)) - return false; - - return true; - } - -} - -} -/* -* Nyberg-Rueppel -* (C) 1999-2010 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -NR_PublicKey::NR_PublicKey(const AlgorithmIdentifier& alg_id, - const MemoryRegion& key_bits) : - DL_Scheme_PublicKey(alg_id, key_bits, DL_Group::ANSI_X9_57) - { - } - -/* -* NR_PublicKey Constructor -*/ -NR_PublicKey::NR_PublicKey(const DL_Group& grp, const BigInt& y1) - { - group = grp; - y = y1; - } - -/* -* Create a NR private key -*/ -NR_PrivateKey::NR_PrivateKey(RandomNumberGenerator& rng, - const DL_Group& grp, - const BigInt& x_arg) - { - group = grp; - x = x_arg; - - if(x == 0) - x = BigInt::random_integer(rng, 2, group_q() - 1); - - y = power_mod(group_g(), x, group_p()); - - if(x_arg == 0) - gen_check(rng); - else - load_check(rng); - } - -NR_PrivateKey::NR_PrivateKey(const AlgorithmIdentifier& alg_id, - const MemoryRegion& key_bits, - RandomNumberGenerator& rng) : - DL_Scheme_PrivateKey(alg_id, key_bits, DL_Group::ANSI_X9_57) - { - y = power_mod(group_g(), x, group_p()); - - load_check(rng); - } - -/* -* Check Private Nyberg-Rueppel Parameters -*/ -bool NR_PrivateKey::check_key(RandomNumberGenerator& rng, bool strong) const - { - if(!DL_Scheme_PrivateKey::check_key(rng, strong) || x >= group_q()) - return false; - - if(!strong) - return true; - - return KeyPair::signature_consistency_check(rng, *this, "EMSA1(SHA-1)"); - } - -NR_Signature_Operation::NR_Signature_Operation(const NR_PrivateKey& nr) : - q(nr.group_q()), - x(nr.get_x()), - powermod_g_p(nr.group_g(), nr.group_p()), - mod_q(nr.group_q()) - { - } - -SecureVector -NR_Signature_Operation::sign(const byte msg[], size_t msg_len, - RandomNumberGenerator& rng) - { - rng.add_entropy(msg, msg_len); - - BigInt f(msg, msg_len); - - if(f >= q) - throw Invalid_Argument("NR_Signature_Operation: Input is out of range"); - - BigInt c, d; - - while(c == 0) - { - BigInt k; - do - k.randomize(rng, q.bits()); - while(k >= q); - - c = mod_q.reduce(powermod_g_p(k) + f); - d = mod_q.reduce(k - x * c); - } - - SecureVector output(2*q.bytes()); - c.binary_encode(&output[output.size() / 2 - c.bytes()]); - d.binary_encode(&output[output.size() - d.bytes()]); - return output; - } - -NR_Verification_Operation::NR_Verification_Operation(const NR_PublicKey& nr) : - q(nr.group_q()), y(nr.get_y()) - { - powermod_g_p = Fixed_Base_Power_Mod(nr.group_g(), nr.group_p()); - powermod_y_p = Fixed_Base_Power_Mod(y, nr.group_p()); - mod_p = Modular_Reducer(nr.group_p()); - mod_q = Modular_Reducer(nr.group_q()); - } - -SecureVector -NR_Verification_Operation::verify_mr(const byte msg[], size_t msg_len) - { - const BigInt& q = mod_q.get_modulus(); - - if(msg_len != 2*q.bytes()) - throw Invalid_Argument("NR verification: Invalid signature"); - - BigInt c(msg, q.bytes()); - BigInt d(msg + q.bytes(), q.bytes()); - - if(c.is_zero() || c >= q || d >= q) - throw Invalid_Argument("NR verification: Invalid signature"); - - BigInt i = mod_p.multiply(powermod_g_p(d), powermod_y_p(c)); - return BigInt::encode(mod_q.reduce(c - i)); - } - -} -/* -* PK Key -* (C) 1999-2010 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -#if defined(BOTAN_HAS_RSA) -#endif - -#if defined(BOTAN_HAS_DSA) -#endif - -#if defined(BOTAN_HAS_DIFFIE_HELLMAN) -#endif - -#if defined(BOTAN_HAS_ECDSA) -#endif - -#if defined(BOTAN_HAS_GOST_34_10_2001) -#endif - -#if defined(BOTAN_HAS_NYBERG_RUEPPEL) -#endif - -#if defined(BOTAN_HAS_RW) -#endif - -#if defined(BOTAN_HAS_ELGAMAL) -#endif - -#if defined(BOTAN_HAS_ECDH) -#endif - -namespace Botan { - -Public_Key* make_public_key(const AlgorithmIdentifier& alg_id, - const MemoryRegion& key_bits) - { - const std::string alg_name = OIDS::lookup(alg_id.oid); - if(alg_name == "") - throw Decoding_Error("Unknown algorithm OID: " + alg_id.oid.as_string()); - -#if defined(BOTAN_HAS_RSA) - if(alg_name == "RSA") - return new RSA_PublicKey(alg_id, key_bits); -#endif - -#if defined(BOTAN_HAS_RW) - if(alg_name == "RW") - return new RW_PublicKey(alg_id, key_bits); -#endif - -#if defined(BOTAN_HAS_DSA) - if(alg_name == "DSA") - return new DSA_PublicKey(alg_id, key_bits); -#endif - -#if defined(BOTAN_HAS_DIFFIE_HELLMAN) - if(alg_name == "DH") - return new DH_PublicKey(alg_id, key_bits); -#endif - -#if defined(BOTAN_HAS_NYBERG_RUEPPEL) - if(alg_name == "NR") - return new NR_PublicKey(alg_id, key_bits); -#endif - -#if defined(BOTAN_HAS_ELGAMAL) - if(alg_name == "ElGamal") - return new ElGamal_PublicKey(alg_id, key_bits); -#endif - -#if defined(BOTAN_HAS_ECDSA) - if(alg_name == "ECDSA") - return new ECDSA_PublicKey(alg_id, key_bits); -#endif - -#if defined(BOTAN_HAS_GOST_34_10_2001) - if(alg_name == "GOST-34.10") - return new GOST_3410_PublicKey(alg_id, key_bits); -#endif - -#if defined(BOTAN_HAS_ECDH) - if(alg_name == "ECDH") - return new ECDH_PublicKey(alg_id, key_bits); -#endif - - return 0; - } - -Private_Key* make_private_key(const AlgorithmIdentifier& alg_id, - const MemoryRegion& key_bits, - RandomNumberGenerator& rng) - { - const std::string alg_name = OIDS::lookup(alg_id.oid); - if(alg_name == "") - throw Decoding_Error("Unknown algorithm OID: " + alg_id.oid.as_string()); - -#if defined(BOTAN_HAS_RSA) - if(alg_name == "RSA") - return new RSA_PrivateKey(alg_id, key_bits, rng); -#endif - -#if defined(BOTAN_HAS_RW) - if(alg_name == "RW") - return new RW_PrivateKey(alg_id, key_bits, rng); -#endif - -#if defined(BOTAN_HAS_DSA) - if(alg_name == "DSA") - return new DSA_PrivateKey(alg_id, key_bits, rng); -#endif - -#if defined(BOTAN_HAS_DIFFIE_HELLMAN) - if(alg_name == "DH") - return new DH_PrivateKey(alg_id, key_bits, rng); -#endif - -#if defined(BOTAN_HAS_NYBERG_RUEPPEL) - if(alg_name == "NR") - return new NR_PrivateKey(alg_id, key_bits, rng); -#endif - -#if defined(BOTAN_HAS_ELGAMAL) - if(alg_name == "ElGamal") - return new ElGamal_PrivateKey(alg_id, key_bits, rng); -#endif - -#if defined(BOTAN_HAS_ECDSA) - if(alg_name == "ECDSA") - return new ECDSA_PrivateKey(alg_id, key_bits); -#endif - -#if defined(BOTAN_HAS_GOST_34_10_2001) - if(alg_name == "GOST-34.10") - return new GOST_3410_PrivateKey(alg_id, key_bits); -#endif - -#if defined(BOTAN_HAS_ECDH) - if(alg_name == "ECDH") - return new ECDH_PrivateKey(alg_id, key_bits); -#endif - - return 0; - } - -} -/* -* PK Key Types -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -/* -* Default OID access -*/ -OID Public_Key::get_oid() const - { - try { - return OIDS::lookup(algo_name()); - } - catch(Lookup_Error) - { - throw Lookup_Error("PK algo " + algo_name() + " has no defined OIDs"); - } - } - -/* -* Run checks on a loaded public key -*/ -void Public_Key::load_check(RandomNumberGenerator& rng) const - { - if(!check_key(rng, BOTAN_PUBLIC_KEY_STRONG_CHECKS_ON_LOAD)) - throw Invalid_Argument(algo_name() + ": Invalid public key"); - } - -/* -* Run checks on a loaded private key -*/ -void Private_Key::load_check(RandomNumberGenerator& rng) const - { - if(!check_key(rng, BOTAN_PRIVATE_KEY_STRONG_CHECKS_ON_LOAD)) - throw Invalid_Argument(algo_name() + ": Invalid private key"); - } - -/* -* Run checks on a generated private key -*/ -void Private_Key::gen_check(RandomNumberGenerator& rng) const - { - if(!check_key(rng, BOTAN_PRIVATE_KEY_STRONG_CHECKS_ON_GENERATE)) - throw Self_Test_Failure(algo_name() + " private key generation failed"); - } - -} -/* -* PKCS #8 -* (C) 1999-2010 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include - -namespace Botan { - -namespace PKCS8 { - -namespace { - -/* -* Get info from an EncryptedPrivateKeyInfo -*/ -SecureVector PKCS8_extract(DataSource& source, - AlgorithmIdentifier& pbe_alg_id) - { - SecureVector key_data; - - BER_Decoder(source) - .start_cons(SEQUENCE) - .decode(pbe_alg_id) - .decode(key_data, OCTET_STRING) - .verify_end(); - - return key_data; - } - -/* -* PEM decode and/or decrypt a private key -*/ -SecureVector PKCS8_decode(DataSource& source, const User_Interface& ui, - AlgorithmIdentifier& pk_alg_id) - { - AlgorithmIdentifier pbe_alg_id; - SecureVector key_data, key; - bool is_encrypted = true; - - try { - if(ASN1::maybe_BER(source) && !PEM_Code::matches(source)) - key_data = PKCS8_extract(source, pbe_alg_id); - else - { - std::string label; - key_data = PEM_Code::decode(source, label); - if(label == "PRIVATE KEY") - is_encrypted = false; - else if(label == "ENCRYPTED PRIVATE KEY") - { - DataSource_Memory key_source(key_data); - key_data = PKCS8_extract(key_source, pbe_alg_id); - } - else - throw PKCS8_Exception("Unknown PEM label " + label); - } - - if(key_data.empty()) - throw PKCS8_Exception("No key data found"); - } - catch(Decoding_Error) - { - throw Decoding_Error("PKCS #8 private key decoding failed"); - } - - if(!is_encrypted) - key = key_data; - - const size_t MAX_TRIES = 3; - - size_t tries = 0; - while(true) - { - try { - if(MAX_TRIES && tries >= MAX_TRIES) - break; - - if(is_encrypted) - { - DataSource_Memory params(pbe_alg_id.parameters); - std::unique_ptr pbe(get_pbe(pbe_alg_id.oid, params)); - - User_Interface::UI_Result result = User_Interface::OK; - const std::string passphrase = - ui.get_passphrase("PKCS #8 private key", source.id(), result); - - if(result == User_Interface::CANCEL_ACTION) - break; - - pbe->set_key(passphrase); - Pipe decryptor(pbe.release()); - - decryptor.process_msg(key_data); - key = decryptor.read_all(); - } - - BER_Decoder(key) - .start_cons(SEQUENCE) - .decode_and_check(0, "Unknown PKCS #8 version number") - .decode(pk_alg_id) - .decode(key, OCTET_STRING) - .discard_remaining() - .end_cons(); - - break; - } - catch(Decoding_Error) - { - ++tries; - } - } - - if(key.empty()) - throw Decoding_Error("PKCS #8 private key decoding failed"); - return key; - } - -} - -/* -* BER encode a PKCS #8 private key, unencrypted -*/ -SecureVector BER_encode(const Private_Key& key) - { - const size_t PKCS8_VERSION = 0; - - return DER_Encoder() - .start_cons(SEQUENCE) - .encode(PKCS8_VERSION) - .encode(key.pkcs8_algorithm_identifier()) - .encode(key.pkcs8_private_key(), OCTET_STRING) - .end_cons() - .get_contents(); - } - -/* -* PEM encode a PKCS #8 private key, unencrypted -*/ -std::string PEM_encode(const Private_Key& key) - { - return PEM_Code::encode(PKCS8::BER_encode(key), "PRIVATE KEY"); - } - -/* -* BER encode a PKCS #8 private key, encrypted -*/ -SecureVector BER_encode(const Private_Key& key, - RandomNumberGenerator& rng, - const std::string& pass, - const std::string& pbe_algo) - { - const std::string DEFAULT_PBE = "PBE-PKCS5v20(SHA-1,AES-256/CBC)"; - - std::unique_ptr pbe(get_pbe(((pbe_algo != "") ? pbe_algo : DEFAULT_PBE))); - - pbe->new_params(rng); - pbe->set_key(pass); - - AlgorithmIdentifier pbe_algid(pbe->get_oid(), pbe->encode_params()); - - Pipe key_encrytor(pbe.release()); - key_encrytor.process_msg(PKCS8::BER_encode(key)); - - return DER_Encoder() - .start_cons(SEQUENCE) - .encode(pbe_algid) - .encode(key_encrytor.read_all(), OCTET_STRING) - .end_cons() - .get_contents(); - } - -/* -* PEM encode a PKCS #8 private key, encrypted -*/ -std::string PEM_encode(const Private_Key& key, - RandomNumberGenerator& rng, - const std::string& pass, - const std::string& pbe_algo) - { - if(pass == "") - return PEM_encode(key); - - return PEM_Code::encode(PKCS8::BER_encode(key, rng, pass, pbe_algo), - "ENCRYPTED PRIVATE KEY"); - } - -/* -* Extract a private key and return it -*/ -Private_Key* load_key(DataSource& source, - RandomNumberGenerator& rng, - const User_Interface& ui) - { - AlgorithmIdentifier alg_id; - SecureVector pkcs8_key = PKCS8_decode(source, ui, alg_id); - - const std::string alg_name = OIDS::lookup(alg_id.oid); - if(alg_name == "" || alg_name == alg_id.oid.as_string()) - throw PKCS8_Exception("Unknown algorithm OID: " + - alg_id.oid.as_string()); - - return make_private_key(alg_id, pkcs8_key, rng); - } - -/* -* Extract a private key and return it -*/ -Private_Key* load_key(const std::string& fsname, - RandomNumberGenerator& rng, - const User_Interface& ui) - { - DataSource_Stream source(fsname, true); - return PKCS8::load_key(source, rng, ui); - } - -/* -* Extract a private key and return it -*/ -Private_Key* load_key(DataSource& source, - RandomNumberGenerator& rng, - const std::string& pass) - { - return PKCS8::load_key(source, rng, User_Interface(pass)); - } - -/* -* Extract a private key and return it -*/ -Private_Key* load_key(const std::string& fsname, - RandomNumberGenerator& rng, - const std::string& pass) - { - return PKCS8::load_key(fsname, rng, User_Interface(pass)); - } - -/* -* Make a copy of this private key -*/ -Private_Key* copy_key(const Private_Key& key, - RandomNumberGenerator& rng) - { - DataSource_Memory source(PEM_encode(key)); - return PKCS8::load_key(source, rng); - } - -} - -} -/* -* Public Key Base -* (C) 1999-2010 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include - -namespace Botan { - -/* -* PK_Encryptor_EME Constructor -*/ -PK_Encryptor_EME::PK_Encryptor_EME(const Public_Key& key, - const std::string& eme_name) - { - Algorithm_Factory::Engine_Iterator i(global_state().algorithm_factory()); - - op = 0; - - while(const Engine* engine = i.next()) - { - op = engine->get_encryption_op(key); - if(op) - break; - } - - if(!op) - throw Lookup_Error("PK_Encryptor_EME: No working engine for " + - key.algo_name()); - - eme = (eme_name == "Raw") ? 0 : get_eme(eme_name); - } - -/* -* Encrypt a message -*/ -SecureVector -PK_Encryptor_EME::enc(const byte in[], - size_t length, - RandomNumberGenerator& rng) const - { - if(eme) - { - SecureVector encoded = - eme->encode(in, length, op->max_input_bits(), rng); - - if(8*(encoded.size() - 1) + high_bit(encoded[0]) > op->max_input_bits()) - throw Invalid_Argument("PK_Encryptor_EME: Input is too large"); - - return op->encrypt(&encoded[0], encoded.size(), rng); - } - else - { - if(8*(length - 1) + high_bit(in[0]) > op->max_input_bits()) - throw Invalid_Argument("PK_Encryptor_EME: Input is too large"); - - return op->encrypt(&in[0], length, rng); - } - } - -/* -* Return the max size, in bytes, of a message -*/ -size_t PK_Encryptor_EME::maximum_input_size() const - { - if(!eme) - return (op->max_input_bits() / 8); - else - return eme->maximum_input_size(op->max_input_bits()); - } - -/* -* PK_Decryptor_EME Constructor -*/ -PK_Decryptor_EME::PK_Decryptor_EME(const Private_Key& key, - const std::string& eme_name) - { - Algorithm_Factory::Engine_Iterator i(global_state().algorithm_factory()); - - op = 0; - - while(const Engine* engine = i.next()) - { - op = engine->get_decryption_op(key); - if(op) - break; - } - - if(!op) - throw Lookup_Error("PK_Decryptor_EME: No working engine for " + - key.algo_name()); - - eme = (eme_name == "Raw") ? 0 : get_eme(eme_name); - } - -/* -* Decrypt a message -*/ -SecureVector PK_Decryptor_EME::dec(const byte msg[], - size_t length) const - { - try { - SecureVector decrypted = op->decrypt(msg, length); - if(eme) - return eme->decode(decrypted, op->max_input_bits()); - else - return decrypted; - } - catch(Invalid_Argument) - { - throw Decoding_Error("PK_Decryptor_EME: Input is invalid"); - } - } - -/* -* PK_Signer Constructor -*/ -PK_Signer::PK_Signer(const Private_Key& key, - const std::string& emsa_name, - Signature_Format format, - Fault_Protection prot) - { - Algorithm_Factory::Engine_Iterator i(global_state().algorithm_factory()); - - op = 0; - verify_op = 0; - - while(const Engine* engine = i.next()) - { - if(!op) - op = engine->get_signature_op(key); - - if(!verify_op && prot == ENABLE_FAULT_PROTECTION) - verify_op = engine->get_verify_op(key); - - if(op && (verify_op || prot == DISABLE_FAULT_PROTECTION)) - break; - } - - if(!op || (!verify_op && prot == ENABLE_FAULT_PROTECTION)) - throw Lookup_Error("PK_Signer: No working engine for " + - key.algo_name()); - - emsa = get_emsa(emsa_name); - sig_format = format; - } - -/* -* Sign a message -*/ -SecureVector PK_Signer::sign_message(const byte msg[], size_t length, - RandomNumberGenerator& rng) - { - update(msg, length); - return signature(rng); - } - -/* -* Add more to the message to be signed -*/ -void PK_Signer::update(const byte in[], size_t length) - { - emsa->update(in, length); - } - -/* -* Check the signature we just created, to help prevent fault attacks -*/ -bool PK_Signer::self_test_signature(const MemoryRegion& msg, - const MemoryRegion& sig) const - { - if(!verify_op) - return true; // checking disabled, assume ok - - if(verify_op->with_recovery()) - { - SecureVector recovered = - verify_op->verify_mr(&sig[0], sig.size()); - - if(msg.size() > recovered.size()) - { - size_t extra_0s = msg.size() - recovered.size(); - - for(size_t i = 0; i != extra_0s; ++i) - if(msg[i] != 0) - return false; - - return same_mem(&msg[extra_0s], &recovered[0], recovered.size()); - } - - return (recovered == msg); - } - else - return verify_op->verify(&msg[0], msg.size(), - &sig[0], sig.size()); - } - -/* -* Create a signature -*/ -SecureVector PK_Signer::signature(RandomNumberGenerator& rng) - { - SecureVector encoded = emsa->encoding_of(emsa->raw_data(), - op->max_input_bits(), - rng); - - SecureVector plain_sig = op->sign(&encoded[0], encoded.size(), rng); - - BOTAN_ASSERT(self_test_signature(encoded, plain_sig), - "PK_Signer consistency check failed"); - - if(op->message_parts() == 1 || sig_format == IEEE_1363) - return plain_sig; - - if(sig_format == DER_SEQUENCE) - { - if(plain_sig.size() % op->message_parts()) - throw Encoding_Error("PK_Signer: strange signature size found"); - const size_t SIZE_OF_PART = plain_sig.size() / op->message_parts(); - - std::vector sig_parts(op->message_parts()); - for(size_t j = 0; j != sig_parts.size(); ++j) - sig_parts[j].binary_decode(&plain_sig[SIZE_OF_PART*j], SIZE_OF_PART); - - return DER_Encoder() - .start_cons(SEQUENCE) - .encode_list(sig_parts) - .end_cons() - .get_contents(); - } - else - throw Encoding_Error("PK_Signer: Unknown signature format " + - to_string(sig_format)); - } - -/* -* PK_Verifier Constructor -*/ -PK_Verifier::PK_Verifier(const Public_Key& key, - const std::string& emsa_name, - Signature_Format format) - { - Algorithm_Factory::Engine_Iterator i(global_state().algorithm_factory()); - - op = 0; - - while(const Engine* engine = i.next()) - { - op = engine->get_verify_op(key); - if(op) - break; - } - - if(!op) - throw Lookup_Error("PK_Verifier: No working engine for " + - key.algo_name()); - - emsa = get_emsa(emsa_name); - sig_format = format; - } - -/* -* Set the signature format -*/ -void PK_Verifier::set_input_format(Signature_Format format) - { - if(op->message_parts() == 1 && format != IEEE_1363) - throw Invalid_State("PK_Verifier: This algorithm always uses IEEE 1363"); - sig_format = format; - } - -/* -* Verify a message -*/ -bool PK_Verifier::verify_message(const byte msg[], size_t msg_length, - const byte sig[], size_t sig_length) - { - update(msg, msg_length); - return check_signature(sig, sig_length); - } - -/* -* Append to the message -*/ -void PK_Verifier::update(const byte in[], size_t length) - { - emsa->update(in, length); - } - -/* -* Check a signature -*/ -bool PK_Verifier::check_signature(const byte sig[], size_t length) - { - try { - if(sig_format == IEEE_1363) - return validate_signature(emsa->raw_data(), sig, length); - else if(sig_format == DER_SEQUENCE) - { - BER_Decoder decoder(sig, length); - BER_Decoder ber_sig = decoder.start_cons(SEQUENCE); - - size_t count = 0; - SecureVector real_sig; - while(ber_sig.more_items()) - { - BigInt sig_part; - ber_sig.decode(sig_part); - real_sig += BigInt::encode_1363(sig_part, op->message_part_size()); - ++count; - } - - if(count != op->message_parts()) - throw Decoding_Error("PK_Verifier: signature size invalid"); - - return validate_signature(emsa->raw_data(), - &real_sig[0], real_sig.size()); - } - else - throw Decoding_Error("PK_Verifier: Unknown signature format " + - to_string(sig_format)); - } - catch(Invalid_Argument) { return false; } - } - -/* -* Verify a signature -*/ -bool PK_Verifier::validate_signature(const MemoryRegion& msg, - const byte sig[], size_t sig_len) - { - if(op->with_recovery()) - { - SecureVector output_of_key = op->verify_mr(sig, sig_len); - return emsa->verify(output_of_key, msg, op->max_input_bits()); - } - else - { - Null_RNG rng; - - SecureVector encoded = - emsa->encoding_of(msg, op->max_input_bits(), rng); - - return op->verify(&encoded[0], encoded.size(), sig, sig_len); - } - } - -/* -* PK_Key_Agreement Constructor -*/ -PK_Key_Agreement::PK_Key_Agreement(const PK_Key_Agreement_Key& key, - const std::string& kdf_name) - { - Algorithm_Factory::Engine_Iterator i(global_state().algorithm_factory()); - - op = 0; - - while(const Engine* engine = i.next()) - { - op = engine->get_key_agreement_op(key); - if(op) - break; - } - - if(!op) - throw Lookup_Error("PK_Key_Agreement: No working engine for " + - key.algo_name()); - - kdf = (kdf_name == "Raw") ? 0 : get_kdf(kdf_name); - } - -SymmetricKey PK_Key_Agreement::derive_key(size_t key_len, const byte in[], - size_t in_len, const byte params[], - size_t params_len) const - { - SecureVector z = op->agree(in, in_len); - - if(!kdf) - return z; - - return kdf->derive_key(key_len, z, params, params_len); - } - -} -/* -* KeyUsage -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -namespace BER { - -/* -* Decode a BER encoded KeyUsage -*/ -void decode(BER_Decoder& source, Key_Constraints& key_usage) - { - BER_Object obj = source.get_next_object(); - - if(obj.type_tag != BIT_STRING || obj.class_tag != UNIVERSAL) - throw BER_Bad_Tag("Bad tag for usage constraint", - obj.type_tag, obj.class_tag); - if(obj.value.size() != 2 && obj.value.size() != 3) - throw BER_Decoding_Error("Bad size for BITSTRING in usage constraint"); - if(obj.value[0] >= 8) - throw BER_Decoding_Error("Invalid unused bits in usage constraint"); - - const byte mask = (0xFF << obj.value[0]); - obj.value[obj.value.size()-1] &= mask; - - u16bit usage = 0; - for(size_t j = 1; j != obj.value.size(); ++j) - usage = (obj.value[j] << 8) | usage; - - key_usage = Key_Constraints(usage); - } - -} - -} -/* -* RSA -* (C) 1999-2010 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -/* -* Create a RSA private key -*/ -RSA_PrivateKey::RSA_PrivateKey(RandomNumberGenerator& rng, - size_t bits, size_t exp) - { - if(bits < 512) - throw Invalid_Argument(algo_name() + ": Can't make a key that is only " + - to_string(bits) + " bits long"); - if(exp < 3 || exp % 2 == 0) - throw Invalid_Argument(algo_name() + ": Invalid encryption exponent"); - - e = exp; - - do - { - p = random_prime(rng, (bits + 1) / 2, e); - q = random_prime(rng, bits - p.bits(), e); - n = p * q; - } while(n.bits() != bits); - - d = inverse_mod(e, lcm(p - 1, q - 1)); - d1 = d % (p - 1); - d2 = d % (q - 1); - c = inverse_mod(q, p); - - gen_check(rng); - } - -/* -* Check Private RSA Parameters -*/ -bool RSA_PrivateKey::check_key(RandomNumberGenerator& rng, bool strong) const - { - if(!IF_Scheme_PrivateKey::check_key(rng, strong)) - return false; - - if(!strong) - return true; - - if((e * d) % lcm(p - 1, q - 1) != 1) - return false; - - return KeyPair::signature_consistency_check(rng, *this, "EMSA4(SHA-1)"); - } - -RSA_Private_Operation::RSA_Private_Operation(const RSA_PrivateKey& rsa) : - n(rsa.get_n()), - q(rsa.get_q()), - c(rsa.get_c()), - powermod_e_n(rsa.get_e(), rsa.get_n()), - powermod_d1_p(rsa.get_d1(), rsa.get_p()), - powermod_d2_q(rsa.get_d2(), rsa.get_q()), - mod_p(rsa.get_p()) - { - BigInt k(global_state().global_rng(), n.bits() - 1); - blinder = Blinder(powermod_e_n(k), inverse_mod(k, n), n); - } - -BigInt RSA_Private_Operation::private_op(const BigInt& m) const - { - if(m >= n) - throw Invalid_Argument("RSA private op - input is too large"); - - BigInt j1 = powermod_d1_p(m); - BigInt j2 = powermod_d2_q(m); - - j1 = mod_p.reduce(sub_mul(j1, j2, c)); - - return mul_add(j1, q, j2); - } - -SecureVector -RSA_Private_Operation::sign(const byte msg[], size_t msg_len, - RandomNumberGenerator&) - { - /* We don't check signatures against powermod_e_n here because - PK_Signer checks verification consistency for all signature - algorithms. - */ - - BigInt m(msg, msg_len); - BigInt x = blinder.unblind(private_op(blinder.blind(m))); - return BigInt::encode_1363(x, n.bytes()); - } - -/* -* RSA Decryption Operation -*/ -SecureVector -RSA_Private_Operation::decrypt(const byte msg[], size_t msg_len) - { - BigInt m(msg, msg_len); - BigInt x = blinder.unblind(private_op(blinder.blind(m))); - - BOTAN_ASSERT(m == powermod_e_n(x), - "RSA private op failed consistency check"); - - return BigInt::encode(x); - } - -} -/* -* Rabin-Williams -* (C) 1999-2008 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include - -namespace Botan { - -/* -* Create a Rabin-Williams private key -*/ -RW_PrivateKey::RW_PrivateKey(RandomNumberGenerator& rng, - size_t bits, size_t exp) - { - if(bits < 512) - throw Invalid_Argument(algo_name() + ": Can't make a key that is only " + - to_string(bits) + " bits long"); - if(exp < 2 || exp % 2 == 1) - throw Invalid_Argument(algo_name() + ": Invalid encryption exponent"); - - e = exp; - - do - { - p = random_prime(rng, (bits + 1) / 2, e / 2, 3, 4); - q = random_prime(rng, bits - p.bits(), e / 2, ((p % 8 == 3) ? 7 : 3), 8); - n = p * q; - } while(n.bits() != bits); - - d = inverse_mod(e, lcm(p - 1, q - 1) >> 1); - d1 = d % (p - 1); - d2 = d % (q - 1); - c = inverse_mod(q, p); - - gen_check(rng); - } - -/* -* Check Private Rabin-Williams Parameters -*/ -bool RW_PrivateKey::check_key(RandomNumberGenerator& rng, bool strong) const - { - if(!IF_Scheme_PrivateKey::check_key(rng, strong)) - return false; - - if(!strong) - return true; - - if((e * d) % (lcm(p - 1, q - 1) / 2) != 1) - return false; - - return KeyPair::signature_consistency_check(rng, *this, "EMSA2(SHA-1)"); - } - -RW_Signature_Operation::RW_Signature_Operation(const RW_PrivateKey& rw) : - n(rw.get_n()), - e(rw.get_e()), - q(rw.get_q()), - c(rw.get_c()), - powermod_d1_p(rw.get_d1(), rw.get_p()), - powermod_d2_q(rw.get_d2(), rw.get_q()), - mod_p(rw.get_p()) - { - } - -SecureVector -RW_Signature_Operation::sign(const byte msg[], size_t msg_len, - RandomNumberGenerator& rng) - { - if(!blinder.initialized()) - { - BigInt k(rng, n.bits() / 2); - blinder = Blinder(power_mod(k, e, n), inverse_mod(k, n), n); - } - - BigInt i(msg, msg_len); - - if(i >= n || i % 16 != 12) - throw Invalid_Argument("Rabin-Williams: invalid input"); - - if(jacobi(i, n) != 1) - i >>= 1; - - i = blinder.blind(i); - - BigInt j1 = powermod_d1_p(i); - BigInt j2 = powermod_d2_q(i); - j1 = mod_p.reduce(sub_mul(j1, j2, c)); - - BigInt r = blinder.unblind(mul_add(j1, q, j2)); - - r = std::min(r, n - r); - - return BigInt::encode_1363(r, n.bytes()); - } - -SecureVector -RW_Verification_Operation::verify_mr(const byte msg[], size_t msg_len) - { - BigInt m(msg, msg_len); - - if((m > (n >> 1)) || m.is_negative()) - throw Invalid_Argument("RW signature verification: m > n / 2 || m < 0"); - - BigInt r = powermod_e_n(m); - if(r % 16 == 12) - return BigInt::encode(r); - if(r % 8 == 6) - return BigInt::encode(2*r); - - r = n - r; - if(r % 16 == 12) - return BigInt::encode(r); - if(r % 8 == 6) - return BigInt::encode(2*r); - - throw Invalid_Argument("RW signature verification: Invalid signature"); - } - -} -/* -* Public Key Work Factor Functions -* (C) 1999-2007,2012 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include -#include - -namespace Botan { - -size_t dl_work_factor(size_t bits) - { - /* - Based on GNFS work factors. Constant is 1.43 times the asymptotic - value; I'm not sure but I believe that came from a paper on 'real - world' runtimes, but I don't remember where now. - - Sample return values: - |512| -> 64 - |1024| -> 86 - |1536| -> 102 - |2048| -> 116 - |3072| -> 138 - |4096| -> 155 - |8192| -> 206 - - For DL algos, we use an exponent of twice the size of the result; - the assumption is that an arbitrary discrete log on a group of size - bits would take about 2^n effort, and thus using an exponent of - size 2^(2*n) implies that all available attacks are about as easy - (as e.g Pollard's kangaroo algorithm can compute the DL in sqrt(x) - operations) while minimizing the exponent size for performance - reasons. - */ - - const size_t MIN_WORKFACTOR = 64; - - // approximates natural logarithm of p - const double log_p = bits / 1.4426; - - const double strength = - 2.76 * std::pow(log_p, 1.0/3.0) * std::pow(std::log(log_p), 2.0/3.0); - - return std::max(static_cast(strength), MIN_WORKFACTOR); - } - -} -/* -* X.509 Public Key -* (C) 1999-2010 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include - -namespace Botan { - -namespace X509 { - -MemoryVector BER_encode(const Public_Key& key) - { - return DER_Encoder() - .start_cons(SEQUENCE) - .encode(key.algorithm_identifier()) - .encode(key.x509_subject_public_key(), BIT_STRING) - .end_cons() - .get_contents(); - } - -/* -* PEM encode a X.509 public key -*/ -std::string PEM_encode(const Public_Key& key) - { - return PEM_Code::encode(X509::BER_encode(key), - "PUBLIC KEY"); - } - -/* -* Extract a public key and return it -*/ -Public_Key* load_key(DataSource& source) - { - try { - AlgorithmIdentifier alg_id; - MemoryVector key_bits; - - if(ASN1::maybe_BER(source) && !PEM_Code::matches(source)) - { - BER_Decoder(source) - .start_cons(SEQUENCE) - .decode(alg_id) - .decode(key_bits, BIT_STRING) - .verify_end() - .end_cons(); - } - else - { - DataSource_Memory ber( - PEM_Code::decode_check_label(source, "PUBLIC KEY") - ); - - BER_Decoder(ber) - .start_cons(SEQUENCE) - .decode(alg_id) - .decode(key_bits, BIT_STRING) - .verify_end() - .end_cons(); - } - - if(key_bits.empty()) - throw Decoding_Error("X.509 public key decoding failed"); - - return make_public_key(alg_id, key_bits); - } - catch(Decoding_Error) - { - throw Decoding_Error("X.509 public key decoding failed"); - } - } - -/* -* Extract a public key and return it -*/ -Public_Key* load_key(const std::string& fsname) - { - DataSource_Stream source(fsname, true); - return X509::load_key(source); - } - -/* -* Extract a public key and return it -*/ -Public_Key* load_key(const MemoryRegion& mem) - { - DataSource_Memory source(mem); - return X509::load_key(source); - } - -/* -* Make a copy of this public key -*/ -Public_Key* copy_key(const Public_Key& key) - { - DataSource_Memory source(PEM_encode(key)); - return X509::load_key(source); - } - -/* -* Find the allowable key constraints -*/ -Key_Constraints find_constraints(const Public_Key& pub_key, - Key_Constraints limits) - { - const std::string name = pub_key.algo_name(); - - size_t constraints = 0; - - if(name == "DH" || name == "ECDH") - constraints |= KEY_AGREEMENT; - - if(name == "RSA" || name == "ElGamal") - constraints |= KEY_ENCIPHERMENT | DATA_ENCIPHERMENT; - - if(name == "RSA" || name == "RW" || name == "NR" || - name == "DSA" || name == "ECDSA") - constraints |= DIGITAL_SIGNATURE | NON_REPUDIATION; - - if(limits) - constraints &= limits; - - return Key_Constraints(constraints); - } - -} - -} -/* -* HMAC_RNG -* (C) 2008-2009 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include - -namespace Botan { - -namespace { - -void hmac_prf(MessageAuthenticationCode* prf, - MemoryRegion& K, - u32bit& counter, - const std::string& label) - { - prf->update(K); - prf->update(label); - prf->update_be(counter); - prf->final(&K[0]); - - ++counter; - } - -} - -/* -* Generate a buffer of random bytes -*/ -void HMAC_RNG::randomize(byte out[], size_t length) - { - if(!is_seeded()) - throw PRNG_Unseeded(name()); - - /* - HMAC KDF as described in E-t-E, using a CTXinfo of "rng" - */ - while(length) - { - hmac_prf(prf, K, counter, "rng"); - - const size_t copied = std::min(K.size(), length); - - copy_mem(out, &K[0], copied); - out += copied; - length -= copied; - } - } - -/* -* Poll for entropy and reset the internal keys -*/ -void HMAC_RNG::reseed(size_t poll_bits) - { - /* - Using the terminology of E-t-E, XTR is the MAC function (normally - HMAC) seeded with XTS (below) and we form SKM, the key material, by - fast polling each source, and then slow polling as many as we think - we need (in the following loop), and feeding all of the poll - results, along with any optional user input, along with, finally, - feedback of the current PRK value, into the extractor function. - */ - - Entropy_Accumulator_BufferedComputation accum(*extractor, poll_bits); - - if(!entropy_sources.empty()) - { - size_t poll_attempt = 0; - - while(!accum.polling_goal_achieved() && poll_attempt < poll_bits) - { - const size_t src_idx = poll_attempt % entropy_sources.size(); - entropy_sources[src_idx]->poll(accum); - ++poll_attempt; - } - } - - /* - * It is necessary to feed forward poll data. Otherwise, a good poll - * (collecting a large amount of conditional entropy) followed by a - * bad one (collecting little) would be unsafe. Do this by - * generating new PRF outputs using the previous key and feeding - * them into the extractor function. - * - * Cycle the RNG once (CTXinfo="rng"), then generate a new PRF - * output using the CTXinfo "reseed". Provide these values as input - * to the extractor function. - */ - hmac_prf(prf, K, counter, "rng"); - extractor->update(K); // K is the CTXinfo=rng PRF output - - hmac_prf(prf, K, counter, "reseed"); - extractor->update(K); // K is the CTXinfo=reseed PRF output - - /* Now derive the new PRK using everything that has been fed into - the extractor, and set the PRF key to that */ - prf->set_key(extractor->final()); - - // Now generate a new PRF output to use as the XTS extractor salt - hmac_prf(prf, K, counter, "xts"); - extractor->set_key(K); - - // Reset state - zeroise(K); - counter = 0; - user_input_len = 0; - - /* - Consider ourselves seeded once we've collected an estimated 128 bits of - entropy in a single poll. - */ - if(seeded == false && accum.bits_collected() >= 128) - seeded = true; - } - -/* -* Add user-supplied entropy to the extractor input -*/ -void HMAC_RNG::add_entropy(const byte input[], size_t length) - { - const size_t USER_ENTROPY_WATERSHED = 64; - - extractor->update(input, length); - user_input_len += length; - - /* - * After we've accumulated at least USER_ENTROPY_WATERSHED bytes of - * user input, reseed. This input will automatically have been - * included if reseed was called already, as it's just included in - * the extractor input. - */ - if(user_input_len >= USER_ENTROPY_WATERSHED) - reseed(0); - } - -/* -* Add another entropy source to the list -*/ -void HMAC_RNG::add_entropy_source(EntropySource* src) - { - entropy_sources.push_back(src); - } - -/* -* Clear memory of sensitive data -*/ -void HMAC_RNG::clear() - { - extractor->clear(); - prf->clear(); - zeroise(K); - counter = 0; - user_input_len = 0; - seeded = false; - } - -/* -* Return the name of this type -*/ -std::string HMAC_RNG::name() const - { - return "HMAC_RNG(" + extractor->name() + "," + prf->name() + ")"; - } - -/* -* HMAC_RNG Constructor -*/ -HMAC_RNG::HMAC_RNG(MessageAuthenticationCode* extractor_mac, - MessageAuthenticationCode* prf_mac) : - extractor(extractor_mac), prf(prf_mac) - { - if(!prf->valid_keylength(extractor->output_length()) || - !extractor->valid_keylength(prf->output_length())) - throw Invalid_Argument("HMAC_RNG: Bad algo combination " + - extractor->name() + " and " + - prf->name()); - - // First PRF inputs are all zero, as specified in section 2 - K.resize(prf->output_length()); - - counter = 0; - user_input_len = 0; - seeded = false; - - /* - Normally we want to feedback PRF output into the input to the - extractor function to ensure a single bad poll does not damage the - RNG, but obviously that is meaningless to do on the first poll. - - We will want to use the PRF before we set the first key (in - reseed), and it is a pain to keep track if it is set or - not. Since the first time it doesn't matter anyway, just set the - PRF key to constant zero: randomize() will not produce output - unless is_seeded() returns true, and that will only be the case if - the estimated entropy counter is high enough. That variable is only - set when a reseeding is performed. - */ - MemoryVector prf_key(extractor->output_length()); - prf->set_key(prf_key); - - /* - Use PRF("Botan HMAC_RNG XTS") as the intitial XTS key. - - This will be used during the first extraction sequence; XTS values - after this one are generated using the PRF. - - If I understand the E-t-E paper correctly (specifically Section 4), - using this fixed extractor key is safe to do. - */ - extractor->set_key(prf->process("Botan HMAC_RNG XTS")); - } - -/* -* HMAC_RNG Destructor -*/ -HMAC_RNG::~HMAC_RNG() - { - delete extractor; - delete prf; - - std::for_each(entropy_sources.begin(), entropy_sources.end(), - del_fun()); - - counter = 0; - } - -} -/* -* Randpool -* (C) 1999-2009 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include - -namespace Botan { - -namespace { - -/* -* PRF based on a MAC -*/ -enum RANDPOOL_PRF_TAG { - CIPHER_KEY = 0, - MAC_KEY = 1, - GEN_OUTPUT = 2 -}; - -} - -/* -* Generate a buffer of random bytes -*/ -void Randpool::randomize(byte out[], size_t length) - { - if(!is_seeded()) - throw PRNG_Unseeded(name()); - - update_buffer(); - while(length) - { - const size_t copied = std::min(length, buffer.size()); - copy_mem(out, &buffer[0], copied); - out += copied; - length -= copied; - update_buffer(); - } - } - -/* -* Refill the output buffer -*/ -void Randpool::update_buffer() - { - for(size_t i = 0; i != counter.size(); ++i) - if(++counter[i]) - break; - - mac->update(static_cast(GEN_OUTPUT)); - mac->update(counter); - SecureVector mac_val = mac->final(); - - for(size_t i = 0; i != mac_val.size(); ++i) - buffer[i % buffer.size()] ^= mac_val[i]; - cipher->encrypt(buffer); - - if(counter[0] % ITERATIONS_BEFORE_RESEED == 0) - mix_pool(); - } - -/* -* Mix the entropy pool -*/ -void Randpool::mix_pool() - { - const size_t BLOCK_SIZE = cipher->block_size(); - - mac->update(static_cast(MAC_KEY)); - mac->update(pool); - mac->set_key(mac->final()); - - mac->update(static_cast(CIPHER_KEY)); - mac->update(pool); - cipher->set_key(mac->final()); - - xor_buf(pool, buffer, BLOCK_SIZE); - cipher->encrypt(pool); - for(size_t i = 1; i != POOL_BLOCKS; ++i) - { - const byte* previous_block = &pool[BLOCK_SIZE*(i-1)]; - byte* this_block = &pool[BLOCK_SIZE*i]; - xor_buf(this_block, previous_block, BLOCK_SIZE); - cipher->encrypt(this_block); - } - - update_buffer(); - } - -/* -* Reseed the internal state -*/ -void Randpool::reseed(size_t poll_bits) - { - Entropy_Accumulator_BufferedComputation accum(*mac, poll_bits); - - if(!entropy_sources.empty()) - { - size_t poll_attempt = 0; - - while(!accum.polling_goal_achieved() && poll_attempt < poll_bits) - { - entropy_sources[poll_attempt % entropy_sources.size()]->poll(accum); - ++poll_attempt; - } - } - - SecureVector mac_val = mac->final(); - - xor_buf(pool, mac_val, mac_val.size()); - mix_pool(); - - if(accum.bits_collected() >= poll_bits) - seeded = true; - } - -/* -* Add user-supplied entropy -*/ -void Randpool::add_entropy(const byte input[], size_t length) - { - SecureVector mac_val = mac->process(input, length); - xor_buf(pool, mac_val, mac_val.size()); - mix_pool(); - - if(length) - seeded = true; - } - -/* -* Add another entropy source to the list -*/ -void Randpool::add_entropy_source(EntropySource* src) - { - entropy_sources.push_back(src); - } - -/* -* Clear memory of sensitive data -*/ -void Randpool::clear() - { - cipher->clear(); - mac->clear(); - zeroise(pool); - zeroise(buffer); - zeroise(counter); - seeded = false; - } - -/* -* Return the name of this type -*/ -std::string Randpool::name() const - { - return "Randpool(" + cipher->name() + "," + mac->name() + ")"; - } - -/* -* Randpool Constructor -*/ -Randpool::Randpool(BlockCipher* cipher_in, - MessageAuthenticationCode* mac_in, - size_t pool_blocks, - size_t iter_before_reseed) : - ITERATIONS_BEFORE_RESEED(iter_before_reseed), - POOL_BLOCKS(pool_blocks), - cipher(cipher_in), - mac(mac_in) - { - const size_t BLOCK_SIZE = cipher->block_size(); - const size_t OUTPUT_LENGTH = mac->output_length(); - - if(OUTPUT_LENGTH < BLOCK_SIZE || - !cipher->valid_keylength(OUTPUT_LENGTH) || - !mac->valid_keylength(OUTPUT_LENGTH)) - { - const std::string cipherName = cipher->name(); - const std::string macName = mac->name(); - delete cipher; - delete mac; - throw Internal_Error("Randpool: Invalid algorithm combination " + - cipherName + "/" + macName); - } - - buffer.resize(BLOCK_SIZE); - pool.resize(POOL_BLOCKS * BLOCK_SIZE); - counter.resize(12); - seeded = false; - } - -/* -* Randpool Destructor -*/ -Randpool::~Randpool() - { - delete cipher; - delete mac; - - std::for_each(entropy_sources.begin(), entropy_sources.end(), - del_fun()); - } - -} -/* -* Random Number Generator Base -* (C) 1999-2008 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -#if defined(BOTAN_HAS_AUTO_SEEDING_RNG) -#endif - -namespace Botan { - -/* -* Get a single random byte -*/ -byte RandomNumberGenerator::next_byte() - { - byte out; - this->randomize(&out, 1); - return out; - } - -/* -* Create and seed a new RNG object -*/ -RandomNumberGenerator* RandomNumberGenerator::make_rng() - { -#if defined(BOTAN_HAS_AUTO_SEEDING_RNG) - return new AutoSeeded_RNG; -#endif - - throw Algorithm_Not_Found("RandomNumberGenerator::make_rng - no RNG found"); - } - -} -/* -* ANSI X9.31 RNG -* (C) 1999-2009 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include - -namespace Botan { - -/* -* Generate a buffer of random bytes -*/ -void ANSI_X931_RNG::randomize(byte out[], size_t length) - { - if(!is_seeded()) - throw PRNG_Unseeded(name()); - - while(length) - { - if(position == R.size()) - update_buffer(); - - const size_t copied = std::min(length, R.size() - position); - - copy_mem(out, &R[position], copied); - out += copied; - length -= copied; - position += copied; - } - } - -/* -* Refill the internal state -*/ -void ANSI_X931_RNG::update_buffer() - { - const size_t BLOCK_SIZE = cipher->block_size(); - - SecureVector DT = prng->random_vec(BLOCK_SIZE); - cipher->encrypt(DT); - - xor_buf(&R[0], &V[0], &DT[0], BLOCK_SIZE); - cipher->encrypt(R); - - xor_buf(&V[0], &R[0], &DT[0], BLOCK_SIZE); - cipher->encrypt(V); - - position = 0; - } - -/* -* Reset V and the cipher key with new values -*/ -void ANSI_X931_RNG::rekey() - { - const size_t BLOCK_SIZE = cipher->block_size(); - - if(prng->is_seeded()) - { - cipher->set_key(prng->random_vec(cipher->maximum_keylength())); - - if(V.size() != BLOCK_SIZE) - V.resize(BLOCK_SIZE); - prng->randomize(&V[0], V.size()); - - update_buffer(); - } - } - -/* -* Reseed the internal state -*/ -void ANSI_X931_RNG::reseed(size_t poll_bits) - { - prng->reseed(poll_bits); - rekey(); - } - -/* -* Add a entropy source to the underlying PRNG -*/ -void ANSI_X931_RNG::add_entropy_source(EntropySource* src) - { - prng->add_entropy_source(src); - } - -/* -* Add some entropy to the underlying PRNG -*/ -void ANSI_X931_RNG::add_entropy(const byte input[], size_t length) - { - prng->add_entropy(input, length); - rekey(); - } - -/* -* Check if the PRNG is seeded -*/ -bool ANSI_X931_RNG::is_seeded() const - { - return (V.size() > 0); - } - -/* -* Clear memory of sensitive data -*/ -void ANSI_X931_RNG::clear() - { - cipher->clear(); - prng->clear(); - zeroise(R); - V.clear(); - - position = 0; - } - -/* -* Return the name of this type -*/ -std::string ANSI_X931_RNG::name() const - { - return "X9.31(" + cipher->name() + ")"; - } - -/* -* ANSI X931 RNG Constructor -*/ -ANSI_X931_RNG::ANSI_X931_RNG(BlockCipher* cipher_in, - RandomNumberGenerator* prng_in) - { - if(!prng_in || !cipher_in) - throw Invalid_Argument("ANSI_X931_RNG constructor: NULL arguments"); - - cipher = cipher_in; - prng = prng_in; - - R.resize(cipher->block_size()); - position = 0; - } - -/* -* ANSI X931 RNG Destructor -*/ -ANSI_X931_RNG::~ANSI_X931_RNG() - { - delete cipher; - delete prng; - } - -} -/* -* Startup Self Tests -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -namespace { - -/* -* Perform a Known Answer Test -*/ -bool test_filter_kat(Filter* filter, - const std::string& input, - const std::string& expected_output) - { - Pipe pipe(new Hex_Decoder, filter, new Hex_Encoder); - pipe.process_msg(input); - - const std::string output = pipe.read_all_as_string(); - - return (output == expected_output); - } - -} - -/* -* Run a set of KATs -*/ -std::map -algorithm_kat(const SCAN_Name& algo_name, - const std::map& vars, - Algorithm_Factory& af) - { - const std::string& algo = algo_name.algo_name_and_args(); - - std::vector providers = af.providers_of(algo); - std::map all_results; - - if(providers.empty()) // no providers, nothing to do - return all_results; - - const std::string input = search_map(vars, std::string("input")); - const std::string output = search_map(vars, std::string("output")); - - SymmetricKey key(search_map(vars, std::string("key"))); - InitializationVector iv(search_map(vars, std::string("iv"))); - - for(size_t i = 0; i != providers.size(); ++i) - { - const std::string provider = providers[i]; - - if(const HashFunction* proto = - af.prototype_hash_function(algo, provider)) - { - Filter* filt = new Hash_Filter(proto->clone()); - all_results[provider] = test_filter_kat(filt, input, output); - } - else if(const MessageAuthenticationCode* proto = - af.prototype_mac(algo, provider)) - { - Keyed_Filter* filt = new MAC_Filter(proto->clone(), key); - all_results[provider] = test_filter_kat(filt, input, output); - } - else if(const StreamCipher* proto = - af.prototype_stream_cipher(algo, provider)) - { - Keyed_Filter* filt = new StreamCipher_Filter(proto->clone()); - filt->set_key(key); - filt->set_iv(iv); - - all_results[provider] = test_filter_kat(filt, input, output); - } - else if(const BlockCipher* proto = - af.prototype_block_cipher(algo, provider)) - { - Keyed_Filter* enc = get_cipher_mode(proto, ENCRYPTION, - algo_name.cipher_mode(), - algo_name.cipher_mode_pad()); - - Keyed_Filter* dec = get_cipher_mode(proto, DECRYPTION, - algo_name.cipher_mode(), - algo_name.cipher_mode_pad()); - - if(!enc || !dec) - { - delete enc; - delete dec; - continue; - } - - enc->set_key(key); - - if(enc->valid_iv_length(iv.length())) - enc->set_iv(iv); - else if(!enc->valid_iv_length(0)) - throw Invalid_IV_Length(algo, iv.length()); - - dec->set_key(key); - - if(dec->valid_iv_length(iv.length())) - dec->set_iv(iv); - else if(!dec->valid_iv_length(0)) - throw Invalid_IV_Length(algo, iv.length()); - - bool enc_ok = test_filter_kat(enc, input, output); - bool dec_ok = test_filter_kat(dec, output, input); - - all_results[provider] = enc_ok && dec_ok; - } - } - - return all_results; - } - -namespace { - -void verify_results(const std::string& algo, - const std::map& results) - { - for(std::map::const_iterator i = results.begin(); - i != results.end(); ++i) - { - if(!i->second) - throw Self_Test_Failure(algo + " self-test failed, provider "+ - i->first); - } - } - -void hash_test(Algorithm_Factory& af, - const std::string& name, - const std::string& in, - const std::string& out) - { - std::map vars; - vars["input"] = in; - vars["output"] = out; - - verify_results(name, algorithm_kat(name, vars, af)); - } - -void mac_test(Algorithm_Factory& af, - const std::string& name, - const std::string& in, - const std::string& out, - const std::string& key) - { - std::map vars; - vars["input"] = in; - vars["output"] = out; - vars["key"] = key; - - verify_results(name, algorithm_kat(name, vars, af)); - } - -/* -* Perform a KAT for a cipher -*/ -void cipher_kat(Algorithm_Factory& af, - const std::string& algo, - const std::string& key_str, - const std::string& iv_str, - const std::string& in, - const std::string& ecb_out, - const std::string& cbc_out, - const std::string& cfb_out, - const std::string& ofb_out, - const std::string& ctr_out) - { - SymmetricKey key(key_str); - InitializationVector iv(iv_str); - - std::map vars; - vars["key"] = key_str; - vars["iv"] = iv_str; - vars["input"] = in; - - std::map results; - - vars["output"] = ecb_out; - verify_results(algo + "/ECB", algorithm_kat(algo + "/ECB", vars, af)); - - vars["output"] = cbc_out; - verify_results(algo + "/CBC", - algorithm_kat(algo + "/CBC/NoPadding", vars, af)); - - vars["output"] = cfb_out; - verify_results(algo + "/CFB", algorithm_kat(algo + "/CFB", vars, af)); - - vars["output"] = ofb_out; - verify_results(algo + "/OFB", algorithm_kat(algo + "/OFB", vars, af)); - - vars["output"] = ctr_out; - verify_results(algo + "/CTR", algorithm_kat(algo + "/CTR-BE", vars, af)); - } - -} - -/* -* Perform Self Tests -*/ -bool passes_self_tests(Algorithm_Factory& af) - { - try - { - confirm_startup_self_tests(af); - } - catch(Self_Test_Failure) - { - return false; - } - - return true; - } - -/* -* Perform Self Tests -*/ -void confirm_startup_self_tests(Algorithm_Factory& af) - { - cipher_kat(af, "DES", - "0123456789ABCDEF", "1234567890ABCDEF", - "4E6F77206973207468652074696D6520666F7220616C6C20", - "3FA40E8A984D48156A271787AB8883F9893D51EC4B563B53", - "E5C7CDDE872BF27C43E934008C389C0F683788499A7C05F6", - "F3096249C7F46E51A69E839B1A92F78403467133898EA622", - "F3096249C7F46E5135F24A242EEB3D3F3D6D5BE3255AF8C3", - "F3096249C7F46E51163A8CA0FFC94C27FA2F80F480B86F75"); - - cipher_kat(af, "TripleDES", - "385D7189A5C3D485E1370AA5D408082B5CCCCB5E19F2D90E", - "C141B5FCCD28DC8A", - "6E1BD7C6120947A464A6AAB293A0F89A563D8D40D3461B68", - "64EAAD4ACBB9CEAD6C7615E7C7E4792FE587D91F20C7D2F4", - "6235A461AFD312973E3B4F7AA7D23E34E03371F8E8C376C9", - "E26BA806A59B0330DE40CA38E77A3E494BE2B212F6DD624B", - "E26BA806A59B03307DE2BCC25A08BA40A8BA335F5D604C62", - "E26BA806A59B03303C62C2EFF32D3ACDD5D5F35EBCC53371"); - - cipher_kat(af, "AES-128", - "2B7E151628AED2A6ABF7158809CF4F3C", - "000102030405060708090A0B0C0D0E0F", - "6BC1BEE22E409F96E93D7E117393172A" - "AE2D8A571E03AC9C9EB76FAC45AF8E51", - "3AD77BB40D7A3660A89ECAF32466EF97" - "F5D3D58503B9699DE785895A96FDBAAF", - "7649ABAC8119B246CEE98E9B12E9197D" - "5086CB9B507219EE95DB113A917678B2", - "3B3FD92EB72DAD20333449F8E83CFB4A" - "C8A64537A0B3A93FCDE3CDAD9F1CE58B", - "3B3FD92EB72DAD20333449F8E83CFB4A" - "7789508D16918F03F53C52DAC54ED825", - "3B3FD92EB72DAD20333449F8E83CFB4A" - "010C041999E03F36448624483E582D0E"); - - hash_test(af, "SHA-1", - "", "DA39A3EE5E6B4B0D3255BFEF95601890AFD80709"); - - hash_test(af, "SHA-1", - "616263", "A9993E364706816ABA3E25717850C26C9CD0D89D"); - - hash_test(af, "SHA-1", - "6162636462636465636465666465666765666768666768696768696A" - "68696A6B696A6B6C6A6B6C6D6B6C6D6E6C6D6E6F6D6E6F706E6F7071", - "84983E441C3BD26EBAAE4AA1F95129E5E54670F1"); - - mac_test(af, "HMAC(SHA-1)", - "4869205468657265", - "B617318655057264E28BC0B6FB378C8EF146BE00", - "0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B"); - - hash_test(af, "SHA-256", - "", - "E3B0C44298FC1C149AFBF4C8996FB924" - "27AE41E4649B934CA495991B7852B855"); - - hash_test(af, "SHA-256", - "616263", - "BA7816BF8F01CFEA414140DE5DAE2223" - "B00361A396177A9CB410FF61F20015AD"); - - hash_test(af, "SHA-256", - "6162636462636465636465666465666765666768666768696768696A" - "68696A6B696A6B6C6A6B6C6D6B6C6D6E6C6D6E6F6D6E6F706E6F7071", - "248D6A61D20638B8E5C026930C3E6039" - "A33CE45964FF2167F6ECEDD419DB06C1"); - - mac_test(af, "HMAC(SHA-256)", - "4869205468657265", - "198A607EB44BFBC69903A0F1CF2BBDC5" - "BA0AA3F3D9AE3C1C7A3B1696A0B68CF7", - "0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B" - "0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B"); - } - -} -/* -* ARC4 -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -/* -* Combine cipher stream with message -*/ -void ARC4::cipher(const byte in[], byte out[], size_t length) - { - while(length >= buffer.size() - position) - { - xor_buf(out, in, &buffer[position], buffer.size() - position); - length -= (buffer.size() - position); - in += (buffer.size() - position); - out += (buffer.size() - position); - generate(); - } - xor_buf(out, in, &buffer[position], length); - position += length; - } - -/* -* Generate cipher stream -*/ -void ARC4::generate() - { - byte SX, SY; - for(size_t i = 0; i != buffer.size(); i += 4) - { - SX = state[X+1]; Y = (Y + SX) % 256; SY = state[Y]; - state[X+1] = SY; state[Y] = SX; - buffer[i] = state[(SX + SY) % 256]; - - SX = state[X+2]; Y = (Y + SX) % 256; SY = state[Y]; - state[X+2] = SY; state[Y] = SX; - buffer[i+1] = state[(SX + SY) % 256]; - - SX = state[X+3]; Y = (Y + SX) % 256; SY = state[Y]; - state[X+3] = SY; state[Y] = SX; - buffer[i+2] = state[(SX + SY) % 256]; - - X = (X + 4) % 256; - SX = state[X]; Y = (Y + SX) % 256; SY = state[Y]; - state[X] = SY; state[Y] = SX; - buffer[i+3] = state[(SX + SY) % 256]; - } - position = 0; - } - -/* -* ARC4 Key Schedule -*/ -void ARC4::key_schedule(const byte key[], size_t length) - { - clear(); - - for(size_t i = 0; i != 256; ++i) - state[i] = static_cast(i); - - for(size_t i = 0, state_index = 0; i != 256; ++i) - { - state_index = (state_index + key[i % length] + state[i]) % 256; - std::swap(state[i], state[state_index]); - } - - for(size_t i = 0; i <= SKIP; i += buffer.size()) - generate(); - - position += (SKIP % buffer.size()); - } - -/* -* Return the name of this type -*/ -std::string ARC4::name() const - { - if(SKIP == 0) return "ARC4"; - if(SKIP == 256) return "MARK-4"; - else return "RC4_skip(" + to_string(SKIP) + ")"; - } - -/* -* Clear memory of sensitive data -*/ -void ARC4::clear() - { - zeroise(state); - zeroise(buffer); - position = X = Y = 0; - } - -/* -* ARC4 Constructor -*/ -ARC4::ARC4(size_t s) : SKIP(s), - state(256), - buffer(DEFAULT_BUFFERSIZE) - { - clear(); - } - -} -/* -* Counter mode -* (C) 1999-2011 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -/* -* CTR-BE Constructor -*/ - -CTR_BE::CTR_BE(BlockCipher* ciph) : - permutation(ciph), - counter(256 * permutation->block_size()), - buffer(counter.size()), - position(0) - { - } - -/* -* CTR_BE Destructor -*/ -CTR_BE::~CTR_BE() - { - delete permutation; - } - -/* -* Zeroize -*/ -void CTR_BE::clear() - { - permutation->clear(); - zeroise(buffer); - zeroise(counter); - position = 0; - } - -/* -* Set the key -*/ -void CTR_BE::key_schedule(const byte key[], size_t key_len) - { - permutation->set_key(key, key_len); - - // Set a default all-zeros IV - set_iv(0, 0); - } - -/* -* Return the name of this type -*/ -std::string CTR_BE::name() const - { - return ("CTR-BE(" + permutation->name() + ")"); - } - -/* -* CTR-BE Encryption/Decryption -*/ -void CTR_BE::cipher(const byte in[], byte out[], size_t length) - { - while(length >= buffer.size() - position) - { - xor_buf(out, in, &buffer[position], buffer.size() - position); - length -= (buffer.size() - position); - in += (buffer.size() - position); - out += (buffer.size() - position); - increment_counter(); - } - xor_buf(out, in, &buffer[position], length); - position += length; - } - -/* -* Set CTR-BE IV -*/ -void CTR_BE::set_iv(const byte iv[], size_t iv_len) - { - if(!valid_iv_length(iv_len)) - throw Invalid_IV_Length(name(), iv_len); - - const size_t bs = permutation->block_size(); - - zeroise(counter); - - counter.copy(0, iv, iv_len); - - /* - * Set counter blocks to IV, IV + 1, ... IV + 255 - */ - for(size_t i = 1; i != 256; ++i) - { - counter.copy(i*bs, &counter[(i-1)*bs], bs); - - for(size_t j = 0; j != bs; ++j) - if(++counter[i*bs + (bs - 1 - j)]) - break; - } - - permutation->encrypt_n(&counter[0], &buffer[0], 256); - position = 0; - } - -/* -* Increment the counter and update the buffer -*/ -void CTR_BE::increment_counter() - { - const size_t bs = permutation->block_size(); - - /* - * Each counter value always needs to be incremented by 256, - * so we don't touch the lowest byte and instead treat it as - * an increment of one starting with the next byte. - */ - for(size_t i = 0; i != 256; ++i) - { - for(size_t j = 1; j != bs; ++j) - if(++counter[i*bs + (bs - 1 - j)]) - break; - } - - permutation->encrypt_n(&counter[0], &buffer[0], 256); - - position = 0; - } - -} -/* -* OFB Mode -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include - -namespace Botan { - -/* -* OFB Constructor -*/ -OFB::OFB(BlockCipher* ciph) : permutation(ciph) - { - position = 0; - buffer.resize(permutation->block_size()); - } - -/* -* OFB Destructor -*/ -OFB::~OFB() - { - delete permutation; - } - -/* -* Zeroize -*/ -void OFB::clear() - { - permutation->clear(); - zeroise(buffer); - position = 0; - } - -/* -* Set the key -*/ -void OFB::key_schedule(const byte key[], size_t key_len) - { - permutation->set_key(key, key_len); - - // Set a default all-zeros IV - set_iv(0, 0); - } - -/* -* Return the name of this type -*/ -std::string OFB::name() const - { - return ("OFB(" + permutation->name() + ")"); - } - -/* -* CTR-BE Encryption/Decryption -*/ -void OFB::cipher(const byte in[], byte out[], size_t length) - { - while(length >= buffer.size() - position) - { - xor_buf(out, in, &buffer[position], buffer.size() - position); - length -= (buffer.size() - position); - in += (buffer.size() - position); - out += (buffer.size() - position); - permutation->encrypt(buffer); - position = 0; - } - xor_buf(out, in, &buffer[position], length); - position += length; - } - -/* -* Set CTR-BE IV -*/ -void OFB::set_iv(const byte iv[], size_t iv_len) - { - if(!valid_iv_length(iv_len)) - throw Invalid_IV_Length(name(), iv_len); - - zeroise(buffer); - buffer.copy(0, iv, iv_len); - - permutation->encrypt(buffer); - position = 0; - } - -} -/* -* Salsa20 / XSalsa20 -* (C) 1999-2010 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -namespace { - -#define SALSA20_QUARTER_ROUND(x1, x2, x3, x4) \ - do { \ - x2 ^= rotate_left(x1 + x4, 7); \ - x3 ^= rotate_left(x2 + x1, 9); \ - x4 ^= rotate_left(x3 + x2, 13); \ - x1 ^= rotate_left(x4 + x3, 18); \ - } while(0) - -/* -* Generate HSalsa20 cipher stream (for XSalsa20 IV setup) -*/ -void hsalsa20(u32bit output[8], const u32bit input[16]) - { - u32bit x00 = input[ 0], x01 = input[ 1], x02 = input[ 2], x03 = input[ 3], - x04 = input[ 4], x05 = input[ 5], x06 = input[ 6], x07 = input[ 7], - x08 = input[ 8], x09 = input[ 9], x10 = input[10], x11 = input[11], - x12 = input[12], x13 = input[13], x14 = input[14], x15 = input[15]; - - for(size_t i = 0; i != 10; ++i) - { - SALSA20_QUARTER_ROUND(x00, x04, x08, x12); - SALSA20_QUARTER_ROUND(x05, x09, x13, x01); - SALSA20_QUARTER_ROUND(x10, x14, x02, x06); - SALSA20_QUARTER_ROUND(x15, x03, x07, x11); - - SALSA20_QUARTER_ROUND(x00, x01, x02, x03); - SALSA20_QUARTER_ROUND(x05, x06, x07, x04); - SALSA20_QUARTER_ROUND(x10, x11, x08, x09); - SALSA20_QUARTER_ROUND(x15, x12, x13, x14); - } - - output[0] = x00; - output[1] = x05; - output[2] = x10; - output[3] = x15; - output[4] = x06; - output[5] = x07; - output[6] = x08; - output[7] = x09; - } - -/* -* Generate Salsa20 cipher stream -*/ -void salsa20(byte output[64], const u32bit input[16]) - { - u32bit x00 = input[ 0], x01 = input[ 1], x02 = input[ 2], x03 = input[ 3], - x04 = input[ 4], x05 = input[ 5], x06 = input[ 6], x07 = input[ 7], - x08 = input[ 8], x09 = input[ 9], x10 = input[10], x11 = input[11], - x12 = input[12], x13 = input[13], x14 = input[14], x15 = input[15]; - - for(size_t i = 0; i != 10; ++i) - { - SALSA20_QUARTER_ROUND(x00, x04, x08, x12); - SALSA20_QUARTER_ROUND(x05, x09, x13, x01); - SALSA20_QUARTER_ROUND(x10, x14, x02, x06); - SALSA20_QUARTER_ROUND(x15, x03, x07, x11); - - SALSA20_QUARTER_ROUND(x00, x01, x02, x03); - SALSA20_QUARTER_ROUND(x05, x06, x07, x04); - SALSA20_QUARTER_ROUND(x10, x11, x08, x09); - SALSA20_QUARTER_ROUND(x15, x12, x13, x14); - } - - store_le(x00 + input[ 0], output + 4 * 0); - store_le(x01 + input[ 1], output + 4 * 1); - store_le(x02 + input[ 2], output + 4 * 2); - store_le(x03 + input[ 3], output + 4 * 3); - store_le(x04 + input[ 4], output + 4 * 4); - store_le(x05 + input[ 5], output + 4 * 5); - store_le(x06 + input[ 6], output + 4 * 6); - store_le(x07 + input[ 7], output + 4 * 7); - store_le(x08 + input[ 8], output + 4 * 8); - store_le(x09 + input[ 9], output + 4 * 9); - store_le(x10 + input[10], output + 4 * 10); - store_le(x11 + input[11], output + 4 * 11); - store_le(x12 + input[12], output + 4 * 12); - store_le(x13 + input[13], output + 4 * 13); - store_le(x14 + input[14], output + 4 * 14); - store_le(x15 + input[15], output + 4 * 15); - } - -} - -/* -* Combine cipher stream with message -*/ -void Salsa20::cipher(const byte in[], byte out[], size_t length) - { - while(length >= buffer.size() - position) - { - xor_buf(out, in, &buffer[position], buffer.size() - position); - length -= (buffer.size() - position); - in += (buffer.size() - position); - out += (buffer.size() - position); - salsa20(&buffer[0], &state[0]); - - ++state[8]; - if(!state[8]) // if overflow in state[8] - ++state[9]; // carry to state[9] - - position = 0; - } - - xor_buf(out, in, &buffer[position], length); - - position += length; - } - -/* -* Salsa20 Key Schedule -*/ -void Salsa20::key_schedule(const byte key[], size_t length) - { - static const u32bit TAU[] = - { 0x61707865, 0x3120646e, 0x79622d36, 0x6b206574 }; - - static const u32bit SIGMA[] = - { 0x61707865, 0x3320646e, 0x79622d32, 0x6b206574 }; - - clear(); - - if(length == 16) - { - state[0] = TAU[0]; - state[1] = load_le(key, 0); - state[2] = load_le(key, 1); - state[3] = load_le(key, 2); - state[4] = load_le(key, 3); - state[5] = TAU[1]; - state[10] = TAU[2]; - state[11] = load_le(key, 0); - state[12] = load_le(key, 1); - state[13] = load_le(key, 2); - state[14] = load_le(key, 3); - state[15] = TAU[3]; - } - else if(length == 32) - { - state[0] = SIGMA[0]; - state[1] = load_le(key, 0); - state[2] = load_le(key, 1); - state[3] = load_le(key, 2); - state[4] = load_le(key, 3); - state[5] = SIGMA[1]; - state[10] = SIGMA[2]; - state[11] = load_le(key, 4); - state[12] = load_le(key, 5); - state[13] = load_le(key, 6); - state[14] = load_le(key, 7); - state[15] = SIGMA[3]; - } - - const byte ZERO[8] = { 0 }; - set_iv(ZERO, sizeof(ZERO)); - } - -/* -* Return the name of this type -*/ -void Salsa20::set_iv(const byte iv[], size_t length) - { - if(!valid_iv_length(length)) - throw Invalid_IV_Length(name(), length); - - if(length == 8) - { - // Salsa20 - state[6] = load_le(iv, 0); - state[7] = load_le(iv, 1); - } - else - { - // XSalsa20 - state[6] = load_le(iv, 0); - state[7] = load_le(iv, 1); - state[8] = load_le(iv, 2); - state[9] = load_le(iv, 3); - - SecureVector hsalsa(8); - hsalsa20(&hsalsa[0], &state[0]); - - state[ 1] = hsalsa[0]; - state[ 2] = hsalsa[1]; - state[ 3] = hsalsa[2]; - state[ 4] = hsalsa[3]; - state[ 6] = load_le(iv, 4); - state[ 7] = load_le(iv, 5); - state[11] = hsalsa[4]; - state[12] = hsalsa[5]; - state[13] = hsalsa[6]; - state[14] = hsalsa[7]; - } - - state[8] = 0; - state[9] = 0; - - salsa20(&buffer[0], &state[0]); - ++state[8]; - if(!state[8]) // if overflow in state[8] - ++state[9]; // carry to state[9] - - position = 0; - } - -/* -* Return the name of this type -*/ -std::string Salsa20::name() const - { - return "Salsa20"; - } - -/* -* Clear memory of sensitive data -*/ -void Salsa20::clear() - { - zeroise(state); - zeroise(buffer); - position = 0; - } - -} -/* -* Stream Cipher -* (C) 1999-2010 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -void StreamCipher::set_iv(const byte[], size_t iv_len) - { - if(iv_len) - throw Invalid_Argument("The stream cipher " + name() + - " does not support resyncronization"); - } - -bool StreamCipher::valid_iv_length(size_t iv_len) const - { - return (iv_len == 0); - } - -} -/* -* Tables for Turing -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -const byte Turing::SBOX[256] = { - 0x61, 0x51, 0xEB, 0x19, 0xB9, 0x5D, 0x60, 0x38, 0x7C, 0xB2, 0x06, 0x12, - 0xC4, 0x5B, 0x16, 0x3B, 0x2B, 0x18, 0x83, 0xB0, 0x7F, 0x75, 0xFA, 0xA0, - 0xE9, 0xDD, 0x6D, 0x7A, 0x6B, 0x68, 0x2D, 0x49, 0xB5, 0x1C, 0x90, 0xF7, - 0xED, 0x9F, 0xE8, 0xCE, 0xAE, 0x77, 0xC2, 0x13, 0xFD, 0xCD, 0x3E, 0xCF, - 0x37, 0x6A, 0xD4, 0xDB, 0x8E, 0x65, 0x1F, 0x1A, 0x87, 0xCB, 0x40, 0x15, - 0x88, 0x0D, 0x35, 0xB3, 0x11, 0x0F, 0xD0, 0x30, 0x48, 0xF9, 0xA8, 0xAC, - 0x85, 0x27, 0x0E, 0x8A, 0xE0, 0x50, 0x64, 0xA7, 0xCC, 0xE4, 0xF1, 0x98, - 0xFF, 0xA1, 0x04, 0xDA, 0xD5, 0xBC, 0x1B, 0xBB, 0xD1, 0xFE, 0x31, 0xCA, - 0xBA, 0xD9, 0x2E, 0xF3, 0x1D, 0x47, 0x4A, 0x3D, 0x71, 0x4C, 0xAB, 0x7D, - 0x8D, 0xC7, 0x59, 0xB8, 0xC1, 0x96, 0x1E, 0xFC, 0x44, 0xC8, 0x7B, 0xDC, - 0x5C, 0x78, 0x2A, 0x9D, 0xA5, 0xF0, 0x73, 0x22, 0x89, 0x05, 0xF4, 0x07, - 0x21, 0x52, 0xA6, 0x28, 0x9A, 0x92, 0x69, 0x8F, 0xC5, 0xC3, 0xF5, 0xE1, - 0xDE, 0xEC, 0x09, 0xF2, 0xD3, 0xAF, 0x34, 0x23, 0xAA, 0xDF, 0x7E, 0x82, - 0x29, 0xC0, 0x24, 0x14, 0x03, 0x32, 0x4E, 0x39, 0x6F, 0xC6, 0xB1, 0x9B, - 0xEA, 0x72, 0x79, 0x41, 0xD8, 0x26, 0x6C, 0x5E, 0x2C, 0xB4, 0xA2, 0x53, - 0x57, 0xE2, 0x9C, 0x86, 0x54, 0x95, 0xB6, 0x80, 0x8C, 0x36, 0x67, 0xBD, - 0x08, 0x93, 0x2F, 0x99, 0x5A, 0xF8, 0x3A, 0xD7, 0x56, 0x84, 0xD2, 0x01, - 0xF6, 0x66, 0x4D, 0x55, 0x8B, 0x0C, 0x0B, 0x46, 0xB7, 0x3C, 0x45, 0x91, - 0xA4, 0xE3, 0x70, 0xD6, 0xFB, 0xE6, 0x10, 0xA9, 0xC9, 0x00, 0x9E, 0xE7, - 0x4F, 0x76, 0x25, 0x3F, 0x5F, 0xA3, 0x33, 0x20, 0x02, 0xEF, 0x62, 0x74, - 0xEE, 0x17, 0x81, 0x42, 0x58, 0x0A, 0x4B, 0x63, 0xE5, 0xBE, 0x6E, 0xAD, - 0xBF, 0x43, 0x94, 0x97 }; - -const u32bit Turing::Q_BOX[256] = { - 0x1FAA1887, 0x4E5E435C, 0x9165C042, 0x250E6EF4, 0x5957EE20, 0xD484FED3, - 0xA666C502, 0x7E54E8AE, 0xD12EE9D9, 0xFC1F38D4, 0x49829B5D, 0x1B5CDF3C, - 0x74864249, 0xDA2E3963, 0x28F4429F, 0xC8432C35, 0x4AF40325, 0x9FC0DD70, - 0xD8973DED, 0x1A02DC5E, 0xCD175B42, 0xF10012BF, 0x6694D78C, 0xACAAB26B, - 0x4EC11B9A, 0x3F168146, 0xC0EA8EC5, 0xB38AC28F, 0x1FED5C0F, 0xAAB4101C, - 0xEA2DB082, 0x470929E1, 0xE71843DE, 0x508299FC, 0xE72FBC4B, 0x2E3915DD, - 0x9FA803FA, 0x9546B2DE, 0x3C233342, 0x0FCEE7C3, 0x24D607EF, 0x8F97EBAB, - 0xF37F859B, 0xCD1F2E2F, 0xC25B71DA, 0x75E2269A, 0x1E39C3D1, 0xEDA56B36, - 0xF8C9DEF2, 0x46C9FC5F, 0x1827B3A3, 0x70A56DDF, 0x0D25B510, 0x000F85A7, - 0xB2E82E71, 0x68CB8816, 0x8F951E2A, 0x72F5F6AF, 0xE4CBC2B3, 0xD34FF55D, - 0x2E6B6214, 0x220B83E3, 0xD39EA6F5, 0x6FE041AF, 0x6B2F1F17, 0xAD3B99EE, - 0x16A65EC0, 0x757016C6, 0xBA7709A4, 0xB0326E01, 0xF4B280D9, 0x4BFB1418, - 0xD6AFF227, 0xFD548203, 0xF56B9D96, 0x6717A8C0, 0x00D5BF6E, 0x10EE7888, - 0xEDFCFE64, 0x1BA193CD, 0x4B0D0184, 0x89AE4930, 0x1C014F36, 0x82A87088, - 0x5EAD6C2A, 0xEF22C678, 0x31204DE7, 0xC9C2E759, 0xD200248E, 0x303B446B, - 0xB00D9FC2, 0x9914A895, 0x906CC3A1, 0x54FEF170, 0x34C19155, 0xE27B8A66, - 0x131B5E69, 0xC3A8623E, 0x27BDFA35, 0x97F068CC, 0xCA3A6ACD, 0x4B55E936, - 0x86602DB9, 0x51DF13C1, 0x390BB16D, 0x5A80B83C, 0x22B23763, 0x39D8A911, - 0x2CB6BC13, 0xBF5579D7, 0x6C5C2FA8, 0xA8F4196E, 0xBCDB5476, 0x6864A866, - 0x416E16AD, 0x897FC515, 0x956FEB3C, 0xF6C8A306, 0x216799D9, 0x171A9133, - 0x6C2466DD, 0x75EB5DCD, 0xDF118F50, 0xE4AFB226, 0x26B9CEF3, 0xADB36189, - 0x8A7A19B1, 0xE2C73084, 0xF77DED5C, 0x8B8BC58F, 0x06DDE421, 0xB41E47FB, - 0xB1CC715E, 0x68C0FF99, 0x5D122F0F, 0xA4D25184, 0x097A5E6C, 0x0CBF18BC, - 0xC2D7C6E0, 0x8BB7E420, 0xA11F523F, 0x35D9B8A2, 0x03DA1A6B, 0x06888C02, - 0x7DD1E354, 0x6BBA7D79, 0x32CC7753, 0xE52D9655, 0xA9829DA1, 0x301590A7, - 0x9BC1C149, 0x13537F1C, 0xD3779B69, 0x2D71F2B7, 0x183C58FA, 0xACDC4418, - 0x8D8C8C76, 0x2620D9F0, 0x71A80D4D, 0x7A74C473, 0x449410E9, 0xA20E4211, - 0xF9C8082B, 0x0A6B334A, 0xB5F68ED2, 0x8243CC1B, 0x453C0FF3, 0x9BE564A0, - 0x4FF55A4F, 0x8740F8E7, 0xCCA7F15F, 0xE300FE21, 0x786D37D6, 0xDFD506F1, - 0x8EE00973, 0x17BBDE36, 0x7A670FA8, 0x5C31AB9E, 0xD4DAB618, 0xCC1F52F5, - 0xE358EB4F, 0x19B9E343, 0x3A8D77DD, 0xCDB93DA6, 0x140FD52D, 0x395412F8, - 0x2BA63360, 0x37E53AD0, 0x80700F1C, 0x7624ED0B, 0x703DC1EC, 0xB7366795, - 0xD6549D15, 0x66CE46D7, 0xD17ABE76, 0xA448E0A0, 0x28F07C02, 0xC31249B7, - 0x6E9ED6BA, 0xEAA47F78, 0xBBCFFFBD, 0xC507CA84, 0xE965F4DA, 0x8E9F35DA, - 0x6AD2AA44, 0x577452AC, 0xB5D674A7, 0x5461A46A, 0x6763152A, 0x9C12B7AA, - 0x12615927, 0x7B4FB118, 0xC351758D, 0x7E81687B, 0x5F52F0B3, 0x2D4254ED, - 0xD4C77271, 0x0431ACAB, 0xBEF94AEC, 0xFEE994CD, 0x9C4D9E81, 0xED623730, - 0xCF8A21E8, 0x51917F0B, 0xA7A9B5D6, 0xB297ADF8, 0xEED30431, 0x68CAC921, - 0xF1B35D46, 0x7A430A36, 0x51194022, 0x9ABCA65E, 0x85EC70BA, 0x39AEA8CC, - 0x737BAE8B, 0x582924D5, 0x03098A5A, 0x92396B81, 0x18DE2522, 0x745C1CB8, - 0xA1B8FE1D, 0x5DB3C697, 0x29164F83, 0x97C16376, 0x8419224C, 0x21203B35, - 0x833AC0FE, 0xD966A19A, 0xAAF0B24F, 0x40FDA998, 0xE7D52D71, 0x390896A8, - 0xCEE6053F, 0xD0B0D300, 0xFF99CBCC, 0x065E3D40 }; - -} -/* -* Turing -* (C) 1999-2008 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -namespace { - -/* -* Perform an N-way PHT -*/ -inline void PHT(MemoryRegion& B) - { - u32bit sum = 0; - for(size_t i = 0; i < B.size() - 1; ++i) - sum += B[i]; - - B[B.size()-1] += sum; - - sum = B[B.size()-1]; - for(size_t i = 0; i < B.size() - 1; ++i) - B[i] += sum; - } - -} - -/* -* Combine cipher stream with message -*/ -void Turing::cipher(const byte in[], byte out[], size_t length) - { - while(length >= buffer.size() - position) - { - xor_buf(out, in, &buffer[position], buffer.size() - position); - length -= (buffer.size() - position); - in += (buffer.size() - position); - out += (buffer.size() - position); - generate(); - } - xor_buf(out, in, &buffer[position], length); - position += length; - } - -/* -* Generate cipher stream -*/ -void Turing::generate() - { - // Table for Turing's polynomial multiplication - static const u32bit MULT_TAB[256] = { - 0x00000000, 0xD02B4367, 0xED5686CE, 0x3D7DC5A9, 0x97AC41D1, 0x478702B6, - 0x7AFAC71F, 0xAAD18478, 0x631582EF, 0xB33EC188, 0x8E430421, 0x5E684746, - 0xF4B9C33E, 0x24928059, 0x19EF45F0, 0xC9C40697, 0xC62A4993, 0x16010AF4, - 0x2B7CCF5D, 0xFB578C3A, 0x51860842, 0x81AD4B25, 0xBCD08E8C, 0x6CFBCDEB, - 0xA53FCB7C, 0x7514881B, 0x48694DB2, 0x98420ED5, 0x32938AAD, 0xE2B8C9CA, - 0xDFC50C63, 0x0FEE4F04, 0xC154926B, 0x117FD10C, 0x2C0214A5, 0xFC2957C2, - 0x56F8D3BA, 0x86D390DD, 0xBBAE5574, 0x6B851613, 0xA2411084, 0x726A53E3, - 0x4F17964A, 0x9F3CD52D, 0x35ED5155, 0xE5C61232, 0xD8BBD79B, 0x089094FC, - 0x077EDBF8, 0xD755989F, 0xEA285D36, 0x3A031E51, 0x90D29A29, 0x40F9D94E, - 0x7D841CE7, 0xADAF5F80, 0x646B5917, 0xB4401A70, 0x893DDFD9, 0x59169CBE, - 0xF3C718C6, 0x23EC5BA1, 0x1E919E08, 0xCEBADD6F, 0xCFA869D6, 0x1F832AB1, - 0x22FEEF18, 0xF2D5AC7F, 0x58042807, 0x882F6B60, 0xB552AEC9, 0x6579EDAE, - 0xACBDEB39, 0x7C96A85E, 0x41EB6DF7, 0x91C02E90, 0x3B11AAE8, 0xEB3AE98F, - 0xD6472C26, 0x066C6F41, 0x09822045, 0xD9A96322, 0xE4D4A68B, 0x34FFE5EC, - 0x9E2E6194, 0x4E0522F3, 0x7378E75A, 0xA353A43D, 0x6A97A2AA, 0xBABCE1CD, - 0x87C12464, 0x57EA6703, 0xFD3BE37B, 0x2D10A01C, 0x106D65B5, 0xC04626D2, - 0x0EFCFBBD, 0xDED7B8DA, 0xE3AA7D73, 0x33813E14, 0x9950BA6C, 0x497BF90B, - 0x74063CA2, 0xA42D7FC5, 0x6DE97952, 0xBDC23A35, 0x80BFFF9C, 0x5094BCFB, - 0xFA453883, 0x2A6E7BE4, 0x1713BE4D, 0xC738FD2A, 0xC8D6B22E, 0x18FDF149, - 0x258034E0, 0xF5AB7787, 0x5F7AF3FF, 0x8F51B098, 0xB22C7531, 0x62073656, - 0xABC330C1, 0x7BE873A6, 0x4695B60F, 0x96BEF568, 0x3C6F7110, 0xEC443277, - 0xD139F7DE, 0x0112B4B9, 0xD31DD2E1, 0x03369186, 0x3E4B542F, 0xEE601748, - 0x44B19330, 0x949AD057, 0xA9E715FE, 0x79CC5699, 0xB008500E, 0x60231369, - 0x5D5ED6C0, 0x8D7595A7, 0x27A411DF, 0xF78F52B8, 0xCAF29711, 0x1AD9D476, - 0x15379B72, 0xC51CD815, 0xF8611DBC, 0x284A5EDB, 0x829BDAA3, 0x52B099C4, - 0x6FCD5C6D, 0xBFE61F0A, 0x7622199D, 0xA6095AFA, 0x9B749F53, 0x4B5FDC34, - 0xE18E584C, 0x31A51B2B, 0x0CD8DE82, 0xDCF39DE5, 0x1249408A, 0xC26203ED, - 0xFF1FC644, 0x2F348523, 0x85E5015B, 0x55CE423C, 0x68B38795, 0xB898C4F2, - 0x715CC265, 0xA1778102, 0x9C0A44AB, 0x4C2107CC, 0xE6F083B4, 0x36DBC0D3, - 0x0BA6057A, 0xDB8D461D, 0xD4630919, 0x04484A7E, 0x39358FD7, 0xE91ECCB0, - 0x43CF48C8, 0x93E40BAF, 0xAE99CE06, 0x7EB28D61, 0xB7768BF6, 0x675DC891, - 0x5A200D38, 0x8A0B4E5F, 0x20DACA27, 0xF0F18940, 0xCD8C4CE9, 0x1DA70F8E, - 0x1CB5BB37, 0xCC9EF850, 0xF1E33DF9, 0x21C87E9E, 0x8B19FAE6, 0x5B32B981, - 0x664F7C28, 0xB6643F4F, 0x7FA039D8, 0xAF8B7ABF, 0x92F6BF16, 0x42DDFC71, - 0xE80C7809, 0x38273B6E, 0x055AFEC7, 0xD571BDA0, 0xDA9FF2A4, 0x0AB4B1C3, - 0x37C9746A, 0xE7E2370D, 0x4D33B375, 0x9D18F012, 0xA06535BB, 0x704E76DC, - 0xB98A704B, 0x69A1332C, 0x54DCF685, 0x84F7B5E2, 0x2E26319A, 0xFE0D72FD, - 0xC370B754, 0x135BF433, 0xDDE1295C, 0x0DCA6A3B, 0x30B7AF92, 0xE09CECF5, - 0x4A4D688D, 0x9A662BEA, 0xA71BEE43, 0x7730AD24, 0xBEF4ABB3, 0x6EDFE8D4, - 0x53A22D7D, 0x83896E1A, 0x2958EA62, 0xF973A905, 0xC40E6CAC, 0x14252FCB, - 0x1BCB60CF, 0xCBE023A8, 0xF69DE601, 0x26B6A566, 0x8C67211E, 0x5C4C6279, - 0x6131A7D0, 0xB11AE4B7, 0x78DEE220, 0xA8F5A147, 0x958864EE, 0x45A32789, - 0xEF72A3F1, 0x3F59E096, 0x0224253F, 0xD20F6658 }; - - /* - I tried an implementation without precomputed LFSR offsets, since - I thought that might allow (especially on x86-64) the use of leal to - compute all the offsets.. However on my Core2 with GCC 4.3 it - turned out significantly slower (238 Mib/s, versus 300 Mib/s - with precomputed offsets) - - I also tried using byte vs u32bit for the offset variable (since - x86 memory addressing modes can be odd), but it made things even - slower (186 Mib/s) - */ - static const byte OFFSETS[221] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 12, 14, 15, 16, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 2, 3, 4, - 10, 11, 12, 13, 14, 15, 16, 0, 1, 5, 7, 8, 9, - 15, 16, 0, 1, 2, 3, 4, 5, 6, 10, 12, 13, 14, - 3, 4, 5, 6, 7, 8, 9, 10, 11, 15, 0, 1, 2, - 8, 9, 10, 11, 12, 13, 14, 15, 16, 3, 5, 6, 7, - 13, 14, 15, 16, 0, 1, 2, 3, 4, 8, 10, 11, 12, - 1, 2, 3, 4, 5, 6, 7, 8, 9, 13, 15, 16, 0, - 6, 7, 8, 9, 10, 11, 12, 13, 14, 1, 3, 4, 5, - 11, 12, 13, 14, 15, 16, 0, 1, 2, 6, 8, 9, 10, - 16, 0, 1, 2, 3, 4, 5, 6, 7, 11, 13, 14, 15, - 4, 5, 6, 7, 8, 9, 10, 11, 12, 16, 1, 2, 3, - 9, 10, 11, 12, 13, 14, 15, 16, 0, 4, 6, 7, 8, - 14, 15, 16, 0, 1, 2, 3, 4, 5, 9, 11, 12, 13, - 2, 3, 4, 5, 6, 7, 8, 9, 10, 14, 16, 0, 1, - 7, 8, 9, 10, 11, 12, 13, 14, 15, 2, 4, 5, 6, - 12, 13, 14, 15, 16, 0, 1, 2, 3, 7, 9, 10, 11 }; - - for(size_t i = 0; i != 17; ++i) - { - const byte* R_off = OFFSETS + 13*i; - - u32bit R0 = R[R_off[0]]; - u32bit R1 = R[R_off[1]]; - u32bit R2 = R[R_off[2]]; - u32bit R3 = R[R_off[3]]; - u32bit R4 = R[R_off[4]]; - - const u32bit R5 = R[R_off[5]]; - const u32bit R6 = R[R_off[6]]; - const u32bit R7 = R[R_off[7]]; - const u32bit R8 = R[R_off[8]]; - const u32bit R9 = R[R_off[9]]; - const u32bit R10 = R[R_off[10]]; - const u32bit R11 = R[R_off[11]]; - const u32bit R12 = R[R_off[12]]; - - R[R_off[0]] = R0 = ((R0 << 8) ^ MULT_TAB[(R0 >> 24) & 0xFF]) ^ R11 ^ R4; - - u32bit A = R0; - u32bit B = R10; - u32bit C = R7; - u32bit D = R2; - u32bit E = R1; - - E += A + B + C + D; - - A += E; - B += E; - C += E; - D += E; - - A = S0[get_byte(0, A)] ^ S1[get_byte(1, A)] ^ - S2[get_byte(2, A)] ^ S3[get_byte(3, A)]; - B = S0[get_byte(1, B)] ^ S1[get_byte(2, B)] ^ - S2[get_byte(3, B)] ^ S3[get_byte(0, B)]; - C = S0[get_byte(2, C)] ^ S1[get_byte(3, C)] ^ - S2[get_byte(0, C)] ^ S3[get_byte(1, C)]; - D = S0[get_byte(3, D)] ^ S1[get_byte(0, D)] ^ - S2[get_byte(1, D)] ^ S3[get_byte(2, D)]; - E = S0[get_byte(0, E)] ^ S1[get_byte(1, E)] ^ - S2[get_byte(2, E)] ^ S3[get_byte(3, E)]; - - E += A + B + C + D; - - A += E; - B += E; - C += E; - D += E; - - R[R_off[1]] = R1 = ((R1 << 8) ^ MULT_TAB[(R1 >> 24) & 0xFF]) ^ R12 ^ R5; - R[R_off[2]] = R2 = ((R2 << 8) ^ MULT_TAB[(R2 >> 24) & 0xFF]) ^ R0 ^ R6; - R[R_off[3]] = ((R3 << 8) ^ MULT_TAB[(R3 >> 24) & 0xFF]) ^ R1 ^ R7; - - E += R4; - - R[R_off[4]] = ((R4 << 8) ^ MULT_TAB[(R4 >> 24) & 0xFF]) ^ R2 ^ R8; - - A += R1; - B += R12; - C += R9; - D += R5; - - store_be(A, &buffer[20*i + 0]); - store_be(B, &buffer[20*i + 4]); - store_be(C, &buffer[20*i + 8]); - store_be(D, &buffer[20*i + 12]); - store_be(E, &buffer[20*i + 16]); - } - - position = 0; - } - -/* -* Turing's byte mixing step -*/ -u32bit Turing::fixedS(u32bit W) - { - byte B = SBOX[get_byte(0, W)]; - W ^= Q_BOX[B]; - W &= 0x00FFFFFF; - W |= B << 24; - - B = SBOX[get_byte(1, W)]; - W ^= rotate_left(Q_BOX[B], 8); - W &= 0xFF00FFFF; - W |= B << 16; - - B = SBOX[get_byte(2, W)]; - W ^= rotate_left(Q_BOX[B], 16); - W &= 0xFFFF00FF; - W |= B << 8; - - B = SBOX[get_byte(3, W)]; - W ^= rotate_left(Q_BOX[B], 24); - W &= 0xFFFFFF00; - W |= B; - - return W; - } - -/* -* Turing Key Schedule -*/ -void Turing::key_schedule(const byte key[], size_t length) - { - K.resize(length / 4); - for(size_t i = 0; i != length; ++i) - K[i/4] = (K[i/4] << 8) + key[i]; - - for(size_t i = 0; i != K.size(); ++i) - K[i] = fixedS(K[i]); - - PHT(K); - - for(u32bit i = 0; i != 256; ++i) - { - u32bit W0 = 0, C0 = i; - u32bit W1 = 0, C1 = i; - u32bit W2 = 0, C2 = i; - u32bit W3 = 0, C3 = i; - - for(size_t j = 0; j < K.size(); ++j) - { - C0 = SBOX[get_byte(0, K[j]) ^ C0]; - C1 = SBOX[get_byte(1, K[j]) ^ C1]; - C2 = SBOX[get_byte(2, K[j]) ^ C2]; - C3 = SBOX[get_byte(3, K[j]) ^ C3]; - - W0 ^= rotate_left(Q_BOX[C0], j); - W1 ^= rotate_left(Q_BOX[C1], j + 8); - W2 ^= rotate_left(Q_BOX[C2], j + 16); - W3 ^= rotate_left(Q_BOX[C3], j + 24); - } - - S0[i] = (W0 & 0x00FFFFFF) | (C0 << 24); - S1[i] = (W1 & 0xFF00FFFF) | (C1 << 16); - S2[i] = (W2 & 0xFFFF00FF) | (C2 << 8); - S3[i] = (W3 & 0xFFFFFF00) | C3; - } - - set_iv(0, 0); - } - -/* -* Resynchronization -*/ -void Turing::set_iv(const byte iv[], size_t length) - { - if(!valid_iv_length(length)) - throw Invalid_IV_Length(name(), length); - - SecureVector IV(length / 4); - for(size_t i = 0; i != length; ++i) - IV[i/4] = (IV[i/4] << 8) + iv[i]; - - for(size_t i = 0; i != IV.size(); ++i) - R[i] = IV[i] = fixedS(IV[i]); - - for(size_t i = 0; i != K.size(); ++i) - R[i+IV.size()] = K[i]; - - R[K.size() + IV.size()] = (0x010203 << 8) | (K.size() << 4) | IV.size(); - - for(size_t i = K.size() + IV.size() + 1; i != 17; ++i) - { - const u32bit W = R[i-K.size()-IV.size()-1] + R[i-1]; - R[i] = S0[get_byte(0, W)] ^ S1[get_byte(1, W)] ^ - S2[get_byte(2, W)] ^ S3[get_byte(3, W)]; - } - - PHT(R); - - generate(); - } - -/* -* Clear memory of sensitive data -*/ -void Turing::clear() - { - zeroise(S0); - zeroise(S1); - zeroise(S2); - zeroise(S3); - - zeroise(buffer); - position = 0; - } - -} -/* -* WiderWake -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -/* -* Combine cipher stream with message -*/ -void WiderWake_41_BE::cipher(const byte in[], byte out[], size_t length) - { - while(length >= buffer.size() - position) - { - xor_buf(out, in, &buffer[position], buffer.size() - position); - length -= (buffer.size() - position); - in += (buffer.size() - position); - out += (buffer.size() - position); - generate(buffer.size()); - } - xor_buf(out, in, &buffer[position], length); - position += length; - } - -/* -* Generate cipher stream -*/ -void WiderWake_41_BE::generate(size_t length) - { - u32bit R0 = state[0], R1 = state[1], - R2 = state[2], R3 = state[3], - R4 = state[4]; - - for(size_t i = 0; i != length; i += 8) - { - u32bit R0a; - - store_be(R3, &buffer[i]); - - R0a = R4 + R3; R3 += R2; R2 += R1; R1 += R0; - R0a = (R0a >> 8) ^ T[(R0a & 0xFF)]; - R1 = (R1 >> 8) ^ T[(R1 & 0xFF)]; - R2 = (R2 >> 8) ^ T[(R2 & 0xFF)]; - R3 = (R3 >> 8) ^ T[(R3 & 0xFF)]; - R4 = R0; R0 = R0a; - - store_be(R3, &buffer[i + 4]); - - R0a = R4 + R3; R3 += R2; R2 += R1; R1 += R0; - R0a = (R0a >> 8) ^ T[(R0a & 0xFF)]; - R1 = (R1 >> 8) ^ T[(R1 & 0xFF)]; - R2 = (R2 >> 8) ^ T[(R2 & 0xFF)]; - R3 = (R3 >> 8) ^ T[(R3 & 0xFF)]; - R4 = R0; R0 = R0a; - } - - state[0] = R0; - state[1] = R1; - state[2] = R2; - state[3] = R3; - state[4] = R4; - - position = 0; - } - -/* -* WiderWake Key Schedule -*/ -void WiderWake_41_BE::key_schedule(const byte key[], size_t) - { - for(size_t i = 0; i != 4; ++i) - t_key[i] = load_be(key, i); - - static const u32bit MAGIC[8] = { - 0x726A8F3B, 0xE69A3B5C, 0xD3C71FE5, 0xAB3C73D2, - 0x4D3A8EB3, 0x0396D6E8, 0x3D4C2F7A, 0x9EE27CF3 }; - - for(size_t i = 0; i != 4; ++i) - T[i] = t_key[i]; - - for(size_t i = 4; i != 256; ++i) - { - u32bit X = T[i-1] + T[i-4]; - T[i] = (X >> 3) ^ MAGIC[X % 8]; - } - - for(size_t i = 0; i != 23; ++i) - T[i] += T[i+89]; - - u32bit X = T[33]; - u32bit Z = (T[59] | 0x01000001) & 0xFF7FFFFF; - for(size_t i = 0; i != 256; ++i) - { - X = (X & 0xFF7FFFFF) + Z; - T[i] = (T[i] & 0x00FFFFFF) ^ X; - } - - X = (T[X & 0xFF] ^ X) & 0xFF; - Z = T[0]; - T[0] = T[X]; - for(size_t i = 1; i != 256; ++i) - { - T[X] = T[i]; - X = (T[i ^ X] ^ X) & 0xFF; - T[i] = T[X]; - } - T[X] = Z; - - position = 0; - - const byte ZEROS[8] = { 0 }; - set_iv(ZEROS, sizeof(ZEROS)); - } - -/* -* Resynchronization -*/ -void WiderWake_41_BE::set_iv(const byte iv[], size_t length) - { - if(!valid_iv_length(length)) - throw Invalid_IV_Length(name(), length); - - for(size_t i = 0; i != 4; ++i) - state[i] = t_key[i]; - - state[4] = load_be(iv, 0); - state[0] ^= state[4]; - state[2] ^= load_be(iv, 1); - - generate(8*4); - generate(buffer.size()); - } - -/* -* Clear memory of sensitive data -*/ -void WiderWake_41_BE::clear() - { - position = 0; - zeroise(t_key); - zeroise(state); - zeroise(T); - zeroise(buffer); - } - -} -/* -* Runtime assertion checking -* (C) 2010 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include - -namespace Botan { - -void assertion_failure(const char* expr_str, - const char* msg, - const char* func, - const char* file, - int line) - { - std::ostringstream format; - - format << "Assertion " << expr_str << " failed "; - - if(msg) - format << "(" << msg << ") "; - - if(func) - format << "in " << func << " "; - - format << "@" << file << ":" << line; - - throw Internal_Error(format.str()); - } - -} -/* -* Character Set Handling -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include - -namespace Botan { - -namespace Charset { - -namespace { - -/* -* Convert from UCS-2 to ISO 8859-1 -*/ -std::string ucs2_to_latin1(const std::string& ucs2) - { - if(ucs2.size() % 2 == 1) - throw Decoding_Error("UCS-2 string has an odd number of bytes"); - - std::string latin1; - - for(size_t i = 0; i != ucs2.size(); i += 2) - { - const byte c1 = ucs2[i]; - const byte c2 = ucs2[i+1]; - - if(c1 != 0) - throw Decoding_Error("UCS-2 has non-Latin1 characters"); - - latin1 += static_cast(c2); - } - - return latin1; - } - -/* -* Convert from UTF-8 to ISO 8859-1 -*/ -std::string utf8_to_latin1(const std::string& utf8) - { - std::string iso8859; - - size_t position = 0; - while(position != utf8.size()) - { - const byte c1 = static_cast(utf8[position++]); - - if(c1 <= 0x7F) - iso8859 += static_cast(c1); - else if(c1 >= 0xC0 && c1 <= 0xC7) - { - if(position == utf8.size()) - throw Decoding_Error("UTF-8: sequence truncated"); - - const byte c2 = static_cast(utf8[position++]); - const byte iso_char = ((c1 & 0x07) << 6) | (c2 & 0x3F); - - if(iso_char <= 0x7F) - throw Decoding_Error("UTF-8: sequence longer than needed"); - - iso8859 += static_cast(iso_char); - } - else - throw Decoding_Error("UTF-8: Unicode chars not in Latin1 used"); - } - - return iso8859; - } - -/* -* Convert from ISO 8859-1 to UTF-8 -*/ -std::string latin1_to_utf8(const std::string& iso8859) - { - std::string utf8; - for(size_t i = 0; i != iso8859.size(); ++i) - { - const byte c = static_cast(iso8859[i]); - - if(c <= 0x7F) - utf8 += static_cast(c); - else - { - utf8 += static_cast((0xC0 | (c >> 6))); - utf8 += static_cast((0x80 | (c & 0x3F))); - } - } - return utf8; - } - -} - -/* -* Perform character set transcoding -*/ -std::string transcode(const std::string& str, - Character_Set to, Character_Set from) - { - if(to == LOCAL_CHARSET) - to = LATIN1_CHARSET; - if(from == LOCAL_CHARSET) - from = LATIN1_CHARSET; - - if(to == from) - return str; - - if(from == LATIN1_CHARSET && to == UTF8_CHARSET) - return latin1_to_utf8(str); - if(from == UTF8_CHARSET && to == LATIN1_CHARSET) - return utf8_to_latin1(str); - if(from == UCS2_CHARSET && to == LATIN1_CHARSET) - return ucs2_to_latin1(str); - - throw Invalid_Argument("Unknown transcoding operation from " + - to_string(from) + " to " + to_string(to)); - } - -/* -* Check if a character represents a digit -*/ -bool is_digit(char c) - { - if(c == '0' || c == '1' || c == '2' || c == '3' || c == '4' || - c == '5' || c == '6' || c == '7' || c == '8' || c == '9') - return true; - return false; - } - -/* -* Check if a character represents whitespace -*/ -bool is_space(char c) - { - if(c == ' ' || c == '\t' || c == '\n' || c == '\r') - return true; - return false; - } - -/* -* Convert a character to a digit -*/ -byte char2digit(char c) - { - switch(c) - { - case '0': return 0; - case '1': return 1; - case '2': return 2; - case '3': return 3; - case '4': return 4; - case '5': return 5; - case '6': return 6; - case '7': return 7; - case '8': return 8; - case '9': return 9; - } - - throw Invalid_Argument("char2digit: Input is not a digit character"); - } - -/* -* Convert a digit to a character -*/ -char digit2char(byte b) - { - switch(b) - { - case 0: return '0'; - case 1: return '1'; - case 2: return '2'; - case 3: return '3'; - case 4: return '4'; - case 5: return '5'; - case 6: return '6'; - case 7: return '7'; - case 8: return '8'; - case 9: return '9'; - } - - throw Invalid_Argument("digit2char: Input is not a digit"); - } - -/* -* Case-insensitive character comparison -*/ -bool caseless_cmp(char a, char b) - { - return (std::tolower(static_cast(a)) == - std::tolower(static_cast(b))); - } - -} - -} -/* -* Runtime CPU detection -* (C) 2009-2010 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -#if defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY) - -#if defined(BOTAN_TARGET_OS_IS_DARWIN) - #include -#endif - -#if defined(BOTAN_TARGET_OS_IS_OPENBSD) - #include - #include - #include -#endif - -#endif - -#if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY) - -#if defined(BOTAN_BUILD_COMPILER_IS_MSVC) - - #include - #define CALL_CPUID(type, out) do { __cpuid((int*)out, type); } while(0) - -#elif defined(BOTAN_BUILD_COMPILER_IS_INTEL) - - #include - #define CALL_CPUID(type, out) do { __cpuid((int*)out, type); } while(0) - -#elif defined(BOTAN_BUILD_COMPILER_IS_GCC) && (BOTAN_GCC_VERSION >= 430) - - // Only available starting in GCC 4.3 - #include - -namespace { - - /* - * Prevent inlining to work around GCC bug 44174 - */ - void __attribute__((__noinline__)) call_gcc_cpuid(Botan::u32bit type, - Botan::u32bit out[4]) - { - __get_cpuid(type, out, out+1, out+2, out+3); - } - - #define CALL_CPUID call_gcc_cpuid - -} - -#elif defined(BOTAN_TARGET_ARCH_IS_X86_64) && \ - (defined(BOTAN_BUILD_COMPILER_IS_CLANG) || defined(BOTAN_BUILD_COMPILER_IS_GCC)) - - /* - * We can't safely use this on x86-32 as some 32-bit ABIs use ebx as - * a PIC register, and in theory there are some x86-32s still out - * there that don't support cpuid at all; it requires strange - * contortions to detect them. - */ - - #define CALL_CPUID(type, out) \ - asm("cpuid\n\t" : "=a" (out[0]), "=b" (out[1]), "=c" (out[2]), "=d" (out[3]) \ - : "0" (type)) - -#else - #warning "No method of calling CPUID for this compiler" -#endif - -#endif - -#ifndef CALL_CPUID - // In all other cases, just zeroize the supposed cpuid output - #define CALL_CPUID(type, out) \ - do { out[0] = out[1] = out[2] = out[3] = 0; } while(0); -#endif - -namespace Botan { - -u64bit CPUID::x86_processor_flags = 0; -size_t CPUID::cache_line = 32; -bool CPUID::altivec_capable = false; - -namespace { - -u32bit get_x86_cache_line_size() - { - const u32bit INTEL_CPUID[3] = { 0x756E6547, 0x6C65746E, 0x49656E69 }; - const u32bit AMD_CPUID[3] = { 0x68747541, 0x444D4163, 0x69746E65 }; - - u32bit cpuid[4] = { 0 }; - CALL_CPUID(0, cpuid); - - if(same_mem(cpuid + 1, INTEL_CPUID, 3)) - { - CALL_CPUID(1, cpuid); - return 8 * get_byte(2, cpuid[1]); - } - else if(same_mem(cpuid + 1, AMD_CPUID, 3)) - { - CALL_CPUID(0x80000005, cpuid); - return get_byte(3, cpuid[2]); - } - else - return 32; // default cache line guess - } - -#if defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY) - -bool altivec_check_sysctl() - { -#if defined(BOTAN_TARGET_OS_IS_DARWIN) || defined(BOTAN_TARGET_OS_IS_OPENBSD) - -#if defined(BOTAN_TARGET_OS_IS_OPENBSD) - int sels[2] = { CTL_MACHDEP, CPU_ALTIVEC }; -#else - // From Apple's docs - int sels[2] = { CTL_HW, HW_VECTORUNIT }; -#endif - int vector_type = 0; - size_t length = sizeof(vector_type); - int error = sysctl(sels, 2, &vector_type, &length, NULL, 0); - - if(error == 0 && vector_type > 0) - return true; -#endif - - return false; - } - -bool altivec_check_pvr_emul() - { - bool altivec_capable = false; - -#if defined(BOTAN_TARGET_OS_IS_LINUX) || defined(BOTAN_TARGET_OS_IS_NETBSD) - - /* - On PowerPC, MSR 287 is PVR, the Processor Version Number - Normally it is only accessible to ring 0, but Linux and NetBSD - (others, too, maybe?) will trap and emulate it for us. - - PVR identifiers for various AltiVec enabled CPUs. Taken from - PearPC and Linux sources, mostly. - */ - - const u16bit PVR_G4_7400 = 0x000C; - const u16bit PVR_G5_970 = 0x0039; - const u16bit PVR_G5_970FX = 0x003C; - const u16bit PVR_G5_970MP = 0x0044; - const u16bit PVR_G5_970GX = 0x0045; - const u16bit PVR_POWER6 = 0x003E; - const u16bit PVR_POWER7 = 0x003F; - const u16bit PVR_CELL_PPU = 0x0070; - - // Motorola produced G4s with PVR 0x800[0123C] (at least) - const u16bit PVR_G4_74xx_24 = 0x800; - - u32bit pvr = 0; - - asm volatile("mfspr %0, 287" : "=r" (pvr)); - - // Top 16 bit suffice to identify model - pvr >>= 16; - - altivec_capable |= (pvr == PVR_G4_7400); - altivec_capable |= ((pvr >> 4) == PVR_G4_74xx_24); - altivec_capable |= (pvr == PVR_G5_970); - altivec_capable |= (pvr == PVR_G5_970FX); - altivec_capable |= (pvr == PVR_G5_970MP); - altivec_capable |= (pvr == PVR_G5_970GX); - altivec_capable |= (pvr == PVR_POWER6); - altivec_capable |= (pvr == PVR_POWER7); - altivec_capable |= (pvr == PVR_CELL_PPU); -#endif - - return altivec_capable; - } - -#endif - -} - -void CPUID::initialize() - { - u32bit cpuid[4] = { 0 }; - CALL_CPUID(1, cpuid); - - x86_processor_flags = (static_cast(cpuid[2]) << 32) | cpuid[3]; - -#if defined(BOTAN_TARGET_ARCH_IS_X86_64) - /* - * If we don't have access to CPUID, we can still safely assume that - * any x86-64 processor has SSE2. - */ - if(x86_processor_flags == 0) - x86_processor_flags |= (1 << CPUID_SSE2_BIT); -#endif - - cache_line = get_x86_cache_line_size(); - - altivec_capable = false; - -#if defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY) - if(altivec_check_sysctl() || altivec_check_pvr_emul()) - altivec_capable = true; -#endif - } - -} -/* -* Data Store -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -/* -* Default Matcher transform operation (identity) -*/ -std::pair -Data_Store::Matcher::transform(const std::string& key, - const std::string& value) const - { - return std::make_pair(key, value); - } - -/* -* Data_Store Equality Comparison -*/ -bool Data_Store::operator==(const Data_Store& other) const - { - return (contents == other.contents); - } - -/* -* Check if this key has at least one value -*/ -bool Data_Store::has_value(const std::string& key) const - { - return (contents.lower_bound(key) != contents.end()); - } - -/* -* Search based on an arbitrary predicate -*/ -std::multimap -Data_Store::search_with(const Matcher& matcher) const - { - std::multimap out; - - std::multimap::const_iterator i = - contents.begin(); - - while(i != contents.end()) - { - if(matcher(i->first, i->second)) - { - std::pair p( - matcher.transform(i->first, i->second)); - - multimap_insert(out, p.first, p.second); - } - - ++i; - } - - return out; - } - -/* -* Search based on key equality -*/ -std::vector Data_Store::get(const std::string& looking_for) const - { - typedef std::multimap::const_iterator iter; - - std::pair range = contents.equal_range(looking_for); - - std::vector out; - for(iter i = range.first; i != range.second; ++i) - out.push_back(i->second); - return out; - } - -/* -* Get a single atom -*/ -std::string Data_Store::get1(const std::string& key) const - { - std::vector vals = get(key); - - if(vals.empty()) - throw Invalid_State("Data_Store::get1: Not values for " + key); - if(vals.size() > 1) - throw Invalid_State("Data_Store::get1: More than one value for " + key); - - return vals[0]; - } - -/* -* Get a single MemoryVector atom -*/ -MemoryVector -Data_Store::get1_memvec(const std::string& key) const - { - std::vector vals = get(key); - - if(vals.empty()) - return MemoryVector(); - - if(vals.size() > 1) - throw Invalid_State("Data_Store::get1_memvec: Multiple values for " + - key); - - return hex_decode(vals[0]); - } - -/* -* Get a single u32bit atom -*/ -u32bit Data_Store::get1_u32bit(const std::string& key, - u32bit default_val) const - { - std::vector vals = get(key); - - if(vals.empty()) - return default_val; - else if(vals.size() > 1) - throw Invalid_State("Data_Store::get1_u32bit: Multiple values for " + - key); - - return to_u32bit(vals[0]); - } - -/* -* Insert a single key and value -*/ -void Data_Store::add(const std::string& key, const std::string& val) - { - multimap_insert(contents, key, val); - } - -/* -* Insert a single key and value -*/ -void Data_Store::add(const std::string& key, u32bit val) - { - add(key, to_string(val)); - } - -/* -* Insert a single key and value -*/ -void Data_Store::add(const std::string& key, const MemoryRegion& val) - { - add(key, hex_encode(&val[0], val.size())); - } - -/* -* Insert a mapping of key/value pairs -*/ -void Data_Store::add(const std::multimap& in) - { - std::multimap::const_iterator i = in.begin(); - while(i != in.end()) - { - contents.insert(*i); - ++i; - } - } - -} -/** -* Dynamically Loaded Object -* (C) 2010 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include - -#if defined(BOTAN_TARGET_OS_HAS_DLOPEN) - #include -#elif defined(BOTAN_TARGET_OS_HAS_LOADLIBRARY) - #include -#endif - -namespace Botan { - -namespace { - -void raise_runtime_loader_exception(const std::string& lib_name, - const char* msg) - { - throw std::runtime_error("Failed to load " + lib_name + ": " + - (msg ? msg : "Unknown error")); - } - -} - -Dynamically_Loaded_Library::Dynamically_Loaded_Library( - const std::string& library) : - lib_name(library), lib(0) - { -#if defined(BOTAN_TARGET_OS_HAS_DLOPEN) - lib = ::dlopen(lib_name.c_str(), RTLD_LAZY); - - if(!lib) - raise_runtime_loader_exception(lib_name, dlerror()); - -#elif defined(BOTAN_TARGET_OS_HAS_LOADLIBRARY) - lib = ::LoadLibraryA(lib_name.c_str()); - - if(!lib) - raise_runtime_loader_exception(lib_name, "LoadLibrary failed"); -#endif - - if(!lib) - raise_runtime_loader_exception(lib_name, "Dynamic load not supported"); - } - -Dynamically_Loaded_Library::~Dynamically_Loaded_Library() - { -#if defined(BOTAN_TARGET_OS_HAS_DLOPEN) - ::dlclose(lib); -#elif defined(BOTAN_TARGET_OS_HAS_LOADLIBRARY) - ::FreeLibrary((HMODULE)lib); -#endif - } - -void* Dynamically_Loaded_Library::resolve_symbol(const std::string& symbol) - { - void* addr = 0; - -#if defined(BOTAN_TARGET_OS_HAS_DLOPEN) - addr = ::dlsym(lib, symbol.c_str()); -#elif defined(BOTAN_TARGET_OS_HAS_LOADLIBRARY) - addr = reinterpret_cast(::GetProcAddress((HMODULE)lib, - symbol.c_str())); -#endif - - if(!addr) - throw std::runtime_error("Failed to resolve symbol " + symbol + - " in " + lib_name); - - return addr; - } - -} -/* -* Memory Locking Functions -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -#if defined(BOTAN_TARGET_OS_HAS_POSIX_MLOCK) - #include - #include -#elif defined(BOTAN_TARGET_OS_HAS_WIN32_VIRTUAL_LOCK) - #include -#endif - -namespace Botan { - -bool has_mlock() - { - byte buf[4096]; - if(!lock_mem(&buf, sizeof(buf))) - return false; - unlock_mem(&buf, sizeof(buf)); - return true; - } - -/* -* Lock an area of memory into RAM -*/ -bool lock_mem(void* ptr, size_t bytes) - { - Q_UNUSED(ptr); - Q_UNUSED(bytes); -#if defined(BOTAN_TARGET_OS_HAS_POSIX_MLOCK) - return (::mlock(static_cast(ptr), bytes) == 0); -#elif defined(BOTAN_TARGET_OS_HAS_WIN32_VIRTUAL_LOCK) - return (::VirtualLock(ptr, bytes) != 0); -#else - return false; -#endif - } - -/* -* Unlock a previously locked region of memory -*/ -void unlock_mem(void* ptr, size_t bytes) - { - Q_UNUSED(ptr); - Q_UNUSED(bytes); -#if defined(BOTAN_TARGET_OS_HAS_POSIX_MLOCK) - ::munlock(static_cast(ptr), bytes); -#elif defined(BOTAN_TARGET_OS_HAS_WIN32_VIRTUAL_LOCK) - ::VirtualUnlock(ptr, bytes); -#endif - } - -} -/* -* Parser Functions -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -/* -* Convert a string into an integer -*/ -u32bit to_u32bit(const std::string& number) - { - u32bit n = 0; - - for(std::string::const_iterator i = number.begin(); i != number.end(); ++i) - { - const u32bit OVERFLOW_MARK = 0xFFFFFFFF / 10; - - if(*i == ' ') - continue; - - byte digit = Charset::char2digit(*i); - - if((n > OVERFLOW_MARK) || (n == OVERFLOW_MARK && digit > 5)) - throw Decoding_Error("to_u32bit: Integer overflow"); - n *= 10; - n += digit; - } - return n; - } - -/* -* Convert an integer into a string -*/ -std::string to_string(u64bit n, size_t min_len) - { - std::string lenstr; - if(n) - { - while(n > 0) - { - lenstr = Charset::digit2char(n % 10) + lenstr; - n /= 10; - } - } - else - lenstr = "0"; - - while(lenstr.size() < min_len) - lenstr = "0" + lenstr; - - return lenstr; - } - -/* -* Convert a string into a time duration -*/ -u32bit timespec_to_u32bit(const std::string& timespec) - { - if(timespec == "") - return 0; - - const char suffix = timespec[timespec.size()-1]; - std::string value = timespec.substr(0, timespec.size()-1); - - u32bit scale = 1; - - if(Charset::is_digit(suffix)) - value += suffix; - else if(suffix == 's') - scale = 1; - else if(suffix == 'm') - scale = 60; - else if(suffix == 'h') - scale = 60 * 60; - else if(suffix == 'd') - scale = 24 * 60 * 60; - else if(suffix == 'y') - scale = 365 * 24 * 60 * 60; - else - throw Decoding_Error("timespec_to_u32bit: Bad input " + timespec); - - return scale * to_u32bit(value); - } - -/* -* Parse a SCAN-style algorithm name -*/ -std::vector parse_algorithm_name(const std::string& namex) - { - if(namex.find('(') == std::string::npos && - namex.find(')') == std::string::npos) - return std::vector(1, namex); - - std::string name = namex, substring; - std::vector elems; - size_t level = 0; - - elems.push_back(name.substr(0, name.find('('))); - name = name.substr(name.find('(')); - - for(std::string::const_iterator i = name.begin(); i != name.end(); ++i) - { - char c = *i; - - if(c == '(') - ++level; - if(c == ')') - { - if(level == 1 && i == name.end() - 1) - { - if(elems.size() == 1) - elems.push_back(substring.substr(1)); - else - elems.push_back(substring); - return elems; - } - - if(level == 0 || (level == 1 && i != name.end() - 1)) - throw Invalid_Algorithm_Name(namex); - --level; - } - - if(c == ',' && level == 1) - { - if(elems.size() == 1) - elems.push_back(substring.substr(1)); - else - elems.push_back(substring); - substring.clear(); - } - else - substring += c; - } - - if(substring != "") - throw Invalid_Algorithm_Name(namex); - - return elems; - } - -/* -* Split the string on slashes -*/ -std::vector split_on(const std::string& str, char delim) - { - std::vector elems; - if(str == "") return elems; - - std::string substr; - for(std::string::const_iterator i = str.begin(); i != str.end(); ++i) - { - if(*i == delim) - { - if(substr != "") - elems.push_back(substr); - substr.clear(); - } - else - substr += *i; - } - - if(substr == "") - throw Invalid_Argument("Unable to split string: " + str); - elems.push_back(substr); - - return elems; - } - -/* -* Parse an ASN.1 OID string -*/ -std::vector parse_asn1_oid(const std::string& oid) - { - std::string substring; - std::vector oid_elems; - - for(std::string::const_iterator i = oid.begin(); i != oid.end(); ++i) - { - char c = *i; - - if(c == '.') - { - if(substring == "") - throw Invalid_OID(oid); - oid_elems.push_back(to_u32bit(substring)); - substring.clear(); - } - else - substring += c; - } - - if(substring == "") - throw Invalid_OID(oid); - oid_elems.push_back(to_u32bit(substring)); - - if(oid_elems.size() < 2) - throw Invalid_OID(oid); - - return oid_elems; - } - -/* -* X.500 String Comparison -*/ -bool x500_name_cmp(const std::string& name1, const std::string& name2) - { - std::string::const_iterator p1 = name1.begin(); - std::string::const_iterator p2 = name2.begin(); - - while((p1 != name1.end()) && Charset::is_space(*p1)) ++p1; - while((p2 != name2.end()) && Charset::is_space(*p2)) ++p2; - - while(p1 != name1.end() && p2 != name2.end()) - { - if(Charset::is_space(*p1)) - { - if(!Charset::is_space(*p2)) - return false; - - while((p1 != name1.end()) && Charset::is_space(*p1)) ++p1; - while((p2 != name2.end()) && Charset::is_space(*p2)) ++p2; - - if(p1 == name1.end() && p2 == name2.end()) - return true; - } - - if(!Charset::caseless_cmp(*p1, *p2)) - return false; - ++p1; - ++p2; - } - - while((p1 != name1.end()) && Charset::is_space(*p1)) ++p1; - while((p2 != name2.end()) && Charset::is_space(*p2)) ++p2; - - if((p1 != name1.end()) || (p2 != name2.end())) - return false; - return true; - } - -/* -* Convert a decimal-dotted string to binary IP -*/ -u32bit string_to_ipv4(const std::string& str) - { - std::vector parts = split_on(str, '.'); - - if(parts.size() != 4) - throw Decoding_Error("Invalid IP string " + str); - - u32bit ip = 0; - - for(size_t i = 0; i != parts.size(); ++i) - { - u32bit octet = to_u32bit(parts[i]); - - if(octet > 255) - throw Decoding_Error("Invalid IP string " + str); - - ip = (ip << 8) | (octet & 0xFF); - } - - return ip; - } - -/* -* Convert an IP address to decimal-dotted string -*/ -std::string ipv4_to_string(u32bit ip) - { - std::string str; - - for(size_t i = 0; i != sizeof(ip); ++i) - { - if(i) - str += "."; - str += to_string(get_byte(i, ip)); - } - - return str; - } - -} -/* -* Time Functions -* (C) 1999-2010 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include - -#if defined(BOTAN_TARGET_OS_HAS_WIN32_GET_SYSTEMTIME) - #include -#endif - -#if defined(BOTAN_TARGET_OS_HAS_GETTIMEOFDAY) - #include -#endif - -#if defined(BOTAN_TARGET_OS_HAS_CLOCK_GETTIME) - - #ifndef _POSIX_C_SOURCE - #define _POSIX_C_SOURCE 199309 - #endif - - #include - - #ifndef CLOCK_REALTIME - #define CLOCK_REALTIME 0 - #endif - -#endif - -namespace Botan { - -namespace { - -/* -* Combine a two time values into a single one -*/ -u64bit combine_timers(u32bit seconds, u32bit parts, u32bit parts_hz) - { - static const u64bit NANOSECONDS_UNITS = 1000000000; - - u64bit res = seconds * NANOSECONDS_UNITS; - res += parts * (NANOSECONDS_UNITS / parts_hz); - return res; - } - -std::tm do_gmtime(time_t time_val) - { - std::tm tm; - -#if defined(BOTAN_TARGET_OS_HAS_GMTIME_S) - gmtime_s(&tm, &time_val); // Windows -#elif defined(BOTAN_TARGET_OS_HAS_GMTIME_R) - gmtime_r(&time_val, &tm); // Unix/SUSv2 -#else - std::tm* tm_p = std::gmtime(&time_val); - if (tm_p == 0) - throw Encoding_Error("time_t_to_tm could not convert"); - tm = *tm_p; -#endif - - return tm; - } - -} - -/* -* Get the system clock -*/ -u64bit system_time() - { - return static_cast(std::time(0)); - } - -/* -* Convert a time_point to a calendar_point -*/ -calendar_point calendar_value(u64bit a_time_t) - { - std::tm tm = do_gmtime(static_cast(a_time_t)); - - return calendar_point(tm.tm_year + 1900, - tm.tm_mon + 1, - tm.tm_mday, - tm.tm_hour, - tm.tm_min, - tm.tm_sec); - } - -u64bit get_nanoseconds_clock() - { -#if defined(BOTAN_TARGET_OS_HAS_CLOCK_GETTIME) - - struct ::timespec tv; - ::clock_gettime(CLOCK_REALTIME, &tv); - return combine_timers(tv.tv_sec, tv.tv_nsec, 1000000000); - -#elif defined(BOTAN_TARGET_OS_HAS_GETTIMEOFDAY) - - struct ::timeval tv; - ::gettimeofday(&tv, 0); - return combine_timers(tv.tv_sec, tv.tv_usec, 1000000); - -#elif defined(BOTAN_TARGET_OS_HAS_WIN32_GET_SYSTEMTIME) - - // Returns time since January 1, 1601 in 100-ns increments - ::FILETIME tv; - ::GetSystemTimeAsFileTime(&tv); - u64bit tstamp = (static_cast(tv.dwHighDateTime) << 32) | - tv.dwLowDateTime; - - return (tstamp * 100); // Scale to 1 nanosecond units - -#else - - return combine_timers(static_cast(std::time(0)), - std::clock(), CLOCKS_PER_SEC); - -#endif - } - -} -/* -* User Interface -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -namespace Botan { - -/* -* Get a passphrase from the user -*/ -std::string User_Interface::get_passphrase(const std::string&, - const std::string&, - UI_Result& action) const - { - action = OK; - - if(!first_try) - action = CANCEL_ACTION; - - return preset_passphrase; - } - -/* -* User_Interface Constructor -*/ -User_Interface::User_Interface(const std::string& preset) : - preset_passphrase(preset) - { - first_try = true; - } - -} -/* -* Version Information -* (C) 1999-2011 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include - -namespace Botan { - -/* - These are intentionally compiled rather than inlined, so an - application running against a shared library can test the true - version they are running against. -*/ - -/* -* Return the version as a string -*/ -std::string version_string() - { - std::ostringstream out; - - out << "Botan " << version_major() << "." - << version_minor() << "." - << version_patch() << " ("; - - if(BOTAN_VERSION_DATESTAMP == 0) - out << "unreleased version"; - else - out << "released " << version_datestamp(); - - out << ", revision " << BOTAN_VERSION_VC_REVISION; - out << ", distribution " << BOTAN_DISTRIBUTION_INFO << ")"; - - return out.str(); - } - -u32bit version_datestamp() { return BOTAN_VERSION_DATESTAMP; } - -/* -* Return parts of the version as integers -*/ -u32bit version_major() { return BOTAN_VERSION_MAJOR; } -u32bit version_minor() { return BOTAN_VERSION_MINOR; } -u32bit version_patch() { return BOTAN_VERSION_PATCH; } - -} diff --git a/src/libs/3rdparty/botan/botan.h b/src/libs/3rdparty/botan/botan.h deleted file mode 100644 index d7b90cc92f..0000000000 --- a/src/libs/3rdparty/botan/botan.h +++ /dev/null @@ -1,16208 +0,0 @@ -/* -* Botan 1.10.2 Amalgamation -* (C) 1999-2011 Jack Lloyd and others -* -* Distributed under the terms of the Botan license -*/ - -#ifndef BOTAN_AMALGAMATION_H__ -#define BOTAN_AMALGAMATION_H__ - -#ifdef USE_SYSTEM_BOTAN -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#else - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define BOTAN_VERSION_MAJOR 1 -#define BOTAN_VERSION_MINOR 10 -#define BOTAN_VERSION_PATCH 2 -#define BOTAN_VERSION_DATESTAMP 0 - -#define BOTAN_VERSION_VC_REVISION "mtn:2bf8ad2c501213efb4cf9b219330b87666988e91" - -#define BOTAN_DISTRIBUTION_INFO "unspecified" - -#ifndef BOTAN_DLL -#define BOTAN_DLL Q_DECL_IMPORT -#endif - -/* Chunk sizes */ -#define BOTAN_DEFAULT_BUFFER_SIZE 4096 -#define BOTAN_MEM_POOL_CHUNK_SIZE 64*1024 -#define BOTAN_BLOCK_CIPHER_PAR_MULT 4 - -/* BigInt toggles */ -#define BOTAN_MP_WORD_BITS 32 -#define BOTAN_KARAT_MUL_THRESHOLD 32 -#define BOTAN_KARAT_SQR_THRESHOLD 32 - -/* PK key consistency checking toggles */ -#define BOTAN_PUBLIC_KEY_STRONG_CHECKS_ON_LOAD 1 -#define BOTAN_PRIVATE_KEY_STRONG_CHECKS_ON_LOAD 0 -#define BOTAN_PRIVATE_KEY_STRONG_CHECKS_ON_GENERATE 1 - -/* Should we use GCC-style inline assembler? */ -#if !defined(BOTAN_USE_GCC_INLINE_ASM) && defined(__GNUG__) - #define BOTAN_USE_GCC_INLINE_ASM 1 -#endif - -#if !defined(BOTAN_USE_GCC_INLINE_ASM) - #define BOTAN_USE_GCC_INLINE_ASM 0 -#endif - -#ifdef __GNUC__ - #define BOTAN_GCC_VERSION \ - (__GNUC__ * 100 + __GNUC_MINOR__ * 10 + __GNUC_PATCHLEVEL__) -#else - #define BOTAN_GCC_VERSION 0 -#endif - -#define BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN -#define BOTAN_TARGET_CPU_IS_X86_FAMILY -#define BOTAN_TARGET_UNALIGNED_MEMORY_ACCESS_OK 1 - -#if defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN) || \ - defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN) - #define BOTAN_TARGET_CPU_HAS_KNOWN_ENDIANNESS -#endif - -#if defined(_MSC_VER) - // 4250: inherits via dominance (diamond inheritence issue) - // 4251: needs DLL interface (STL DLL exports) - #pragma warning(disable: 4250 4251) -#endif - -/* -* Compile-time deprecatation warnings -*/ -#if !defined(BOTAN_NO_DEPRECATED_WARNINGS) - - #if defined(__clang__) - #define BOTAN_DEPRECATED(msg) __attribute__ ((deprecated)) - - #elif defined(_MSC_VER) - #define BOTAN_DEPRECATED(msg) __declspec(deprecated(msg)) - - #elif defined(__GNUG__) - - #if BOTAN_GCC_VERSION >= 450 && !defined(__INTEL_COMPILER) - #define BOTAN_DEPRECATED(msg) __attribute__ ((deprecated(msg))) - #else - #define BOTAN_DEPRECATED(msg) __attribute__ ((deprecated)) - #endif - - #endif - -#endif - -#if !defined(BOTAN_DEPRECATED) - #define BOTAN_DEPRECATED(msg) -#endif - -/* -* Module availability definitions -*/ -#define BOTAN_HAS_ADLER32 -#define BOTAN_HAS_AES -#define BOTAN_HAS_ALGORITHM_FACTORY -#define BOTAN_HAS_ANSI_X919_MAC -#define BOTAN_HAS_ARC4 -#define BOTAN_HAS_ASN1 -#define BOTAN_HAS_AUTO_SEEDING_RNG -#define BOTAN_HAS_BASE64_CODEC -#define BOTAN_HAS_BCRYPT -#define BOTAN_HAS_BIGINT -#define BOTAN_HAS_BIGINT_MATH -#define BOTAN_HAS_BIGINT_MP -#define BOTAN_HAS_BLOCK_CIPHER -#define BOTAN_HAS_BLOWFISH -#define BOTAN_HAS_BMW_512 -#define BOTAN_HAS_CAMELLIA -#define BOTAN_HAS_CASCADE -#define BOTAN_HAS_CAST -#define BOTAN_HAS_CBC -#define BOTAN_HAS_CBC_MAC -#define BOTAN_HAS_CERTIFICATE_STORE -#define BOTAN_HAS_CFB -#define BOTAN_HAS_CIPHER_MODE_PADDING -#define BOTAN_HAS_CMAC -#define BOTAN_HAS_CODEC_FILTERS -#define BOTAN_HAS_COMB4P -#define BOTAN_HAS_CORE_ENGINE -#define BOTAN_HAS_CRC24 -#define BOTAN_HAS_CRC32 -#define BOTAN_HAS_CRYPTO_BOX -#define BOTAN_HAS_CTR_BE -#define BOTAN_HAS_CTS -#define BOTAN_HAS_DES -#define BOTAN_HAS_DIFFIE_HELLMAN -#define BOTAN_HAS_DLIES -#define BOTAN_HAS_DL_GROUP -#define BOTAN_HAS_DL_PUBLIC_KEY_FAMILY -#define BOTAN_HAS_DSA -#define BOTAN_HAS_EAX -#define BOTAN_HAS_ECB -#define BOTAN_HAS_ECC_GROUP -#define BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO -#define BOTAN_HAS_ECDH -#define BOTAN_HAS_ECDSA -#define BOTAN_HAS_EC_CURVE_GFP -#define BOTAN_HAS_ELGAMAL -#define BOTAN_HAS_EME1 -#define BOTAN_HAS_EME_PKCS1v15 -#define BOTAN_HAS_EMSA1 -#define BOTAN_HAS_EMSA1_BSI -#define BOTAN_HAS_EMSA2 -#define BOTAN_HAS_EMSA3 -#define BOTAN_HAS_EMSA4 -#define BOTAN_HAS_EMSA_RAW -#define BOTAN_HAS_ENGINES -#define BOTAN_HAS_ENGINE_SIMD -#define BOTAN_HAS_ENTROPY_SRC_HIGH_RESOLUTION_TIMER -#define BOTAN_HAS_FILTERS -#define BOTAN_HAS_FPE_FE1 -#define BOTAN_HAS_GOST_28147_89 -#define BOTAN_HAS_GOST_34_10_2001 -#define BOTAN_HAS_GOST_34_11 -#define BOTAN_HAS_HASH_ID -#define BOTAN_HAS_HAS_160 -#define BOTAN_HAS_HEX_CODEC -#define BOTAN_HAS_HMAC -#define BOTAN_HAS_HMAC_RNG -#define BOTAN_HAS_IDEA -#define BOTAN_HAS_IF_PUBLIC_KEY_FAMILY -#define BOTAN_HAS_KASUMI -#define BOTAN_HAS_KDF1 -#define BOTAN_HAS_KDF2 -#define BOTAN_HAS_KDF_BASE -#define BOTAN_HAS_KECCAK -#define BOTAN_HAS_KEYPAIR_TESTING -#define BOTAN_HAS_LIBSTATE_MODULE -#define BOTAN_HAS_LION -#define BOTAN_HAS_LUBY_RACKOFF -#define BOTAN_HAS_MARS -#define BOTAN_HAS_MD2 -#define BOTAN_HAS_MD4 -#define BOTAN_HAS_MD5 -#define BOTAN_HAS_MDX_HASH_FUNCTION -#define BOTAN_HAS_MGF1 -#define BOTAN_HAS_MISTY1 -#define BOTAN_HAS_MUTEX_NOOP -#define BOTAN_HAS_MUTEX_WRAPPERS -#define BOTAN_HAS_NOEKEON -#define BOTAN_HAS_NOEKEON_SIMD -#define BOTAN_HAS_NYBERG_RUEPPEL -#define BOTAN_HAS_OFB -#define BOTAN_HAS_OID_LOOKUP -#define BOTAN_HAS_OPENPGP_CODEC -#define BOTAN_HAS_PACKAGE_TRANSFORM -#define BOTAN_HAS_PARALLEL_HASH -#define BOTAN_HAS_PASSHASH9 -#define BOTAN_HAS_PASSWORD_BASED_ENCRYPTION -#define BOTAN_HAS_PBE_PKCS_V15 -#define BOTAN_HAS_PBE_PKCS_V20 -#define BOTAN_HAS_PBKDF1 -#define BOTAN_HAS_PBKDF2 -#define BOTAN_HAS_PEM_CODEC -#define BOTAN_HAS_PGPS2K -#define BOTAN_HAS_PKCS10_REQUESTS -#define BOTAN_HAS_PK_PADDING -#define BOTAN_HAS_PUBLIC_KEY_CRYPTO -#define BOTAN_HAS_PUBLIC_KEY_CRYPTO -#define BOTAN_HAS_RANDPOOL -#define BOTAN_HAS_RC2 -#define BOTAN_HAS_RC5 -#define BOTAN_HAS_RC6 -#define BOTAN_HAS_RFC3394_KEYWRAP -#define BOTAN_HAS_RIPEMD_128 -#define BOTAN_HAS_RIPEMD_160 -#define BOTAN_HAS_RSA -#define BOTAN_HAS_RUNTIME_BENCHMARKING -#define BOTAN_HAS_RW -#define BOTAN_HAS_SAFER -#define BOTAN_HAS_SALSA20 -#define BOTAN_HAS_SEED -#define BOTAN_HAS_SELFTESTS -#define BOTAN_HAS_SERPENT -#define BOTAN_HAS_SERPENT_SIMD -#define BOTAN_HAS_SHA1 -#define BOTAN_HAS_SHA2_32 -#define BOTAN_HAS_SHA2_64 -#define BOTAN_HAS_SIMD_32 -#define BOTAN_HAS_SIMD_SCALAR -#define BOTAN_HAS_SKEIN_512 -#define BOTAN_HAS_SKIPJACK -#define BOTAN_HAS_SQUARE -#define BOTAN_HAS_SRP6 -#define BOTAN_HAS_SSL3_MAC -#define BOTAN_HAS_SSL_V3_PRF -#define BOTAN_HAS_STREAM_CIPHER -#define BOTAN_HAS_TEA -#define BOTAN_HAS_THRESHOLD_SECRET_SHARING -#define BOTAN_HAS_TIGER -#define BOTAN_HAS_TLS_V10_PRF -#define BOTAN_HAS_TURING -#define BOTAN_HAS_TWOFISH -#define BOTAN_HAS_UTIL_FUNCTIONS -#define BOTAN_HAS_WHIRLPOOL -#define BOTAN_HAS_WID_WAKE -#define BOTAN_HAS_X509_CA -#define BOTAN_HAS_X509_CERTIFICATES -#define BOTAN_HAS_X509_CRL -#define BOTAN_HAS_X509_SELF_SIGNED -#define BOTAN_HAS_X509_STORE -#define BOTAN_HAS_X931_RNG -#define BOTAN_HAS_X942_PRF -#define BOTAN_HAS_XTEA -#define BOTAN_HAS_XTEA_SIMD -#define BOTAN_HAS_XTS - -/* -* Local configuration options (if any) follow -*/ - - -#include - -/** -* The primary namespace for the botan library -*/ -namespace Botan { - -/** -* Typedef representing an unsigned 8-bit quantity -*/ -typedef unsigned char byte; - -/** -* Typedef representing an unsigned 16-bit quantity -*/ -typedef unsigned short u16bit; - -/** -* Typedef representing an unsigned 32-bit quantity -*/ -typedef unsigned int u32bit; - -/** -* Typedef representing a signed 32-bit quantity -*/ -typedef signed int s32bit; - -/** -* Typedef representing an unsigned 64-bit quantity -*/ -#if defined(_MSC_VER) || defined(__BORLANDC__) - typedef unsigned __int64 u64bit; -#elif defined(__KCC) - typedef unsigned __long_long u64bit; -#elif defined(__GNUG__) - __extension__ typedef unsigned long long u64bit; -#else - typedef unsigned long long u64bit; -#endif - -/** -* A default buffer size; typically a memory page -*/ -static const size_t DEFAULT_BUFFERSIZE = BOTAN_DEFAULT_BUFFER_SIZE; - -} - -namespace Botan_types { - -using Botan::byte; -using Botan::u32bit; - -} - - -namespace Botan { - -/** -* Allocator Interface -*/ -class BOTAN_DLL Allocator - { - public: - /** - * Acquire a pointer to an allocator - * @param locking is true if the allocator should attempt to - * secure the memory (eg for using to store keys) - * @return pointer to an allocator; ownership remains with library, - * so do not delete - */ - static Allocator* get(bool locking); - - /** - * Allocate a block of memory - * @param n how many bytes to allocate - * @return pointer to n bytes of memory - */ - virtual void* allocate(size_t n) = 0; - - /** - * Deallocate memory allocated with allocate() - * @param ptr the pointer returned by allocate() - * @param n the size of the block pointed to by ptr - */ - virtual void deallocate(void* ptr, size_t n) = 0; - - /** - * @return name of this allocator type - */ - virtual std::string type() const = 0; - - /** - * Initialize the allocator - */ - virtual void init() {} - - /** - * Shutdown the allocator - */ - virtual void destroy() {} - - virtual ~Allocator() Q_DECL_NOEXCEPT_EXPR(false) {} - }; - -} - - -namespace Botan { - -/** -* Copy memory -* @param out the destination array -* @param in the source array -* @param n the number of elements of in/out -*/ -template inline void copy_mem(T* out, const T* in, size_t n) - { - std::memmove(out, in, sizeof(T)*n); - } - -/** -* Zeroize memory -* @param ptr a pointer to an array -* @param n the number of Ts pointed to by ptr -*/ -template inline void clear_mem(T* ptr, size_t n) - { - if(n) // avoid glibc warning if n == 0 - std::memset(ptr, 0, sizeof(T)*n); - } - -/** -* Set memory to a fixed value -* @param ptr a pointer to an array -* @param n the number of Ts pointed to by ptr -* @param val the value to set each byte to -*/ -template -inline void set_mem(T* ptr, size_t n, byte val) - { - std::memset(ptr, val, sizeof(T)*n); - } - -/** -* Memory comparison, input insensitive -* @param p1 a pointer to an array -* @param p2 a pointer to another array -* @param n the number of Ts in p1 and p2 -* @return true iff p1[i] == p2[i] forall i in [0...n) -*/ -template inline bool same_mem(const T* p1, const T* p2, size_t n) - { - bool is_same = true; - - for(size_t i = 0; i != n; ++i) - is_same &= (p1[i] == p2[i]); - - return is_same; - } - -} - - -namespace Botan { - -/** -* This class represents variable length memory buffers. -*/ -template -class MemoryRegion - { - public: - /** - * Find out the size of the buffer, i.e. how many objects of type T it - * contains. - * @return size of the buffer - */ - size_t size() const { return used; } - - /** - * Find out whether this buffer is empty. - * @return true if the buffer is empty, false otherwise - */ - bool empty() const { return (used == 0); } - - /** - * Get a pointer to the first element in the buffer. - * @return pointer to the first element in the buffer - */ - operator T* () { return buf; } - - /** - * Get a constant pointer to the first element in the buffer. - * @return constant pointer to the first element in the buffer - */ - operator const T* () const { return buf; } - - /** - * Get a pointer to the first element in the buffer. - * @return pointer to the first element in the buffer - */ - T* begin() { return buf; } - - /** - * Get a constant pointer to the first element in the buffer. - * @return constant pointer to the first element in the buffer - */ - const T* begin() const { return buf; } - - /** - * Get a pointer to one past the last element in the buffer. - * @return pointer to one past the last element in the buffer - */ - T* end() { return (buf + size()); } - - /** - * Get a const pointer to one past the last element in the buffer. - * @return const pointer to one past the last element in the buffer - */ - const T* end() const { return (buf + size()); } - - /** - * Check two buffers for equality. - * @return true iff the content of both buffers is byte-wise equal - */ - bool operator==(const MemoryRegion& other) const - { - return (size() == other.size() && - same_mem(buf, other.buf, size())); - } - - /** - * Compare two buffers - * @return true iff this is ordered before other - */ - bool operator<(const MemoryRegion& other) const; - - /** - * Check two buffers for inequality. - * @return false if the content of both buffers is byte-wise equal, true - * otherwise. - */ - bool operator!=(const MemoryRegion& other) const - { return (!(*this == other)); } - - /** - * Copy the contents of another buffer into this buffer. - * The former contents of *this are discarded. - * @param other the buffer to copy the contents from. - * @return reference to *this - */ - MemoryRegion& operator=(const MemoryRegion& other) - { - if(this != &other) - { - this->resize(other.size()); - this->copy(&other[0], other.size()); - } - return (*this); - } - - /** - * Copy the contents of an array of objects of type T into this buffer. - * The former contents of *this are discarded. - * The length of *this must be at least n, otherwise memory errors occur. - * @param in the array to copy the contents from - * @param n the length of in - */ - void copy(const T in[], size_t n) - { - copy_mem(buf, in, std::min(n, size())); - } - - /** - * Copy the contents of an array of objects of type T into this buffer. - * The former contents of *this are discarded. - * The length of *this must be at least n, otherwise memory errors occur. - * @param off the offset position inside this buffer to start inserting - * the copied bytes - * @param in the array to copy the contents from - * @param n the length of in - */ - void copy(size_t off, const T in[], size_t n) - { - copy_mem(buf + off, in, std::min(n, size() - off)); - } - - /** - * Append a single element. - * @param x the element to append - */ - void push_back(T x) - { - resize(size() + 1); - buf[size()-1] = x; - } - - /** - * Reset this buffer to an empty buffer with size zero. - */ - void clear() { resize(0); } - - /** - * Inserts or erases elements at the end such that the size - * becomes n, leaving elements in the range 0...n unmodified if - * set or otherwise zero-initialized - * @param n length of the new buffer - */ - void resize(size_t n); - - /** - * Swap this buffer with another object. - */ - void swap(MemoryRegion& other); - - virtual ~MemoryRegion() { deallocate(buf, allocated); } - protected: - MemoryRegion() : buf(0), used(0), allocated(0), alloc(0) {} - - /** - * Copy constructor - * @param other the other region to copy - */ - MemoryRegion(const MemoryRegion& other) : - buf(0), - used(0), - allocated(0), - alloc(other.alloc) - { - resize(other.size()); - copy(&other[0], other.size()); - } - - /** - * @param locking should we use a locking allocator - * @param length the initial length to use - */ - void init(bool locking, size_t length = 0) - { alloc = Allocator::get(locking); resize(length); } - - private: - T* allocate(size_t n) - { - return static_cast(alloc->allocate(sizeof(T)*n)); - } - - void deallocate(T* p, size_t n) - { if(alloc && p && n) alloc->deallocate(p, sizeof(T)*n); } - - T* buf; - size_t used; - size_t allocated; - Allocator* alloc; - }; - -/* -* Change the size of the buffer -*/ -template -void MemoryRegion::resize(size_t n) - { - if(n <= allocated) - { - size_t zap = std::min(used, n); - clear_mem(buf + zap, allocated - zap); - used = n; - } - else - { - T* new_buf = allocate(n); - copy_mem(new_buf, buf, used); - deallocate(buf, allocated); - buf = new_buf; - allocated = used = n; - } - } - -/* -* Compare this buffer with another one -*/ -template -bool MemoryRegion::operator<(const MemoryRegion& other) const - { - const size_t min_size = std::min(size(), other.size()); - - // This should probably be rewritten to run in constant time - for(size_t i = 0; i != min_size; ++i) - { - if(buf[i] < other[i]) - return true; - if(buf[i] > other[i]) - return false; - } - - // First min_size bytes are equal, shorter is first - return (size() < other.size()); - } - -/* -* Swap this buffer with another one -*/ -template -void MemoryRegion::swap(MemoryRegion& x) - { - std::swap(buf, x.buf); - std::swap(used, x.used); - std::swap(allocated, x.allocated); - std::swap(alloc, x.alloc); - } - -/** -* This class represents variable length buffers that do not -* make use of memory locking. -*/ -template -class MemoryVector : public MemoryRegion - { - public: - /** - * Copy the contents of another buffer into this buffer. - * @param in the buffer to copy the contents from - * @return reference to *this - */ - MemoryVector& operator=(const MemoryRegion& in) - { - if(this != &in) - { - this->resize(in.size()); - this->copy(&in[0], in.size()); - } - return (*this); - } - - /** - * Create a buffer of the specified length. - * @param n the length of the buffer to create. - */ - MemoryVector(size_t n = 0) { this->init(false, n); } - - /** - * Create a buffer with the specified contents. - * @param in the array containing the data to be initially copied - * into the newly created buffer - * @param n the size of the arry in - */ - MemoryVector(const T in[], size_t n) - { - this->init(false); - this->resize(n); - this->copy(in, n); - } - - /** - * Copy constructor. - */ - MemoryVector(const MemoryRegion& in) - { - this->init(false); - this->resize(in.size()); - this->copy(&in[0], in.size()); - } - }; - -/** -* This class represents variable length buffers using the operating -* systems capability to lock memory, i.e. keeping it from being -* swapped out to disk. In this way, a security hole allowing attackers -* to find swapped out secret keys is closed. -*/ -template -class SecureVector : public MemoryRegion - { - public: - /** - * Copy the contents of another buffer into this buffer. - * @param other the buffer to copy the contents from - * @return reference to *this - */ - SecureVector& operator=(const MemoryRegion& other) - { - if(this != &other) - { - this->resize(other.size()); - this->copy(&other[0], other.size()); - } - return (*this); - } - - /** - * Create a buffer of the specified length. - * @param n the length of the buffer to create. - */ - SecureVector(size_t n = 0) { this->init(true, n); } - - /** - * Create a buffer with the specified contents. - * @param in the array containing the data to be initially copied - * into the newly created buffer - * @param n the size of the array in - */ - SecureVector(const T in[], size_t n) - { - this->init(true); - this->resize(n); - this->copy(&in[0], n); - } - - /** - * Create a buffer with contents specified contents. - * @param in the buffer holding the contents that will be - * copied into the newly created buffer. - */ - SecureVector(const MemoryRegion& in) - { - this->init(true); - this->resize(in.size()); - this->copy(&in[0], in.size()); - } - }; - -template -MemoryRegion& operator+=(MemoryRegion& out, - const MemoryRegion& in) - { - const size_t copy_offset = out.size(); - out.resize(out.size() + in.size()); - copy_mem(&out[copy_offset], &in[0], in.size()); - return out; - } - -template -MemoryRegion& operator+=(MemoryRegion& out, - T in) - { - out.push_back(in); - return out; - } - -template -MemoryRegion& operator+=(MemoryRegion& out, - const std::pair& in) - { - const size_t copy_offset = out.size(); - out.resize(out.size() + in.second); - copy_mem(&out[copy_offset], in.first, in.second); - return out; - } - -template -MemoryRegion& operator+=(MemoryRegion& out, - const std::pair& in) - { - const size_t copy_offset = out.size(); - out.resize(out.size() + in.second); - copy_mem(&out[copy_offset], in.first, in.second); - return out; - } - -/** -* Zeroise the values; length remains unchanged -* @param vec the vector to zeroise -*/ -template -void zeroise(MemoryRegion& vec) - { - clear_mem(&vec[0], vec.size()); - } - -} - -namespace std { - -template -inline void swap(Botan::MemoryRegion& x, Botan::MemoryRegion& y) - { - x.swap(y); - } - -} - - -namespace Botan { - -/** -* Byte extraction -* @param byte_num which byte to extract, 0 == highest byte -* @param input the value to extract from -* @return byte byte_num of input -*/ -template inline byte get_byte(size_t byte_num, T input) - { - return static_cast( - input >> ((sizeof(T)-1-(byte_num&(sizeof(T)-1))) << 3) - ); - } - -} - - -namespace Botan { - -/** -* This class represents any kind of computation which uses an internal -* state, such as hash functions or MACs -*/ -class BOTAN_DLL Buffered_Computation - { - public: - /** - * @return length of the output of this function in bytes - */ - virtual size_t output_length() const = 0; - - /** - * Add new input to process. - * @param in the input to process as a byte array - * @param length of param in in bytes - */ - void update(const byte in[], size_t length) { add_data(in, length); } - - /** - * Add new input to process. - * @param in the input to process as a MemoryRegion - */ - void update(const MemoryRegion& in) - { - add_data(&in[0], in.size()); - } - - /** - * Add an integer in big-endian order - * @param in the value - */ - template void update_be(const T in) - { - for(size_t i = 0; i != sizeof(T); ++i) - { - byte b = get_byte(i, in); - add_data(&b, 1); - } - } - - /** - * Add new input to process. - * @param str the input to process as a std::string. Will be interpreted - * as a byte array based on - * the strings encoding. - */ - void update(const std::string& str) - { - add_data(reinterpret_cast(str.data()), str.size()); - } - - /** - * Process a single byte. - * @param in the byte to process - */ - void update(byte in) { add_data(&in, 1); } - - /** - * Complete the computation and retrieve the - * final result. - * @param out The byte array to be filled with the result. - * Must be of length output_length() - */ - void final(byte out[]) { final_result(out); } - - /** - * Complete the computation and retrieve the - * final result. - * @return SecureVector holding the result - */ - SecureVector final() - { - SecureVector output(output_length()); - final_result(&output[0]); - return output; - } - - /** - * Update and finalize computation. Does the same as calling update() - * and final() consecutively. - * @param in the input to process as a byte array - * @param length the length of the byte array - * @result the result of the call to final() - */ - SecureVector process(const byte in[], size_t length) - { - add_data(in, length); - return final(); - } - - /** - * Update and finalize computation. Does the same as calling update() - * and final() consecutively. - * @param in the input to process - * @result the result of the call to final() - */ - SecureVector process(const MemoryRegion& in) - { - add_data(&in[0], in.size()); - return final(); - } - - /** - * Update and finalize computation. Does the same as calling update() - * and final() consecutively. - * @param in the input to process as a string - * @result the result of the call to final() - */ - SecureVector process(const std::string& in) - { - update(in); - return final(); - } - - virtual ~Buffered_Computation() {} - private: - /** - * Add more data to the computation - * @param input is an input buffer - * @param length is the length of input in bytes - */ - virtual void add_data(const byte input[], size_t length) = 0; - - /** - * Write the final output to out - * @param out is an output buffer of output_length() - */ - virtual void final_result(byte out[]) = 0; - }; - -} - - -namespace Botan { - -/** -* Class used to accumulate the poll results of EntropySources -*/ -class BOTAN_DLL Entropy_Accumulator - { - public: - /** - * Initialize an Entropy_Accumulator - * @param goal is how many bits we would like to collect - */ - Entropy_Accumulator(size_t goal) : - entropy_goal(goal), collected_bits(0) {} - - virtual ~Entropy_Accumulator() {} - - /** - * Get a cached I/O buffer (purely for minimizing allocation - * overhead to polls) - * - * @param size requested size for the I/O buffer - * @return cached I/O buffer for repeated polls - */ - MemoryRegion& get_io_buffer(size_t size) - { io_buffer.resize(size); return io_buffer; } - - /** - * @return number of bits collected so far - */ - size_t bits_collected() const - { return static_cast(collected_bits); } - - /** - * @return if our polling goal has been achieved - */ - bool polling_goal_achieved() const - { return (collected_bits >= entropy_goal); } - - /** - * @return how many bits we need to reach our polling goal - */ - size_t desired_remaining_bits() const - { - if(collected_bits >= entropy_goal) - return 0; - return static_cast(entropy_goal - collected_bits); - } - - /** - * Add entropy to the accumulator - * @param bytes the input bytes - * @param length specifies how many bytes the input is - * @param entropy_bits_per_byte is a best guess at how much - * entropy per byte is in this input - */ - void add(const void* bytes, size_t length, double entropy_bits_per_byte) - { - add_bytes(reinterpret_cast(bytes), length); - collected_bits += entropy_bits_per_byte * length; - } - - /** - * Add entropy to the accumulator - * @param v is some value - * @param entropy_bits_per_byte is a best guess at how much - * entropy per byte is in this input - */ - template - void add(const T& v, double entropy_bits_per_byte) - { - add(&v, sizeof(T), entropy_bits_per_byte); - } - private: - virtual void add_bytes(const byte bytes[], size_t length) = 0; - - SecureVector io_buffer; - size_t entropy_goal; - double collected_bits; - }; - -/** -* Entropy accumulator that puts the input into a Buffered_Computation -*/ -class BOTAN_DLL Entropy_Accumulator_BufferedComputation : - public Entropy_Accumulator - { - public: - /** - * @param sink the hash or MAC we are feeding the poll data into - * @param goal is how many bits we want to collect in this poll - */ - Entropy_Accumulator_BufferedComputation(Buffered_Computation& sink, - size_t goal) : - Entropy_Accumulator(goal), entropy_sink(sink) {} - - private: - virtual void add_bytes(const byte bytes[], size_t length) - { - entropy_sink.update(bytes, length); - } - - Buffered_Computation& entropy_sink; - }; - -/** -* Abstract interface to a source of (hopefully unpredictable) system entropy -*/ -class BOTAN_DLL EntropySource - { - public: - /** - * @return name identifying this entropy source - */ - virtual std::string name() const = 0; - - /** - * Perform an entropy gathering poll - * @param accum is an accumulator object that will be given entropy - */ - virtual void poll(Entropy_Accumulator& accum) = 0; - - virtual ~EntropySource() {} - }; - -} - - -namespace Botan { - -/** -* Parse a SCAN-style algorithm name -* @param scan_name the name -* @return the name components -*/ -BOTAN_DLL std::vector -parse_algorithm_name(const std::string& scan_name); - -/** -* Split a string -* @param str the input string -* @param delim the delimitor -* @return string split by delim -*/ -BOTAN_DLL std::vector split_on( - const std::string& str, char delim); - -/** -* Parse an ASN.1 OID -* @param oid the OID in string form -* @return OID components -*/ -BOTAN_DLL std::vector parse_asn1_oid(const std::string& oid); - -/** -* Compare two names using the X.509 comparison algorithm -* @param name1 the first name -* @param name2 the second name -* @return true if name1 is the same as name2 by the X.509 comparison rules -*/ -BOTAN_DLL bool x500_name_cmp(const std::string& name1, - const std::string& name2); - -/** -* Convert a number to a string -* @param n the integer to convert to a string -* @param min_len the min length of the output string -* @return n convert to a string -*/ -BOTAN_DLL std::string to_string(u64bit n, size_t min_len = 0); - -/** -* Convert a string to a number -* @param str the string to convert -* @return number value of the string -*/ -BOTAN_DLL u32bit to_u32bit(const std::string& str); - -/** -* Convert a time specification to a number -* @param timespec the time specification -* @return number of seconds represented by timespec -*/ -BOTAN_DLL u32bit timespec_to_u32bit(const std::string& timespec); - -/** -* Convert a string representation of an IPv4 address to a number -* @param ip_str the string representation -* @return integer IPv4 address -*/ -BOTAN_DLL u32bit string_to_ipv4(const std::string& ip_str); - -/** -* Convert an IPv4 address to a string -* @param ip_addr the IPv4 address to convert -* @return string representation of the IPv4 address -*/ -BOTAN_DLL std::string ipv4_to_string(u32bit ip_addr); - -} - - -namespace Botan { - -typedef std::runtime_error Exception; -typedef std::invalid_argument Invalid_Argument; - -/** -* Invalid_State Exception -*/ -struct BOTAN_DLL Invalid_State : public Exception - { - Invalid_State(const std::string& err) : - Exception(err) - {} - }; - -/** -* Lookup_Error Exception -*/ -struct BOTAN_DLL Lookup_Error : public Exception - { - Lookup_Error(const std::string& err) : - Exception(err) - {} - }; - -/** -* Internal_Error Exception -*/ -struct BOTAN_DLL Internal_Error : public Exception - { - Internal_Error(const std::string& err) : - Exception("Internal error: " + err) - {} - }; - -/** -* Invalid_Key_Length Exception -*/ -struct BOTAN_DLL Invalid_Key_Length : public Invalid_Argument - { - Invalid_Key_Length(const std::string& name, size_t length) : - Invalid_Argument(name + " cannot accept a key of length " + - to_string(length)) - {} - }; - -/** -* Invalid_Block_Size Exception -*/ -struct BOTAN_DLL Invalid_Block_Size : public Invalid_Argument - { - Invalid_Block_Size(const std::string& mode, - const std::string& pad) : - Invalid_Argument("Padding method " + pad + - " cannot be used with " + mode) - {} - }; - -/** -* Invalid_IV_Length Exception -*/ -struct BOTAN_DLL Invalid_IV_Length : public Invalid_Argument - { - Invalid_IV_Length(const std::string& mode, size_t bad_len) : - Invalid_Argument("IV length " + to_string(bad_len) + - " is invalid for " + mode) - {} - }; - -/** -* PRNG_Unseeded Exception -*/ -struct BOTAN_DLL PRNG_Unseeded : public Invalid_State - { - PRNG_Unseeded(const std::string& algo) : - Invalid_State("PRNG not seeded: " + algo) - {} - }; - -/** -* Policy_Violation Exception -*/ -struct BOTAN_DLL Policy_Violation : public Invalid_State - { - Policy_Violation(const std::string& err) : - Invalid_State("Policy violation: " + err) - {} - }; - -/** -* Algorithm_Not_Found Exception -*/ -struct BOTAN_DLL Algorithm_Not_Found : public Lookup_Error - { - Algorithm_Not_Found(const std::string& name) : - Lookup_Error("Could not find any algorithm named \"" + name + "\"") - {} - }; - -/** -* Invalid_Algorithm_Name Exception -*/ -struct BOTAN_DLL Invalid_Algorithm_Name : public Invalid_Argument - { - Invalid_Algorithm_Name(const std::string& name): - Invalid_Argument("Invalid algorithm name: " + name) - {} - }; - -/** -* Encoding_Error Exception -*/ -struct BOTAN_DLL Encoding_Error : public Invalid_Argument - { - Encoding_Error(const std::string& name) : - Invalid_Argument("Encoding error: " + name) {} - }; - -/** -* Decoding_Error Exception -*/ -struct BOTAN_DLL Decoding_Error : public Invalid_Argument - { - Decoding_Error(const std::string& name) : - Invalid_Argument("Decoding error: " + name) {} - }; - -/** -* Integrity_Failure Exception -*/ -struct BOTAN_DLL Integrity_Failure : public Exception - { - Integrity_Failure(const std::string& msg) : - Exception("Integrity failure: " + msg) {} - }; - -/** -* Invalid_OID Exception -*/ -struct BOTAN_DLL Invalid_OID : public Decoding_Error - { - Invalid_OID(const std::string& oid) : - Decoding_Error("Invalid ASN.1 OID: " + oid) {} - }; - -/** -* Stream_IO_Error Exception -*/ -struct BOTAN_DLL Stream_IO_Error : public Exception - { - Stream_IO_Error(const std::string& err) : - Exception("I/O error: " + err) - {} - }; - -/** -* Self Test Failure Exception -*/ -struct BOTAN_DLL Self_Test_Failure : public Internal_Error - { - Self_Test_Failure(const std::string& err) : - Internal_Error("Self test failed: " + err) - {} - }; - -/** -* Memory Allocation Exception -*/ -struct BOTAN_DLL Memory_Exhaustion : public std::bad_alloc - { - const char* what() const throw() - { return "Ran out of memory, allocation failed"; } - }; - -} - - -namespace Botan { - -/** -* This class represents a random number (RNG) generator object. -*/ -class BOTAN_DLL RandomNumberGenerator - { - public: - /** - * Create a seeded and active RNG object for general application use - */ - static RandomNumberGenerator* make_rng(); - - /** - * Randomize a byte array. - * @param output the byte array to hold the random output. - * @param length the length of the byte array output. - */ - virtual void randomize(byte output[], size_t length) = 0; - - /** - * Return a random vector - * @param bytes number of bytes in the result - * @return randomized vector of length bytes - */ - SecureVector random_vec(size_t bytes) - { - SecureVector output(bytes); - randomize(&output[0], output.size()); - return output; - } - - /** - * Return a random byte - * @return random byte - */ - byte next_byte(); - - /** - * Check whether this RNG is seeded. - * @return true if this RNG was already seeded, false otherwise. - */ - virtual bool is_seeded() const { return true; } - - /** - * Clear all internally held values of this RNG. - */ - virtual void clear() = 0; - - /** - * Return the name of this object - */ - virtual std::string name() const = 0; - - /** - * Seed this RNG using the entropy sources it contains. - * @param bits_to_collect is the number of bits of entropy to - attempt to gather from the entropy sources - */ - virtual void reseed(size_t bits_to_collect) = 0; - - /** - * Add this entropy source to the RNG object - * @param source the entropy source which will be retained and used by RNG - */ - virtual void add_entropy_source(EntropySource* source) = 0; - - /** - * Add entropy to this RNG. - * @param in a byte array containg the entropy to be added - * @param length the length of the byte array in - */ - virtual void add_entropy(const byte in[], size_t length) = 0; - - RandomNumberGenerator() {} - virtual ~RandomNumberGenerator() {} - private: - RandomNumberGenerator(const RandomNumberGenerator&) {} - RandomNumberGenerator& operator=(const RandomNumberGenerator&) - { return (*this); } - }; - -/** -* Null/stub RNG - fails if you try to use it for anything -*/ -class BOTAN_DLL Null_RNG : public RandomNumberGenerator - { - public: - void randomize(byte[], size_t) { throw PRNG_Unseeded("Null_RNG"); } - void clear() {} - std::string name() const { return "Null_RNG"; } - - void reseed(size_t) {} - bool is_seeded() const { return false; } - void add_entropy(const byte[], size_t) {} - void add_entropy_source(EntropySource* es) { delete es; } - }; - -} - - -namespace Botan { - -/** -* Encoding Method for Signatures, Appendix -*/ -class BOTAN_DLL EMSA - { - public: - /** - * Add more data to the signature computation - * @param input some data - * @param length length of input in bytes - */ - virtual void update(const byte input[], size_t length) = 0; - - /** - * @return raw hash - */ - virtual SecureVector raw_data() = 0; - - /** - * Return the encoding of a message - * @param msg the result of raw_data() - * @param output_bits the desired output bit size - * @param rng a random number generator - * @return encoded signature - */ - virtual SecureVector encoding_of(const MemoryRegion& msg, - size_t output_bits, - RandomNumberGenerator& rng) = 0; - - /** - * Verify the encoding - * @param coded the received (coded) message representative - * @param raw the computed (local, uncoded) message representative - * @param key_bits the size of the key in bits - * @return true if coded is a valid encoding of raw, otherwise false - */ - virtual bool verify(const MemoryRegion& coded, - const MemoryRegion& raw, - size_t key_bits) = 0; - virtual ~EMSA() {} - }; - -} - - -namespace Botan { - -/** -* This class represents an algorithm of some kind -*/ -class BOTAN_DLL Algorithm - { - public: - - /** - * Zeroize internal state - */ - virtual void clear() = 0; - - /** - * @return name of this algorithm - */ - virtual std::string name() const = 0; - - Algorithm() {} - virtual ~Algorithm() {} - private: - Algorithm(const Algorithm&) {} - Algorithm& operator=(const Algorithm&) { return (*this); } - }; - -} - - -namespace Botan { - -/** -* This class represents hash function (message digest) objects -*/ -class BOTAN_DLL HashFunction : public Buffered_Computation, - public Algorithm - { - public: - /** - * Get a new object representing the same algorithm as *this - */ - virtual HashFunction* clone() const = 0; - - /** - * The hash block size as defined for this algorithm - */ - virtual size_t hash_block_size() const { return 0; } - }; - -} - - -namespace Botan { - -/** -* EMSA1 from IEEE 1363 -* Essentially, sign the hash directly -*/ -class BOTAN_DLL EMSA1 : public EMSA - { - public: - /** - * @param h the hash object to use - */ - EMSA1(HashFunction* h) : hash(h) {} - ~EMSA1() { delete hash; } - protected: - /** - * @return const pointer to the underlying hash - */ - const HashFunction* hash_ptr() const { return hash; } - private: - void update(const byte[], size_t); - SecureVector raw_data(); - - SecureVector encoding_of(const MemoryRegion&, size_t, - RandomNumberGenerator& rng); - - bool verify(const MemoryRegion&, const MemoryRegion&, - size_t); - - HashFunction* hash; - }; - -} - - -namespace Botan { - -/** -* Keccak[1600], a SHA-3 candidate -*/ -class BOTAN_DLL Keccak_1600 : public HashFunction - { - public: - - /** - * @param output_bits the size of the hash output; must be one of - * 224, 256, 384, or 512 - */ - Keccak_1600(size_t output_bits = 512); - - size_t hash_block_size() const { return bitrate / 8; } - size_t output_length() const { return output_bits / 8; } - - HashFunction* clone() const; - std::string name() const; - void clear(); - private: - void add_data(const byte input[], size_t length); - void final_result(byte out[]); - - size_t output_bits, bitrate; - SecureVector S; - size_t S_pos; - }; - -} - - -namespace Botan { - -/** -A class encapsulating a SCAN name (similar to JCE conventions) -http://www.users.zetnet.co.uk/hopwood/crypto/scan/ -*/ -class BOTAN_DLL SCAN_Name - { - public: - /** - * @param algo_spec A SCAN-format name - */ - SCAN_Name(std::string algo_spec); - - /** - * @return original input string - */ - std::string as_string() const { return orig_algo_spec; } - - /** - * @return algorithm name - */ - std::string algo_name() const { return alg_name; } - - /** - * @return algorithm name plus any arguments - */ - std::string algo_name_and_args() const; - - /** - * @return number of arguments - */ - size_t arg_count() const { return args.size(); } - - /** - * @param lower is the lower bound - * @param upper is the upper bound - * @return if the number of arguments is between lower and upper - */ - bool arg_count_between(size_t lower, size_t upper) const - { return ((arg_count() >= lower) && (arg_count() <= upper)); } - - /** - * @param i which argument - * @return ith argument - */ - std::string arg(size_t i) const; - - /** - * @param i which argument - * @param def_value the default value - * @return ith argument or the default value - */ - std::string arg(size_t i, const std::string& def_value) const; - - /** - * @param i which argument - * @param def_value the default value - * @return ith argument as an integer, or the default value - */ - size_t arg_as_integer(size_t i, size_t def_value) const; - - /** - * @return cipher mode (if any) - */ - std::string cipher_mode() const - { return (mode_info.size() >= 1) ? mode_info[0] : ""; } - - /** - * @return cipher mode padding (if any) - */ - std::string cipher_mode_pad() const - { return (mode_info.size() >= 2) ? mode_info[1] : ""; } - - private: - std::string orig_algo_spec; - std::string alg_name; - std::vector args; - std::vector mode_info; - }; - -} - - -namespace Botan { - -/** -* Represents the length requirements on an algorithm key -*/ -class BOTAN_DLL Key_Length_Specification - { - public: - /** - * Constructor for fixed length keys - * @param keylen the supported key length - */ - Key_Length_Specification(size_t keylen) : - min_keylen(keylen), - max_keylen(keylen), - keylen_mod(1) - { - } - - /** - * Constructor for variable length keys - * @param min_k the smallest supported key length - * @param max_k the largest supported key length - * @param k_mod the number of bytes the key must be a multiple of - */ - Key_Length_Specification(size_t min_k, - size_t max_k, - size_t k_mod = 1) : - min_keylen(min_k), - max_keylen(max_k ? max_k : min_k), - keylen_mod(k_mod) - { - } - - /** - * @param length is a key length in bytes - * @return true iff this length is a valid length for this algo - */ - bool valid_keylength(size_t length) const - { - return ((length >= min_keylen) && - (length <= max_keylen) && - (length % keylen_mod == 0)); - } - - /** - * @return minimum key length in bytes - */ - size_t minimum_keylength() const - { - return min_keylen; - } - - /** - * @return maximum key length in bytes - */ - size_t maximum_keylength() const - { - return max_keylen; - } - - /** - * @return key length multiple in bytes - */ - size_t keylength_multiple() const - { - return keylen_mod; - } - - private: - size_t min_keylen, max_keylen, keylen_mod; - }; - -} - - -namespace Botan { - -/** -* Octet String -*/ -class BOTAN_DLL OctetString - { - public: - /** - * @return size of this octet string in bytes - */ - size_t length() const { return bits.size(); } - - /** - * @return this object as a SecureVector - */ - SecureVector bits_of() const { return bits; } - - /** - * @return start of this string - */ - const byte* begin() const { return &bits[0]; } - - /** - * @return end of this string - */ - const byte* end() const { return &bits[bits.size()]; } - - /** - * @return this encoded as hex - */ - std::string as_string() const; - - /** - * XOR the contents of another octet string into this one - * @param other octet string - * @return reference to this - */ - OctetString& operator^=(const OctetString& other); - - /** - * Force to have odd parity - */ - void set_odd_parity(); - - /** - * Change the contents of this octet string - * @param hex_string a hex encoded bytestring - */ - void change(const std::string& hex_string); - - /** - * Change the contents of this octet string - * @param in the input - * @param length of in in bytes - */ - void change(const byte in[], size_t length); - - /** - * Change the contents of this octet string - * @param in the input - */ - void change(const MemoryRegion& in) { bits = in; } - - /** - * Create a new random OctetString - * @param rng is a random number generator - * @param len is the desired length in bytes - */ - OctetString(class RandomNumberGenerator& rng, size_t len); - - /** - * Create a new OctetString - * @param str is a hex encoded string - */ - OctetString(const std::string& str = "") { change(str); } - - /** - * Create a new OctetString - * @param in is an array - * @param len is the length of in in bytes - */ - OctetString(const byte in[], size_t len) { change(in, len); } - - /** - * Create a new OctetString - * @param in a bytestring - */ - OctetString(const MemoryRegion& in) { change(in); } - private: - SecureVector bits; - }; - -/** -* Compare two strings -* @param x an octet string -* @param y an octet string -* @return if x is equal to y -*/ -BOTAN_DLL bool operator==(const OctetString& x, - const OctetString& y); - -/** -* Compare two strings -* @param x an octet string -* @param y an octet string -* @return if x is not equal to y -*/ -BOTAN_DLL bool operator!=(const OctetString& x, - const OctetString& y); - -/** -* Concatenate two strings -* @param x an octet string -* @param y an octet string -* @return x concatenated with y -*/ -BOTAN_DLL OctetString operator+(const OctetString& x, - const OctetString& y); - -/** -* XOR two strings -* @param x an octet string -* @param y an octet string -* @return x XORed with y -*/ -BOTAN_DLL OctetString operator^(const OctetString& x, - const OctetString& y); - - -/** -* Alternate name for octet string showing intent to use as a key -*/ -typedef OctetString SymmetricKey; - -/** -* Alternate name for octet string showing intent to use as an IV -*/ -typedef OctetString InitializationVector; - -} - - -namespace Botan { - -/** -* This class represents a symmetric algorithm object. -*/ -class BOTAN_DLL SymmetricAlgorithm : public Algorithm - { - public: - /** - * @return object describing limits on key size - */ - virtual Key_Length_Specification key_spec() const = 0; - - /** - * @return minimum allowed key length - */ - size_t maximum_keylength() const - { - return key_spec().maximum_keylength(); - } - - /** - * @return maxmium allowed key length - */ - size_t minimum_keylength() const - { - return key_spec().minimum_keylength(); - } - - /** - * 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 object. - * @param key the SymmetricKey to be set. - */ - void set_key(const SymmetricKey& key) - { set_key(key.begin(), key.length()); } - - /** - * Set the symmetric key of this object. - * @param key the to be set as a byte array. - * @param length in bytes of key param - */ - void set_key(const byte key[], size_t length) - { - if(!valid_keylength(length)) - throw Invalid_Key_Length(name(), length); - key_schedule(key, length); - } - private: - /** - * Run the key schedule - * @param key the key - * @param length of key - */ - virtual void key_schedule(const byte key[], size_t length) = 0; - }; - -/** -* The two possible directions for cipher filters, determining whether they -* actually perform encryption or decryption. -*/ -enum Cipher_Dir { ENCRYPTION, DECRYPTION }; - -} - - -namespace Botan { - -/** -* This class represents a block cipher object. -*/ -class BOTAN_DLL BlockCipher : public SymmetricAlgorithm - { - public: - - /** - * @return block size of this algorithm - */ - virtual size_t block_size() const = 0; - - /** - * @return native parallelism of this cipher in blocks - */ - virtual size_t parallelism() const { return 1; } - - /** - * @return prefererred parallelism of this cipher in bytes - */ - size_t parallel_bytes() const - { - return parallelism() * block_size() * BOTAN_BLOCK_CIPHER_PAR_MULT; - } - - /** - * Encrypt a block. - * @param in The plaintext block to be encrypted as a byte array. - * Must be of length block_size(). - * @param out The byte array designated to hold the encrypted block. - * Must be of length block_size(). - */ - void encrypt(const byte in[], byte out[]) const - { encrypt_n(in, out, 1); } - - /** - * Decrypt a block. - * @param in The ciphertext block to be decypted as a byte array. - * Must be of length block_size(). - * @param out The byte array designated to hold the decrypted block. - * Must be of length block_size(). - */ - void decrypt(const byte in[], byte out[]) const - { decrypt_n(in, out, 1); } - - /** - * Encrypt a block. - * @param block the plaintext block to be encrypted - * Must be of length block_size(). Will hold the result when the function - * has finished. - */ - void encrypt(byte block[]) const { encrypt_n(block, block, 1); } - - /** - * Decrypt a block. - * @param block the ciphertext block to be decrypted - * Must be of length block_size(). Will hold the result when the function - * has finished. - */ - void decrypt(byte block[]) const { decrypt_n(block, block, 1); } - - /** - * Encrypt one or more blocks - * @param in the input buffer (multiple of block_size()) - * @param out the output buffer (same size as in) - * @param blocks the number of blocks to process - */ - virtual void encrypt_n(const byte in[], byte out[], - size_t blocks) const = 0; - - /** - * Decrypt one or more blocks - * @param in the input buffer (multiple of block_size()) - * @param out the output buffer (same size as in) - * @param blocks the number of blocks to process - */ - virtual void decrypt_n(const byte in[], byte out[], - size_t blocks) const = 0; - - /** - * Get a new object representing the same algorithm as *this - */ - virtual BlockCipher* clone() const = 0; - }; - -/** -* Represents a block cipher with a single fixed block size -*/ -template -class Block_Cipher_Fixed_Params : public BlockCipher - { - public: - enum { BLOCK_SIZE = BS }; - size_t block_size() const { return BS; } - - Key_Length_Specification key_spec() const - { - return Key_Length_Specification(KMIN, KMAX, KMOD); - } - }; - -} - - -namespace Botan { - -/** -* Base class for all stream ciphers -*/ -class BOTAN_DLL StreamCipher : public SymmetricAlgorithm - { - public: - /** - * Encrypt or decrypt a message - * @param in the plaintext - * @param out the byte array to hold the output, i.e. the ciphertext - * @param len the length of both in and out in bytes - */ - virtual void cipher(const byte in[], byte out[], size_t len) = 0; - - /** - * Encrypt or decrypt a message - * @param buf the plaintext / ciphertext - * @param len the length of buf in bytes - */ - void cipher1(byte buf[], size_t len) - { cipher(buf, buf, len); } - - /** - * Resync the cipher using the IV - * @param iv the initialization vector - * @param iv_len the length of the IV in bytes - */ - virtual void set_iv(const byte iv[], size_t iv_len); - - /** - * @param iv_len the length of the IV in bytes - * @return if the length is valid for this algorithm - */ - virtual bool valid_iv_length(size_t iv_len) const; - - /** - * Get a new object representing the same algorithm as *this - */ - virtual StreamCipher* clone() const = 0; - }; - -} - - -namespace Botan { - -/** -* This class represents Message Authentication Code (MAC) objects. -*/ -class BOTAN_DLL MessageAuthenticationCode : public Buffered_Computation, - public SymmetricAlgorithm - { - public: - /** - * Verify a MAC. - * @param in the MAC to verify as a byte array - * @param length the length of param in - * @return true if the MAC is valid, false otherwise - */ - virtual bool verify_mac(const byte in[], size_t length); - - /** - * Get a new object representing the same algorithm as *this - */ - virtual MessageAuthenticationCode* clone() const = 0; - - /** - * Get the name of this algorithm. - * @return name of this algorithm - */ - virtual std::string name() const = 0; - }; - -} - - -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. -*/ -class BOTAN_DLL PBKDF : public Algorithm - { - public: - - /** - * @return new instance of this same algorithm - */ - virtual PBKDF* clone() const = 0; - - void clear() {} - - /** - * Derive a key from a passphrase - * @param output_len the desired length of the key to produce - * @param passphrase the password to derive the key from - * @param salt a randomly chosen salt - * @param salt_len length of salt in bytes - * @param iterations the number of iterations to use (use 10K or more) - */ - virtual OctetString derive_key(size_t output_len, - const std::string& passphrase, - const byte salt[], size_t salt_len, - size_t iterations) const = 0; - }; - -/** -* For compatability with 1.8 -*/ -typedef PBKDF S2K; - -} - - -namespace Botan { - -#if (BOTAN_MP_WORD_BITS == 8) - typedef byte word; -#elif (BOTAN_MP_WORD_BITS == 16) - typedef u16bit word; -#elif (BOTAN_MP_WORD_BITS == 32) - typedef u32bit word; -#elif (BOTAN_MP_WORD_BITS == 64) - typedef u64bit word; -#else - #error BOTAN_MP_WORD_BITS must be 8, 16, 32, or 64 -#endif - -const word MP_WORD_MASK = ~static_cast(0); -const word MP_WORD_TOP_BIT = static_cast(1) << (8*sizeof(word) - 1); -const word MP_WORD_MAX = MP_WORD_MASK; - -} - - -namespace Botan { - -/** -* Arbitrary precision integer -*/ -class BOTAN_DLL BigInt - { - public: - /** - * Base enumerator for encoding and decoding - */ - enum Base { Octal = 8, Decimal = 10, Hexadecimal = 16, Binary = 256 }; - - /** - * Sign symbol definitions for positive and negative numbers - */ - enum Sign { Negative = 0, Positive = 1 }; - - /** - * Number types (currently only power-of-2 supported) - */ - enum NumberType { Power2 }; - - /** - * DivideByZero Exception - */ - struct BOTAN_DLL DivideByZero : public Exception - { DivideByZero() : Exception("BigInt divide by zero") {} }; - - /** - * += operator - * @param y the BigInt to add to this - */ - BigInt& operator+=(const BigInt& y); - - /** - * -= operator - * @param y the BigInt to subtract from this - */ - BigInt& operator-=(const BigInt& y); - - /** - * *= operator - * @param y the BigInt to multiply with this - */ - BigInt& operator*=(const BigInt& y); - - /** - * /= operator - * @param y the BigInt to divide this by - */ - BigInt& operator/=(const BigInt& y); - - /** - * Modulo operator - * @param y the modulus to reduce this by - */ - BigInt& operator%=(const BigInt& y); - - /** - * Modulo operator - * @param y the modulus (word) to reduce this by - */ - word operator%=(word y); - - /** - * Left shift operator - * @param shift the number of bits to shift this left by - */ - BigInt& operator<<=(size_t shift); - - /** - * Right shift operator - * @param shift the number of bits to shift this right by - */ - BigInt& operator>>=(size_t shift); - - /** - * Increment operator - */ - BigInt& operator++() { return (*this += 1); } - - /** - * Decrement operator - */ - BigInt& operator--() { return (*this -= 1); } - - /** - * Postfix increment operator - */ - BigInt operator++(int) { BigInt x = (*this); ++(*this); return x; } - - /** - * Postfix decrement operator - */ - BigInt operator--(int) { BigInt x = (*this); --(*this); return x; } - - /** - * Unary negation operator - * @return negative this - */ - BigInt operator-() const; - - /** - * ! operator - * @return true iff this is zero, otherwise false - */ - bool operator !() const { return (!is_nonzero()); } - - /** - * [] operator (array access) - * @param i a word index - * @return the word at index i - */ - word& operator[](size_t i) { return reg[i]; } - - /** - * [] operator (array access) - * @param i a word index - * @return the word at index i - */ - const word& operator[](size_t i) const { return reg[i]; } - - /** - * Zeroize the BigInt - */ - void clear() { zeroise(reg); } - - /** - * Compare this to another BigInt - * @param n the BigInt value to compare with - * @param check_signs include sign in comparison? - * @result if (thisn) return 1, if both - * values are identical return 0 [like Perl's <=> operator] - */ - s32bit cmp(const BigInt& n, bool check_signs = true) const; - - /** - * Test if the integer has an even value - * @result true if the integer is even, false otherwise - */ - bool is_even() const { return (get_bit(0) == 0); } - - /** - * Test if the integer has an odd value - * @result true if the integer is odd, false otherwise - */ - bool is_odd() const { return (get_bit(0) == 1); } - - /** - * Test if the integer is not zero - * @result true if the integer is non-zero, false otherwise - */ - bool is_nonzero() const { return (!is_zero()); } - - /** - * Test if the integer is zero - * @result true if the integer is zero, false otherwise - */ - bool is_zero() const - { - const size_t sw = sig_words(); - - for(size_t i = 0; i != sw; ++i) - if(reg[i]) - return false; - return true; - } - - /** - * Set bit at specified position - * @param n bit position to set - */ - void set_bit(size_t n); - - /** - * Clear bit at specified position - * @param n bit position to clear - */ - void clear_bit(size_t n); - - /** - * Clear all but the lowest n bits - * @param n amount of bits to keep - */ - void mask_bits(size_t n); - - /** - * Return bit value at specified position - * @param n the bit offset to test - * @result true, if the bit at position n is set, false otherwise - */ - bool get_bit(size_t n) const; - - /** - * Return (a maximum of) 32 bits of the complete value - * @param offset the offset to start extracting - * @param length amount of bits to extract (starting at offset) - * @result the integer extracted from the register starting at - * offset with specified length - */ - u32bit get_substring(size_t offset, size_t length) const; - - /** - * Convert this value into a u32bit, if it is in the range - * [0 ... 2**32-1], or otherwise throw an exception. - * @result the value as a u32bit if conversion is possible - */ - u32bit to_u32bit() const; - - /** - * @param n the offset to get a byte from - * @result byte at offset n - */ - byte byte_at(size_t n) const; - - /** - * Return the word at a specified position of the internal register - * @param n position in the register - * @return value at position n - */ - word word_at(size_t n) const - { return ((n < size()) ? reg[n] : 0); } - - /** - * Tests if the sign of the integer is negative - * @result true, iff the integer has a negative sign - */ - bool is_negative() const { return (sign() == Negative); } - - /** - * Tests if the sign of the integer is positive - * @result true, iff the integer has a positive sign - */ - bool is_positive() const { return (sign() == Positive); } - - /** - * Return the sign of the integer - * @result the sign of the integer - */ - Sign sign() const { return (signedness); } - - /** - * @result the opposite sign of the represented integer value - */ - Sign reverse_sign() const; - - /** - * Flip the sign of this BigInt - */ - void flip_sign(); - - /** - * Set sign of the integer - * @param sign new Sign to set - */ - void set_sign(Sign sign); - - /** - * @result absolute (positive) value of this - */ - BigInt abs() const; - - /** - * Give size of internal register - * @result size of internal register in words - */ - size_t size() const { return get_reg().size(); } - - /** - * Return how many words we need to hold this value - * @result significant words of the represented integer value - */ - size_t sig_words() const - { - const word* x = ®[0]; - size_t sig = reg.size(); - - while(sig && (x[sig-1] == 0)) - sig--; - return sig; - } - - /** - * Give byte length of the integer - * @result byte length of the represented integer value - */ - size_t bytes() const; - - /** - * Get the bit length of the integer - * @result bit length of the represented integer value - */ - size_t bits() const; - - /** - * Return a pointer to the big integer word register - * @result a pointer to the start of the internal register of - * the integer value - */ - const word* data() const { return ®[0]; } - - /** - * return a reference to the internal register containing the value - * @result a reference to the word-array (SecureVector) - * with the internal register value (containing the integer - * value) - */ - SecureVector& get_reg() { return reg; } - - /** - * return a const reference to the internal register containing the value - * @result a const reference to the word-array (SecureVector) - * with the internal register value (containing the integer value) - */ - const SecureVector& get_reg() const { return reg; } - - /** - * Assign using a plain word array - */ - void assign(const word x[], size_t length) - { - reg.resize(length); - copy_mem(®[0], x, length); - } - - /** - * Increase internal register buffer by n words - * @param n increase by n words - */ - void grow_reg(size_t n); - - void grow_to(size_t n); - - /** - * Fill BigInt with a random number with size of bitsize - * @param rng the random number generator to use - * @param bitsize number of bits the created random value should have - */ - void randomize(RandomNumberGenerator& rng, size_t bitsize = 0); - - /** - * Store BigInt-value in a given byte array - * @param buf destination byte array for the integer value - */ - void binary_encode(byte buf[]) const; - - /** - * Read integer value from a byte array with given size - * @param buf byte array buffer containing the integer - * @param length size of buf - */ - void binary_decode(const byte buf[], size_t length); - - /** - * Read integer value from a byte array (MemoryRegion) - * @param buf the array to load from - */ - void binary_decode(const MemoryRegion& buf); - - /** - * @param base the base to measure the size for - * @return size of this integer in base base - */ - size_t encoded_size(Base base = Binary) const; - - /** - * @param rng a random number generator - * @param min the minimum value - * @param max the maximum value - * @return random integer between min and max - */ - static BigInt random_integer(RandomNumberGenerator& rng, - const BigInt& min, - const BigInt& max); - - /** - * Encode the integer value from a BigInt to a SecureVector of bytes - * @param n the BigInt to use as integer source - * @param base number-base of resulting byte array representation - * @result SecureVector of bytes containing the integer with given base - */ - static SecureVector encode(const BigInt& n, Base base = Binary); - - /** - * Encode the integer value from a BigInt to a byte array - * @param buf destination byte array for the encoded integer - * value with given base - * @param n the BigInt to use as integer source - * @param base number-base of resulting byte array representation - */ - static void encode(byte buf[], const BigInt& n, Base base = Binary); - - /** - * Create a BigInt from an integer in a byte array - * @param buf the binary value to load - * @param length size of buf - * @param base number-base of the integer in buf - * @result BigInt representing the integer in the byte array - */ - static BigInt decode(const byte buf[], size_t length, - Base base = Binary); - - /** - * Create a BigInt from an integer in a byte array - * @param buf the binary value to load - * @param base number-base of the integer in buf - * @result BigInt representing the integer in the byte array - */ - static BigInt decode(const MemoryRegion& buf, - Base base = Binary); - - /** - * Encode a BigInt to a byte array according to IEEE 1363 - * @param n the BigInt to encode - * @param bytes the length of the resulting SecureVector - * @result a SecureVector containing the encoded BigInt - */ - static SecureVector encode_1363(const BigInt& n, size_t bytes); - - /** - * Swap this value with another - * @param other BigInt to swap values with - */ - void swap(BigInt& other); - - /** - * Create empty BigInt - */ - BigInt() { signedness = Positive; } - - /** - * Create BigInt from 64 bit integer - * @param n initial value of this BigInt - */ - BigInt(u64bit n); - - /** - * Copy Constructor - * @param other the BigInt to copy - */ - BigInt(const BigInt& other); - - /** - * Create BigInt from a string. If the string starts with 0x the - * rest of the string will be interpreted as hexadecimal digits. - * If the string starts with 0 and the second character is NOT an - * 'x' the string will be interpreted as octal digits. If the - * string starts with non-zero digit, it will be interpreted as a - * decimal number. - * - * @param str the string to parse for an integer value - */ - BigInt(const std::string& str); - - /** - * 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 - */ - BigInt(const byte buf[], size_t length, Base base = Binary); - - /** - * Create a random BigInt of the specified size - * @param rng random number generator - * @param bits size in bits - */ - BigInt(RandomNumberGenerator& rng, size_t bits); - - /** - * Create BigInt of specified size, all zeros - * @param sign the sign - * @param n size of the internal register in words - */ - BigInt(Sign sign, size_t n); - - /** - * Create a number of the specified type and size - * @param type the type of number to create. For Power2, - * will create the integer 2^n - * @param n a size/length parameter, interpretation depends upon - * the value of type - */ - BigInt(NumberType type, size_t n); - - private: - SecureVector reg; - Sign signedness; - }; - -/* -* Arithmetic Operators -*/ -BigInt BOTAN_DLL operator+(const BigInt& x, const BigInt& y); -BigInt BOTAN_DLL operator-(const BigInt& x, const BigInt& y); -BigInt BOTAN_DLL operator*(const BigInt& x, const BigInt& y); -BigInt BOTAN_DLL operator/(const BigInt& x, const BigInt& d); -BigInt BOTAN_DLL operator%(const BigInt& x, const BigInt& m); -word BOTAN_DLL operator%(const BigInt& x, word m); -BigInt BOTAN_DLL operator<<(const BigInt& x, size_t n); -BigInt BOTAN_DLL operator>>(const BigInt& x, size_t n); - -/* -* Comparison Operators -*/ -inline bool operator==(const BigInt& a, const BigInt& b) - { return (a.cmp(b) == 0); } -inline bool operator!=(const BigInt& a, const BigInt& b) - { return (a.cmp(b) != 0); } -inline bool operator<=(const BigInt& a, const BigInt& b) - { return (a.cmp(b) <= 0); } -inline bool operator>=(const BigInt& a, const BigInt& b) - { return (a.cmp(b) >= 0); } -inline bool operator<(const BigInt& a, const BigInt& b) - { return (a.cmp(b) < 0); } -inline bool operator>(const BigInt& a, const BigInt& b) - { return (a.cmp(b) > 0); } - -/* -* I/O Operators -*/ -BOTAN_DLL std::ostream& operator<<(std::ostream&, const BigInt&); -BOTAN_DLL std::istream& operator>>(std::istream&, BigInt&); - -} - -namespace std { - -template<> -inline void swap(Botan::BigInt& x, Botan::BigInt& y) - { - x.swap(y); - } - -} - - -namespace Botan { - -/** -* Modular Exponentiator Interface -*/ -class BOTAN_DLL Modular_Exponentiator - { - public: - virtual void set_base(const BigInt&) = 0; - virtual void set_exponent(const BigInt&) = 0; - virtual BigInt execute() const = 0; - virtual Modular_Exponentiator* copy() const = 0; - virtual ~Modular_Exponentiator() {} - }; - -/** -* Modular Exponentiator Proxy -*/ -class BOTAN_DLL Power_Mod - { - public: - - enum Usage_Hints { - NO_HINTS = 0x0000, - - BASE_IS_FIXED = 0x0001, - BASE_IS_SMALL = 0x0002, - BASE_IS_LARGE = 0x0004, - BASE_IS_2 = 0x0008, - - EXP_IS_FIXED = 0x0100, - EXP_IS_SMALL = 0x0200, - EXP_IS_LARGE = 0x0400 - }; - - /* - * Try to choose a good window size - */ - static size_t window_bits(size_t exp_bits, size_t base_bits, - Power_Mod::Usage_Hints hints); - - void set_modulus(const BigInt&, Usage_Hints = NO_HINTS) const; - void set_base(const BigInt&) const; - void set_exponent(const BigInt&) const; - - BigInt execute() const; - - Power_Mod& operator=(const Power_Mod&); - - Power_Mod(const BigInt& = 0, Usage_Hints = NO_HINTS); - Power_Mod(const Power_Mod&); - virtual ~Power_Mod(); - private: - mutable Modular_Exponentiator* core; - Usage_Hints hints; - }; - -/** -* Fixed Exponent Modular Exponentiator Proxy -*/ -class BOTAN_DLL Fixed_Exponent_Power_Mod : public Power_Mod - { - public: - BigInt operator()(const BigInt& b) const - { set_base(b); return execute(); } - - Fixed_Exponent_Power_Mod() {} - Fixed_Exponent_Power_Mod(const BigInt&, const BigInt&, - Usage_Hints = NO_HINTS); - }; - -/** -* Fixed Base Modular Exponentiator Proxy -*/ -class BOTAN_DLL Fixed_Base_Power_Mod : public Power_Mod - { - public: - BigInt operator()(const BigInt& e) const - { set_exponent(e); return execute(); } - - Fixed_Base_Power_Mod() {} - Fixed_Base_Power_Mod(const BigInt&, const BigInt&, - Usage_Hints = NO_HINTS); - }; - -} - - -namespace Botan { - -/** -* ASN.1 Type and Class Tags -*/ -enum ASN1_Tag { - UNIVERSAL = 0x00, - APPLICATION = 0x40, - CONTEXT_SPECIFIC = 0x80, - PRIVATE = 0xC0, - - CONSTRUCTED = 0x20, - - EOC = 0x00, - BOOLEAN = 0x01, - INTEGER = 0x02, - BIT_STRING = 0x03, - OCTET_STRING = 0x04, - NULL_TAG = 0x05, - OBJECT_ID = 0x06, - ENUMERATED = 0x0A, - SEQUENCE = 0x10, - SET = 0x11, - - UTF8_STRING = 0x0C, - NUMERIC_STRING = 0x12, - PRINTABLE_STRING = 0x13, - T61_STRING = 0x14, - IA5_STRING = 0x16, - VISIBLE_STRING = 0x1A, - BMP_STRING = 0x1E, - - UTC_TIME = 0x17, - GENERALIZED_TIME = 0x18, - - NO_OBJECT = 0xFF00, - DIRECTORY_STRING = 0xFF01 -}; - -/** -* Basic ASN.1 Object Interface -*/ -class BOTAN_DLL ASN1_Object - { - public: - /** - * Encode whatever this object is into to - * @param to the DER_Encoder that will be written to - */ - virtual void encode_into(class DER_Encoder& to) const = 0; - - /** - * Decode whatever this object is from from - * @param from the BER_Decoder that will be read from - */ - virtual void decode_from(class BER_Decoder& from) = 0; - - virtual ~ASN1_Object() {} - }; - -/** -* BER Encoded Object -*/ -class BOTAN_DLL BER_Object - { - public: - void assert_is_a(ASN1_Tag, ASN1_Tag); - - ASN1_Tag type_tag, class_tag; - SecureVector value; - }; - -/* -* ASN.1 Utility Functions -*/ -class DataSource; - -namespace ASN1 { - -SecureVector put_in_sequence(const MemoryRegion& val); -std::string to_string(const BER_Object& obj); - -/** -* Heuristics tests; is this object possibly BER? -* @param src a data source that will be peeked at but not modified -*/ -bool maybe_BER(DataSource& src); - -} - -/** -* General BER Decoding Error Exception -*/ -struct BOTAN_DLL BER_Decoding_Error : public Decoding_Error - { - BER_Decoding_Error(const std::string&); - }; - -/** -* Exception For Incorrect BER Taggings -*/ -struct BOTAN_DLL BER_Bad_Tag : public BER_Decoding_Error - { - BER_Bad_Tag(const std::string& msg, ASN1_Tag tag); - BER_Bad_Tag(const std::string& msg, ASN1_Tag tag1, ASN1_Tag tag2); - }; - -} - - -namespace Botan { - -/** -* This class represents ASN.1 object identifiers. -*/ -class BOTAN_DLL OID : public ASN1_Object - { - public: - void encode_into(class DER_Encoder&) const; - void decode_from(class BER_Decoder&); - - /** - * Find out whether this OID is empty - * @return true is no OID value is set - */ - bool is_empty() const { return id.size() == 0; } - - /** - * Get this OID as list (vector) of its components. - * @return vector representing this OID - */ - std::vector get_id() const { return id; } - - /** - * Get this OID as a string - * @return string representing this OID - */ - std::string as_string() const; - - /** - * Compare two OIDs. - * @return true if they are equal, false otherwise - */ - bool operator==(const OID&) const; - - /** - * Reset this instance to an empty OID. - */ - void clear(); - - /** - * Add a component to this OID. - * @param new_comp the new component to add to the end of this OID - * @return reference to *this - */ - OID& operator+=(u32bit new_comp); - - /** - * Construct an OID from a string. - * @param str a string in the form "a.b.c" etc., where a,b,c are numbers - */ - OID(const std::string& str = ""); - private: - std::vector id; - }; - -/** -* Append another component onto the OID. -* @param oid the OID to add the new component to -* @param new_comp the new component to add -*/ -OID operator+(const OID& oid, u32bit new_comp); - -/** -* Compare two OIDs. -* @param a the first OID -* @param b the second OID -* @return true if a is not equal to b -*/ -bool operator!=(const OID& a, const OID& b); - -/** -* Compare two OIDs. -* @param a the first OID -* @param b the second OID -* @return true if a is lexicographically smaller than b -*/ -bool operator<(const OID& a, const OID& b); - -} - - -namespace Botan { - -/** -* Algorithm Identifier -*/ -class BOTAN_DLL AlgorithmIdentifier : public ASN1_Object - { - public: - enum Encoding_Option { USE_NULL_PARAM }; - - void encode_into(class DER_Encoder&) const; - void decode_from(class BER_Decoder&); - - AlgorithmIdentifier() {} - AlgorithmIdentifier(const OID&, Encoding_Option); - AlgorithmIdentifier(const std::string&, Encoding_Option); - - AlgorithmIdentifier(const OID&, const MemoryRegion&); - AlgorithmIdentifier(const std::string&, const MemoryRegion&); - - OID oid; - SecureVector parameters; - }; - -/* -* Comparison Operations -*/ -bool BOTAN_DLL operator==(const AlgorithmIdentifier&, - const AlgorithmIdentifier&); -bool BOTAN_DLL operator!=(const AlgorithmIdentifier&, - const AlgorithmIdentifier&); - -} - - -namespace Botan { - -/** -* Public Key Base Class. -*/ -class BOTAN_DLL Public_Key - { - public: - /** - * Get the name of the underlying public key scheme. - * @return name of the public key scheme - */ - virtual std::string algo_name() const = 0; - - /** - * Get the OID of the underlying public key scheme. - * @return OID of the public key scheme - */ - virtual OID get_oid() const; - - /** - * Test the key values for consistency. - * @param rng rng to use - * @param strong whether to perform strong and lengthy version - * of the test - * @return true if the test is passed - */ - virtual bool check_key(RandomNumberGenerator& rng, - bool strong) const = 0; - - /** - * Find out the number of message parts supported by this scheme. - * @return number of message parts - */ - virtual size_t message_parts() const { return 1; } - - /** - * Find out the message part size supported by this scheme/key. - * @return size of the message parts in bits - */ - virtual size_t message_part_size() const { return 0; } - - /** - * Get the maximum message size in bits supported by this public key. - * @return maximum message size in bits - */ - virtual size_t max_input_bits() const = 0; - - /** - * @return X.509 AlgorithmIdentifier for this key - */ - virtual AlgorithmIdentifier algorithm_identifier() const = 0; - - /** - * @return X.509 subject key encoding for this key object - */ - virtual MemoryVector x509_subject_public_key() const = 0; - - virtual ~Public_Key() {} - protected: - /** - * Self-test after loading a key - * @param rng a random number generator - */ - virtual void load_check(RandomNumberGenerator& rng) const; - }; - -/** -* Private Key Base Class -*/ -class BOTAN_DLL Private_Key : public virtual Public_Key - { - public: - /** - * @return PKCS #8 private key encoding for this key object - */ - virtual MemoryVector pkcs8_private_key() const = 0; - - /** - * @return PKCS #8 AlgorithmIdentifier for this key - * Might be different from the X.509 identifier, but normally is not - */ - virtual AlgorithmIdentifier pkcs8_algorithm_identifier() const - { return algorithm_identifier(); } - - protected: - /** - * Self-test after loading a key - * @param rng a random number generator - */ - void load_check(RandomNumberGenerator& rng) const; - - /** - * Self-test after generating a key - * @param rng a random number generator - */ - void gen_check(RandomNumberGenerator& rng) const; - }; - -/** -* PK Secret Value Derivation Key -*/ -class BOTAN_DLL PK_Key_Agreement_Key : public virtual Private_Key - { - public: - /* - * @return public component of this key - */ - virtual MemoryVector public_value() const = 0; - - virtual ~PK_Key_Agreement_Key() {} - }; - -/* -* Typedefs -*/ -typedef PK_Key_Agreement_Key PK_KA_Key; -typedef Public_Key X509_PublicKey; -typedef Private_Key PKCS8_PrivateKey; - -} - - -namespace Botan { - -namespace PK_Ops { - -/** -* Public key encryption interface -*/ -class BOTAN_DLL Encryption - { - public: - virtual size_t max_input_bits() const = 0; - - virtual SecureVector encrypt(const byte msg[], size_t msg_len, - RandomNumberGenerator& rng) = 0; - - virtual ~Encryption() {} - }; - -/** -* Public key decryption interface -*/ -class BOTAN_DLL Decryption - { - public: - virtual size_t max_input_bits() const = 0; - - virtual SecureVector decrypt(const byte msg[], - size_t msg_len) = 0; - - virtual ~Decryption() {} - }; - -/** -* Public key signature creation interface -*/ -class BOTAN_DLL Signature - { - public: - /** - * Find out the number of message parts supported by this scheme. - * @return number of message parts - */ - virtual size_t message_parts() const { return 1; } - - /** - * Find out the message part size supported by this scheme/key. - * @return size of the message parts - */ - virtual size_t message_part_size() const { return 0; } - - /** - * Get the maximum message size in bits supported by this public key. - * @return maximum message in bits - */ - virtual size_t max_input_bits() const = 0; - - /* - * Perform a signature operation - * @param msg the message - * @param msg_len the length of msg in bytes - * @param rng a random number generator - */ - virtual SecureVector sign(const byte msg[], size_t msg_len, - RandomNumberGenerator& rng) = 0; - - virtual ~Signature() {} - }; - -/** -* Public key signature verification interface -*/ -class BOTAN_DLL Verification - { - public: - /** - * Get the maximum message size in bits supported by this public key. - * @return maximum message in bits - */ - virtual size_t max_input_bits() const = 0; - - /** - * Find out the number of message parts supported by this scheme. - * @return number of message parts - */ - virtual size_t message_parts() const { return 1; } - - /** - * Find out the message part size supported by this scheme/key. - * @return size of the message parts - */ - virtual size_t message_part_size() const { return 0; } - - /** - * @return boolean specifying if this key type supports message - * recovery and thus if you need to call verify() or verify_mr() - */ - virtual bool with_recovery() const = 0; - - /* - * Perform a signature check operation - * @param msg the message - * @param msg_len the length of msg in bytes - * @param sig the signature - * @param sig_len the length of sig in bytes - * @returns if signature is a valid one for message - */ - virtual bool verify(const byte[], size_t, - const byte[], size_t) - { - throw Invalid_State("Message recovery required"); - } - - /* - * Perform a signature operation (with message recovery) - * Only call this if with_recovery() returns true - * @param msg the message - * @param msg_len the length of msg in bytes - * @returns recovered message - */ - virtual SecureVector verify_mr(const byte[], - size_t) - { - throw Invalid_State("Message recovery not supported"); - } - - virtual ~Verification() {} - }; - -/** -* A generic key agreement Operation (eg DH or ECDH) -*/ -class BOTAN_DLL Key_Agreement - { - public: - /* - * Perform a key agreement operation - * @param w the other key value - * @param w_len the length of w in bytes - * @returns the agreed key - */ - virtual SecureVector agree(const byte w[], size_t w_len) = 0; - - virtual ~Key_Agreement() {} - }; - -} - -} - - -namespace Botan { - -class Algorithm_Factory; -class Keyed_Filter; - -/** -* Base class for all engines. All non-pure virtual functions simply -* return NULL, indicating the algorithm in question is not -* supported. Subclasses can reimplement whichever function(s) -* they want to hook in a particular type. -*/ -class BOTAN_DLL Engine - { - public: - virtual ~Engine() {} - - /** - * @return name of this engine - */ - virtual std::string provider_name() const = 0; - - /** - * @param algo_spec the algorithm name/specification - * @param af an algorithm factory object - * @return newly allocated object, or NULL - */ - virtual BlockCipher* - find_block_cipher(const SCAN_Name& algo_spec, - Algorithm_Factory& af) const; - - /** - * @param algo_spec the algorithm name/specification - * @param af an algorithm factory object - * @return newly allocated object, or NULL - */ - virtual StreamCipher* - find_stream_cipher(const SCAN_Name& algo_spec, - Algorithm_Factory& af) const; - - /** - * @param algo_spec the algorithm name/specification - * @param af an algorithm factory object - * @return newly allocated object, or NULL - */ - virtual HashFunction* - find_hash(const SCAN_Name& algo_spec, - Algorithm_Factory& af) const; - - /** - * @param algo_spec the algorithm name/specification - * @param af an algorithm factory object - * @return newly allocated object, or NULL - */ - virtual MessageAuthenticationCode* - find_mac(const SCAN_Name& algo_spec, - Algorithm_Factory& af) const; - - /** - * @param algo_spec the algorithm name/specification - * @param af an algorithm factory object - * @return newly allocated object, or NULL - */ - virtual PBKDF* find_pbkdf(const SCAN_Name& algo_spec, - Algorithm_Factory& af) const; - - /** - * @param n the modulus - * @param hints any use hints - * @return newly allocated object, or NULL - */ - virtual Modular_Exponentiator* - mod_exp(const BigInt& n, - Power_Mod::Usage_Hints hints) const; - - /** - * Return a new cipher object - * @param algo_spec the algorithm name/specification - * @param dir specifies if encryption or decryption is desired - * @param af an algorithm factory object - * @return newly allocated object, or NULL - */ - virtual Keyed_Filter* get_cipher(const std::string& algo_spec, - Cipher_Dir dir, - Algorithm_Factory& af); - - /** - * Return a new operator object for this key, if possible - * @param key the key we want an operator for - * @return newly allocated operator object, or NULL - */ - virtual PK_Ops::Key_Agreement* - get_key_agreement_op(const Private_Key& key) const; - - /** - * Return a new operator object for this key, if possible - * @param key the key we want an operator for - * @return newly allocated operator object, or NULL - */ - virtual PK_Ops::Signature* - get_signature_op(const Private_Key& key) const; - - /** - * Return a new operator object for this key, if possible - * @param key the key we want an operator for - * @return newly allocated operator object, or NULL - */ - virtual PK_Ops::Verification* - get_verify_op(const Public_Key& key) const; - - /** - * Return a new operator object for this key, if possible - * @param key the key we want an operator for - * @return newly allocated operator object, or NULL - */ - virtual PK_Ops::Encryption* - get_encryption_op(const Public_Key& key) const; - - /** - * Return a new operator object for this key, if possible - * @param key the key we want an operator for - * @return newly allocated operator object, or NULL - */ - virtual PK_Ops::Decryption* - get_decryption_op(const Private_Key& key) const; - }; - -} - - -namespace Botan { - -/** -* Dynamically_Loaded_Engine just proxies the requests to the underlying -* Engine object, and handles load/unload details -*/ -class BOTAN_DLL Dynamically_Loaded_Engine : public Engine - { - public: - /** - * @param lib_path full pathname to DLL to load - */ - Dynamically_Loaded_Engine(const std::string& lib_path); - - ~Dynamically_Loaded_Engine(); - - std::string provider_name() const { return engine->provider_name(); } - - BlockCipher* find_block_cipher(const SCAN_Name& algo_spec, - Algorithm_Factory& af) const - { - return engine->find_block_cipher(algo_spec, af); - } - - StreamCipher* find_stream_cipher(const SCAN_Name& algo_spec, - Algorithm_Factory& af) const - { - return engine->find_stream_cipher(algo_spec, af); - } - - HashFunction* find_hash(const SCAN_Name& algo_spec, - Algorithm_Factory& af) const - { - return engine->find_hash(algo_spec, af); - } - - MessageAuthenticationCode* find_mac(const SCAN_Name& algo_spec, - Algorithm_Factory& af) const - { - return engine->find_mac(algo_spec, af); - } - - PBKDF* find_pbkdf(const SCAN_Name& algo_spec, - Algorithm_Factory& af) const - { - return engine->find_pbkdf(algo_spec, af); - } - - Modular_Exponentiator* mod_exp(const BigInt& n, - Power_Mod::Usage_Hints hints) const - { - return engine->mod_exp(n, hints); - } - - Keyed_Filter* get_cipher(const std::string& algo_spec, - Cipher_Dir dir, - Algorithm_Factory& af) - { - return engine->get_cipher(algo_spec, dir, af); - } - - PK_Ops::Key_Agreement* - get_key_agreement_op(const Private_Key& key) const - { - return engine->get_key_agreement_op(key); - } - - PK_Ops::Signature* - get_signature_op(const Private_Key& key) const - { - return engine->get_signature_op(key); - } - - PK_Ops::Verification* - get_verify_op(const Public_Key& key) const - { - return engine->get_verify_op(key); - } - - PK_Ops::Encryption* - get_encryption_op(const Public_Key& key) const - { - return engine->get_encryption_op(key); - } - - PK_Ops::Decryption* - get_decryption_op(const Private_Key& key) const - { - return engine->get_decryption_op(key); - } - - private: - class Dynamically_Loaded_Library* lib; - Engine* engine; - }; - -} - - -namespace Botan { - -/** -* Simple String -*/ -class BOTAN_DLL ASN1_String : public ASN1_Object - { - public: - void encode_into(class DER_Encoder&) const; - void decode_from(class BER_Decoder&); - - std::string value() const; - std::string iso_8859() const; - - ASN1_Tag tagging() const; - - ASN1_String(const std::string& = ""); - ASN1_String(const std::string&, ASN1_Tag); - private: - std::string iso_8859_str; - ASN1_Tag tag; - }; - -} - - -namespace Botan { - -/** -* Attribute -*/ -class BOTAN_DLL Attribute : public ASN1_Object - { - public: - void encode_into(class DER_Encoder& to) const; - void decode_from(class BER_Decoder& from); - - OID oid; - MemoryVector parameters; - - Attribute() {} - Attribute(const OID&, const MemoryRegion&); - Attribute(const std::string&, const MemoryRegion&); - }; - -/** -* X.509 Time -*/ -class BOTAN_DLL X509_Time : public ASN1_Object - { - public: - void encode_into(class DER_Encoder&) const; - void decode_from(class BER_Decoder&); - - std::string as_string() const; - std::string readable_string() const; - bool time_is_set() const; - - s32bit cmp(const X509_Time&) const; - - void set_to(const std::string&); - void set_to(const std::string&, ASN1_Tag); - - X509_Time(u64bit); - X509_Time(const std::string& = ""); - X509_Time(const std::string&, ASN1_Tag); - private: - bool passes_sanity_check() const; - u32bit year, month, day, hour, minute, second; - ASN1_Tag tag; - }; - -/** -* Alternative Name -*/ -class BOTAN_DLL AlternativeName : public ASN1_Object - { - public: - void encode_into(class DER_Encoder&) const; - void decode_from(class BER_Decoder&); - - std::multimap contents() const; - - void add_attribute(const std::string&, const std::string&); - std::multimap get_attributes() const; - - void add_othername(const OID&, const std::string&, ASN1_Tag); - std::multimap get_othernames() const; - - bool has_items() const; - - AlternativeName(const std::string& = "", const std::string& = "", - const std::string& = "", const std::string& = ""); - private: - std::multimap alt_info; - std::multimap othernames; - }; - -/* -* Comparison Operations -*/ -bool BOTAN_DLL operator==(const X509_Time&, const X509_Time&); -bool BOTAN_DLL operator!=(const X509_Time&, const X509_Time&); -bool BOTAN_DLL operator<=(const X509_Time&, const X509_Time&); -bool BOTAN_DLL operator>=(const X509_Time&, const X509_Time&); -bool BOTAN_DLL operator<(const X509_Time&, const X509_Time&); -bool BOTAN_DLL operator>(const X509_Time&, const X509_Time&); - -} - - -namespace Botan { - -/** -* This class represents an abstract data source object. -*/ -class BOTAN_DLL DataSource - { - public: - /** - * Read from the source. Moves the internal offset so that every - * call to read will return a new portion of the source. - * - * @param out the byte array to write the result to - * @param length the length of the byte array out - * @return length in bytes that was actually read and put - * into out - */ - virtual size_t read(byte out[], size_t length) = 0; - - /** - * Read from the source but do not modify the internal - * offset. Consecutive calls to peek() will return portions of - * the source starting at the same position. - * - * @param out the byte array to write the output to - * @param length the length of the byte array out - * @param peek_offset the offset into the stream to read at - * @return length in bytes that was actually read and put - * into out - */ - virtual size_t peek(byte out[], size_t length, - size_t peek_offset) const = 0; - - /** - * Test whether the source still has data that can be read. - * @return true if there is still data to read, false otherwise - */ - virtual bool end_of_data() const = 0; - /** - * return the id of this data source - * @return std::string representing the id of this data source - */ - virtual std::string id() const { return ""; } - - /** - * Read one byte. - * @param out the byte to read to - * @return length in bytes that was actually read and put - * into out - */ - size_t read_byte(byte& out); - - /** - * Peek at one byte. - * @param out an output byte - * @return length in bytes that was actually read and put - * into out - */ - size_t peek_byte(byte& out) const; - - /** - * Discard the next N bytes of the data - * @param N the number of bytes to discard - * @return number of bytes actually discarded - */ - size_t discard_next(size_t N); - - DataSource() {} - virtual ~DataSource() {} - private: - DataSource& operator=(const DataSource&) { return (*this); } - DataSource(const DataSource&); - }; - -/** -* This class represents a Memory-Based DataSource -*/ -class BOTAN_DLL DataSource_Memory : public DataSource - { - public: - size_t read(byte[], size_t); - size_t peek(byte[], size_t, size_t) const; - bool end_of_data() const; - - /** - * Construct a memory source that reads from a string - * @param in the string to read from - */ - DataSource_Memory(const std::string& in); - - /** - * Construct a memory source that reads from a byte array - * @param in the byte array to read from - * @param length the length of the byte array - */ - DataSource_Memory(const byte in[], size_t length); - - /** - * Construct a memory source that reads from a MemoryRegion - * @param in the MemoryRegion to read from - */ - DataSource_Memory(const MemoryRegion& in); - private: - SecureVector source; - size_t offset; - }; - -/** -* This class represents a Stream-Based DataSource. -*/ -class BOTAN_DLL DataSource_Stream : public DataSource - { - public: - size_t read(byte[], size_t); - size_t peek(byte[], size_t, size_t) const; - bool end_of_data() const; - std::string id() const; - - DataSource_Stream(std::istream&, - const std::string& id = ""); - - /** - * Construct a Stream-Based DataSource from file - * @param file the name of the file - * @param use_binary whether to treat the file as binary or not - */ - DataSource_Stream(const std::string& file, bool use_binary = false); - - ~DataSource_Stream(); - private: - const std::string identifier; - - std::istream* source_p; - std::istream& source; - size_t total_read; - }; - -} - - -namespace Botan { - -/** -* This class represents general abstract filter objects. -*/ -class BOTAN_DLL Filter - { - public: - /** - * @return descriptive name for this filter - */ - virtual std::string name() const = 0; - - /** - * Write a portion of a message to this filter. - * @param input the input as a byte array - * @param length the length of the byte array input - */ - virtual void write(const byte input[], size_t length) = 0; - - /** - * Start a new message. Must be closed by end_msg() before another - * message can be started. - */ - virtual void start_msg() {} - - /** - * Notify that the current message is finished; flush buffers and - * do end-of-message processing (if any). - */ - virtual void end_msg() {} - - /** - * Check whether this filter is an attachable filter. - * @return true if this filter is attachable, false otherwise - */ - virtual bool attachable() { return true; } - - virtual ~Filter() {} - protected: - /** - * @param in some input for the filter - * @param length the length of in - */ - void send(const byte in[], size_t length); - - /** - * @param in some input for the filter - */ - void send(byte in) { send(&in, 1); } - - /** - * @param in some input for the filter - */ - void send(const MemoryRegion& in) { send(&in[0], in.size()); } - - /** - * @param in some input for the filter - * @param length the number of bytes of in to send - */ - void send(const MemoryRegion& in, size_t length) - { - send(&in[0], length); - } - - Filter(); - private: - Filter(const Filter&) {} - Filter& operator=(const Filter&) { return (*this); } - - /** - * Start a new message in *this and all following filters. Only for - * internal use, not intended for use in client applications. - */ - void new_msg(); - - /** - * End a new message in *this and all following filters. Only for - * internal use, not intended for use in client applications. - */ - void finish_msg(); - - friend class Pipe; - friend class Fanout_Filter; - - size_t total_ports() const; - size_t current_port() const { return port_num; } - - /** - * Set the active port - * @param new_port the new value - */ - void set_port(size_t new_port); - - size_t owns() const { return filter_owns; } - - /** - * Attach another filter to this one - * @param f filter to attach - */ - void attach(Filter* f); - - /** - * @param filters the filters to set - * @param count number of items in filters - */ - void set_next(Filter* filters[], size_t count); - Filter* get_next() const; - - SecureVector write_queue; - std::vector next; - size_t port_num, filter_owns; - - // true if filter belongs to a pipe --> prohibit filter sharing! - bool owned; - }; - -/** -* This is the abstract Fanout_Filter base class. -**/ -class BOTAN_DLL Fanout_Filter : public Filter - { - protected: - /** - * Increment the number of filters past us that we own - */ - void incr_owns() { ++filter_owns; } - - void set_port(size_t n) { Filter::set_port(n); } - - void set_next(Filter* f[], size_t n) { Filter::set_next(f, n); } - - void attach(Filter* f) { Filter::attach(f); } - }; - -/** -* The type of checking to be performed by decoders: -* NONE - no checks, IGNORE_WS - perform checks, but ignore -* whitespaces, FULL_CHECK - perform checks, also complain -* about white spaces. -*/ -enum Decoder_Checking { NONE, IGNORE_WS, FULL_CHECK }; - -} - - -namespace Botan { - -/** -* This class represents pipe objects. -* A set of filters can be placed into a pipe, and information flows -* through the pipe until it reaches the end, where the output is -* collected for retrieval. If you're familiar with the Unix shell -* environment, this design will sound quite familiar. -*/ -class BOTAN_DLL Pipe : public DataSource - { - public: - /** - * An opaque type that identifies a message in this Pipe - */ - typedef size_t message_id; - - /** - * Exception if you use an invalid message as an argument to - * read, remaining, etc - */ - struct BOTAN_DLL Invalid_Message_Number : public Invalid_Argument - { - /** - * @param where the error occured - * @param msg the invalid message id that was used - */ - Invalid_Message_Number(const std::string& where, message_id msg) : - Invalid_Argument("Pipe::" + where + ": Invalid message number " + - to_string(msg)) - {} - }; - - /** - * A meta-id for whatever the last message is - */ - static const message_id LAST_MESSAGE; - - /** - * A meta-id for the default message (set with set_default_msg) - */ - static const message_id DEFAULT_MESSAGE; - - /** - * Write input to the pipe, i.e. to its first filter. - * @param in the byte array to write - * @param length the length of the byte array in - */ - void write(const byte in[], size_t length); - - /** - * Write input to the pipe, i.e. to its first filter. - * @param in the MemoryRegion containing the data to write - */ - void write(const MemoryRegion& in); - - /** - * Write input to the pipe, i.e. to its first filter. - * @param in the string containing the data to write - */ - void write(const std::string& in); - - /** - * Write input to the pipe, i.e. to its first filter. - * @param in the DataSource to read the data from - */ - void write(DataSource& in); - - /** - * Write input to the pipe, i.e. to its first filter. - * @param in a single byte to be written - */ - void write(byte in); - - /** - * Perform start_msg(), write() and end_msg() sequentially. - * @param in the byte array containing the data to write - * @param length the length of the byte array to write - */ - void process_msg(const byte in[], size_t length); - - /** - * Perform start_msg(), write() and end_msg() sequentially. - * @param in the MemoryRegion containing the data to write - */ - void process_msg(const MemoryRegion& in); - - /** - * Perform start_msg(), write() and end_msg() sequentially. - * @param in the string containing the data to write - */ - void process_msg(const std::string& in); - - /** - * Perform start_msg(), write() and end_msg() sequentially. - * @param in the DataSource providing the data to write - */ - void process_msg(DataSource& in); - - /** - * Find out how many bytes are ready to read. - * @param msg the number identifying the message - * for which the information is desired - * @return number of bytes that can still be read - */ - size_t remaining(message_id msg = DEFAULT_MESSAGE) const; - - /** - * Read the default message from the pipe. Moves the internal - * offset so that every call to read will return a new portion of - * the message. - * - * @param output the byte array to write the read bytes to - * @param length the length of the byte array output - * @return number of bytes actually read into output - */ - size_t read(byte output[], size_t length); - - /** - * Read a specified message from the pipe. Moves the internal - * offset so that every call to read will return a new portion of - * the message. - * @param output the byte array to write the read bytes to - * @param length the length of the byte array output - * @param msg the number identifying the message to read from - * @return number of bytes actually read into output - */ - size_t read(byte output[], size_t length, message_id msg); - - /** - * Read a single byte from the pipe. Moves the internal offset so - * that every call to read will return a new portion of the - * message. - * - * @param output the byte to write the result to - * @param msg the message to read from - * @return number of bytes actually read into output - */ - size_t read(byte& output, message_id msg = DEFAULT_MESSAGE); - - /** - * Read the full contents of the pipe. - * @param msg the number identifying the message to read from - * @return SecureVector holding the contents of the pipe - */ - SecureVector read_all(message_id msg = DEFAULT_MESSAGE); - - /** - * Read the full contents of the pipe. - * @param msg the number identifying the message to read from - * @return string holding the contents of the pipe - */ - std::string read_all_as_string(message_id = DEFAULT_MESSAGE); - - /** Read from the default message but do not modify the internal - * offset. Consecutive calls to peek() will return portions of - * the message starting at the same position. - * @param output the byte array to write the peeked message part to - * @param length the length of the byte array output - * @param offset the offset from the current position in message - * @return number of bytes actually peeked and written into output - */ - size_t peek(byte output[], size_t length, size_t offset) const; - - /** Read from the specified message but do not modify the - * internal offset. Consecutive calls to peek() will return - * portions of the message starting at the same position. - * @param output the byte array to write the peeked message part to - * @param length the length of the byte array output - * @param offset the offset from the current position in message - * @param msg the number identifying the message to peek from - * @return number of bytes actually peeked and written into output - */ - size_t peek(byte output[], size_t length, - size_t offset, message_id msg) const; - - /** Read a single byte from the specified message but do not - * modify the internal offset. Consecutive calls to peek() will - * return portions of the message starting at the same position. - * @param output the byte to write the peeked message byte to - * @param offset the offset from the current position in message - * @param msg the number identifying the message to peek from - * @return number of bytes actually peeked and written into output - */ - size_t peek(byte& output, size_t offset, - message_id msg = DEFAULT_MESSAGE) const; - - /** - * @return currently set default message - */ - size_t default_msg() const { return default_read; } - - /** - * Set the default message - * @param msg the number identifying the message which is going to - * be the new default message - */ - void set_default_msg(message_id msg); - - /** - * Get the number of messages the are in this pipe. - * @return number of messages the are in this pipe - */ - message_id message_count() const; - - /** - * Test whether this pipe has any data that can be read from. - * @return true if there is more data to read, false otherwise - */ - bool end_of_data() const; - - /** - * Start a new message in the pipe. A potential other message in this pipe - * must be closed with end_msg() before this function may be called. - */ - void start_msg(); - - /** - * End the current message. - */ - void end_msg(); - - /** - * Insert a new filter at the front of the pipe - * @param filt the new filter to insert - */ - void prepend(Filter* filt); - - /** - * Insert a new filter at the back of the pipe - * @param filt the new filter to insert - */ - void append(Filter* filt); - - /** - * Remove the first filter at the front of the pipe. - */ - void pop(); - - /** - * Reset this pipe to an empty pipe. - */ - void reset(); - - /** - * Construct a Pipe of up to four filters. The filters are set up - * in the same order as the arguments. - */ - Pipe(Filter* = 0, Filter* = 0, Filter* = 0, Filter* = 0); - - /** - * Construct a Pipe from range of filters passed as an array - * @param filters the set of filters to use - * @param count the number of elements in filters - */ - Pipe(Filter* filters[], size_t count); - ~Pipe(); - private: - Pipe(const Pipe&) : DataSource() {} - Pipe& operator=(const Pipe&) { return (*this); } - void init(); - void destruct(Filter*); - void find_endpoints(Filter*); - void clear_endpoints(Filter*); - - message_id get_message_no(const std::string&, message_id) const; - - Filter* pipe; - class Output_Buffers* outputs; - message_id default_read; - bool inside_msg; - }; - -/** -* Stream output operator; dumps the results from pipe's default -* message to the output stream. -* @param out an output stream -* @param pipe the pipe -*/ -BOTAN_DLL std::ostream& operator<<(std::ostream& out, Pipe& pipe); - -/** -* Stream input operator; dumps the remaining bytes of input -* to the (assumed open) pipe message. -* @param in the input stream -* @param pipe the pipe -*/ -BOTAN_DLL std::istream& operator>>(std::istream& in, Pipe& pipe); - -} - -#if defined(BOTAN_HAS_PIPE_UNIXFD_IO) - -namespace Botan { - -/** -* Stream output operator; dumps the results from pipe's default -* message to the output stream. -* @param out file descriptor for an open output stream -* @param pipe the pipe -*/ -int BOTAN_DLL operator<<(int out, Pipe& pipe); - -/** -* File descriptor input operator; dumps the remaining bytes of input -* to the (assumed open) pipe message. -* @param in file descriptor for an open input stream -* @param pipe the pipe -*/ -int BOTAN_DLL operator>>(int in, Pipe& pipe); - -} - -#endif - - -namespace Botan { - -/** -* BER Decoding Object -*/ -class BOTAN_DLL BER_Decoder - { - public: - BER_Object get_next_object(); - void push_back(const BER_Object&); - - bool more_items() const; - BER_Decoder& verify_end(); - BER_Decoder& discard_remaining(); - - BER_Decoder start_cons(ASN1_Tag, ASN1_Tag = UNIVERSAL); - BER_Decoder& end_cons(); - - BER_Decoder& raw_bytes(MemoryRegion&); - - BER_Decoder& decode_null(); - BER_Decoder& decode(bool&); - BER_Decoder& decode(size_t&); - BER_Decoder& decode(class BigInt&); - BER_Decoder& decode(MemoryRegion&, ASN1_Tag); - - BER_Decoder& decode(bool&, ASN1_Tag, ASN1_Tag = CONTEXT_SPECIFIC); - BER_Decoder& decode(size_t&, ASN1_Tag, ASN1_Tag = CONTEXT_SPECIFIC); - BER_Decoder& decode(class BigInt&, - ASN1_Tag, ASN1_Tag = CONTEXT_SPECIFIC); - BER_Decoder& decode(MemoryRegion&, ASN1_Tag, - ASN1_Tag, ASN1_Tag = CONTEXT_SPECIFIC); - - BER_Decoder& decode(class ASN1_Object&); - - BER_Decoder& decode_octet_string_bigint(class BigInt&); - - template - BER_Decoder& decode_optional(T& out, - ASN1_Tag type_tag, - ASN1_Tag class_tag, - const T& default_value = T()); - - template - BER_Decoder& decode_list(std::vector& out, - bool clear_out = true); - - template - BER_Decoder& decode_and_check(const T& expected, - const std::string& error_msg) - { - T actual; - decode(actual); - - if(actual != expected) - throw Decoding_Error(error_msg); - - return (*this); - } - - BER_Decoder& decode_optional_string(MemoryRegion&, - ASN1_Tag, u16bit); - - BER_Decoder(DataSource&); - BER_Decoder(const byte[], size_t); - BER_Decoder(const MemoryRegion&); - BER_Decoder(const BER_Decoder&); - ~BER_Decoder(); - private: - BER_Decoder& operator=(const BER_Decoder&) { return (*this); } - - BER_Decoder* parent; - DataSource* source; - BER_Object pushed; - mutable bool owns; - }; - -/* -* Decode an OPTIONAL or DEFAULT element -*/ -template -BER_Decoder& BER_Decoder::decode_optional(T& out, - ASN1_Tag type_tag, - ASN1_Tag class_tag, - const T& default_value) - { - BER_Object obj = get_next_object(); - - if(obj.type_tag == type_tag && obj.class_tag == class_tag) - { - if(class_tag & CONSTRUCTED) - BER_Decoder(obj.value).decode(out).verify_end(); - else - { - push_back(obj); - decode(out, type_tag, class_tag); - } - } - else - { - out = default_value; - push_back(obj); - } - - return (*this); - } - -/* -* Decode a list of homogenously typed values -*/ -template -BER_Decoder& BER_Decoder::decode_list(std::vector& vec, bool clear_it) - { - if(clear_it) - vec.clear(); - - while(more_items()) - { - T value; - decode(value); - vec.push_back(value); - } - return (*this); - } - -} - - -namespace Botan { - -/** -* X.509v3 Key Constraints. -*/ -enum Key_Constraints { - NO_CONSTRAINTS = 0, - DIGITAL_SIGNATURE = 32768, - NON_REPUDIATION = 16384, - KEY_ENCIPHERMENT = 8192, - DATA_ENCIPHERMENT = 4096, - KEY_AGREEMENT = 2048, - KEY_CERT_SIGN = 1024, - CRL_SIGN = 512, - ENCIPHER_ONLY = 256, - DECIPHER_ONLY = 128 -}; - -/** -* BER Decoding Function for key constraints -*/ -namespace BER { - -void BOTAN_DLL decode(BER_Decoder&, Key_Constraints&); - -} - -/** -* X.509v2 CRL Reason Code. -*/ -enum CRL_Code { - UNSPECIFIED = 0, - KEY_COMPROMISE = 1, - CA_COMPROMISE = 2, - AFFILIATION_CHANGED = 3, - SUPERSEDED = 4, - CESSATION_OF_OPERATION = 5, - CERTIFICATE_HOLD = 6, - REMOVE_FROM_CRL = 8, - PRIVLEDGE_WITHDRAWN = 9, - AA_COMPROMISE = 10, - - DELETE_CRL_ENTRY = 0xFF00, - OCSP_GOOD = 0xFF01, - OCSP_UNKNOWN = 0xFF02 -}; - -/* -* Various Other Enumerations -*/ - -/** -* The two types of X509 encoding supported by Botan. -*/ -enum X509_Encoding { RAW_BER, PEM }; - -} - - -namespace Botan { - -/** -* This class represents abstract X.509 signed objects as -* in the X.500 SIGNED macro -*/ -class BOTAN_DLL X509_Object - { - public: - /** - * The underlying data that is to be or was signed - * @return data that is or was signed - */ - MemoryVector tbs_data() const; - - /** - * @return signature on tbs_data() - */ - MemoryVector signature() const; - - /** - * @return signature algorithm that was used to generate signature - */ - AlgorithmIdentifier signature_algorithm() const; - - /** - * @return hash algorithm that was used to generate signature - */ - std::string hash_used_for_signature() const; - - /** - * Create a signed X509 object. - * @param signer the signer used to sign the object - * @param rng the random number generator to use - * @param alg_id the algorithm identifier of the signature scheme - * @param tbs the tbs bits to be signed - * @return signed X509 object - */ - static MemoryVector make_signed(class PK_Signer* signer, - RandomNumberGenerator& rng, - const AlgorithmIdentifier& alg_id, - const MemoryRegion& tbs); - - /** - * Check the signature on this data - * @param key the public key purportedly used to sign this data - * @return true if the signature is valid, otherwise false - */ - bool check_signature(class Public_Key& key) const; - - /** - * Check the signature on this data - * @param key the public key purportedly used to sign this data - * the pointer will be deleted after use - * @return true if the signature is valid, otherwise false - */ - bool check_signature(class Public_Key* key) const; - - /** - * @return BER encoding of this - */ - MemoryVector BER_encode() const; - - /** - * @return PEM encoding of this - */ - std::string PEM_encode() const; - - /** - * Encode this to a pipe - * @deprecated use BER_encode or PEM_encode instead - * @param out the pipe to write to - * @param encoding the encoding to use - */ - BOTAN_DEPRECATED("Use BER_encode or PEM_encode") - void encode(Pipe& out, X509_Encoding encoding = PEM) const; - - virtual ~X509_Object() {} - protected: - X509_Object(DataSource& src, const std::string& pem_labels); - X509_Object(const std::string& file, const std::string& pem_labels); - - void do_decode(); - X509_Object() {} - AlgorithmIdentifier sig_algo; - MemoryVector tbs_bits, sig; - private: - virtual void force_decode() = 0; - void init(DataSource&, const std::string&); - void decode_info(DataSource&); - std::vector PEM_labels_allowed; - std::string PEM_label_pref; - }; - -} - - -namespace Botan { - -/** -* Distinguished Name -*/ -class BOTAN_DLL X509_DN : public ASN1_Object - { - public: - void encode_into(class DER_Encoder&) const; - void decode_from(class BER_Decoder&); - - std::multimap get_attributes() const; - std::vector get_attribute(const std::string&) const; - - std::multimap contents() const; - - void add_attribute(const std::string&, const std::string&); - void add_attribute(const OID&, const std::string&); - - static std::string deref_info_field(const std::string&); - - MemoryVector get_bits() const; - - X509_DN(); - X509_DN(const std::multimap&); - X509_DN(const std::multimap&); - private: - std::multimap dn_info; - MemoryVector dn_bits; - }; - -bool BOTAN_DLL operator==(const X509_DN&, const X509_DN&); -bool BOTAN_DLL operator!=(const X509_DN&, const X509_DN&); -bool BOTAN_DLL operator<(const X509_DN&, const X509_DN&); - -} - - -namespace Botan { - -/** -* This namespace contains functions for handling X.509 public keys -*/ -namespace X509 { - -/** -* BER encode a key -* @param key the public key to encode -* @return BER encoding of this key -*/ -BOTAN_DLL MemoryVector BER_encode(const Public_Key& key); - -/** -* PEM encode a public key into a string. -* @param key the key to encode -* @return PEM encoded key -*/ -BOTAN_DLL std::string PEM_encode(const Public_Key& key); - -/** -* Create a public key from a data source. -* @param source the source providing the DER or PEM encoded key -* @return new public key object -*/ -BOTAN_DLL Public_Key* load_key(DataSource& source); - -/** -* Create a public key from a file -* @param filename pathname to the file to load -* @return new public key object -*/ -BOTAN_DLL Public_Key* load_key(const std::string& filename); - -/** -* Create a public key from a memory region. -* @param enc the memory region containing the DER or PEM encoded key -* @return new public key object -*/ -BOTAN_DLL Public_Key* load_key(const MemoryRegion& enc); - -/** -* Copy a key. -* @param key the public key to copy -* @return new public key object -*/ -BOTAN_DLL Public_Key* copy_key(const Public_Key& key); - -/** -* Create the key constraints for a specific public key. -* @param pub_key the public key from which the basic set of -* constraints to be placed in the return value is derived -* @param limits additional limits that will be incorporated into the -* return value -* @return combination of key type specific constraints and -* additional limits -*/ -BOTAN_DLL Key_Constraints find_constraints(const Public_Key& pub_key, - Key_Constraints limits); - -/** -* Encode a key into a pipe. -* @deprecated Use PEM_encode or BER_encode instead -* -* @param key the public key to encode -* @param pipe the pipe to feed the encoded key into -* @param encoding the encoding type to use -*/ -BOTAN_DEPRECATED("Use PEM_encode or BER_encode") -inline void encode(const Public_Key& key, - Pipe& pipe, - X509_Encoding encoding = PEM) - { - if(encoding == PEM) - pipe.write(X509::PEM_encode(key)); - else - pipe.write(X509::BER_encode(key)); - } - -} - -} - - -namespace Botan { - -/** -* Data Store -*/ -class BOTAN_DLL Data_Store - { - public: - /** - * A search function - */ - class BOTAN_DLL Matcher - { - public: - virtual bool operator()(const std::string&, - const std::string&) const = 0; - - virtual std::pair - transform(const std::string&, const std::string&) const; - - virtual ~Matcher() {} - }; - - bool operator==(const Data_Store&) const; - - std::multimap - search_with(const Matcher&) const; - - std::vector get(const std::string&) const; - - std::string get1(const std::string&) const; - - MemoryVector get1_memvec(const std::string&) const; - u32bit get1_u32bit(const std::string&, u32bit = 0) const; - - bool has_value(const std::string&) const; - - void add(const std::multimap&); - void add(const std::string&, const std::string&); - void add(const std::string&, u32bit); - void add(const std::string&, const MemoryRegion&); - private: - std::multimap contents; - }; - -} - - -namespace Botan { - -/** -* This class represents X.509 Certificate -*/ -class BOTAN_DLL X509_Certificate : public X509_Object - { - public: - /** - * Get the public key associated with this certificate. - * @return subject public key of this certificate - */ - Public_Key* subject_public_key() const; - - /** - * Get the issuer certificate DN. - * @return issuer DN of this certificate - */ - X509_DN issuer_dn() const; - - /** - * Get the subject certificate DN. - * @return subject DN of this certificate - */ - X509_DN subject_dn() const; - - /** - * Get a value for a specific subject_info parameter name. - * @param name the name of the paramter to look up. Possible names are - * "X509.Certificate.version", "X509.Certificate.serial", - * "X509.Certificate.start", "X509.Certificate.end", - * "X509.Certificate.v2.key_id", "X509.Certificate.public_key", - * "X509v3.BasicConstraints.path_constraint", - * "X509v3.BasicConstraints.is_ca", "X509v3.ExtendedKeyUsage", - * "X509v3.CertificatePolicies", "X509v3.SubjectKeyIdentifier" or - * "X509.Certificate.serial". - * @return value(s) of the specified parameter - */ - std::vector subject_info(const std::string& name) const; - - /** - * Get a value for a specific subject_info parameter name. - * @param name the name of the paramter to look up. Possible names are - * "X509.Certificate.v2.key_id" or "X509v3.AuthorityKeyIdentifier". - * @return value(s) of the specified parameter - */ - std::vector issuer_info(const std::string& name) const; - - /** - * Get the notBefore of the certificate. - * @return notBefore of the certificate - */ - std::string start_time() const; - - /** - * Get the notAfter of the certificate. - * @return notAfter of the certificate - */ - std::string end_time() const; - - /** - * Get the X509 version of this certificate object. - * @return X509 version - */ - u32bit x509_version() const; - - /** - * Get the serial number of this certificate. - * @return certificates serial number - */ - MemoryVector serial_number() const; - - /** - * Get the DER encoded AuthorityKeyIdentifier of this certificate. - * @return DER encoded AuthorityKeyIdentifier - */ - MemoryVector authority_key_id() const; - - /** - * Get the DER encoded SubjectKeyIdentifier of this certificate. - * @return DER encoded SubjectKeyIdentifier - */ - MemoryVector subject_key_id() const; - - /** - * Check whether this certificate is self signed. - * @return true if this certificate is self signed - */ - bool is_self_signed() const { return self_signed; } - - /** - * Check whether this certificate is a CA certificate. - * @return true if this certificate is a CA certificate - */ - bool is_CA_cert() const; - - /** - * Get the path limit as defined in the BasicConstraints extension of - * this certificate. - * @return path limit - */ - u32bit path_limit() const; - - /** - * Get the key constraints as defined in the KeyUsage extension of this - * certificate. - * @return key constraints - */ - Key_Constraints constraints() const; - - /** - * Get the key constraints as defined in the ExtendedKeyUsage - * extension of this - * certificate. - * @return key constraints - */ - std::vector ex_constraints() const; - - /** - * Get the policies as defined in the CertificatePolicies extension - * of this certificate. - * @return certificate policies - */ - std::vector policies() const; - - /** - * @return a string describing the certificate - */ - std::string to_string() const; - - /** - * Check to certificates for equality. - * @return true both certificates are (binary) equal - */ - bool operator==(const X509_Certificate& other) const; - - /** - * Create a certificate from a data source providing the DER or - * PEM encoded certificate. - * @param source the data source - */ - X509_Certificate(DataSource& source); - - /** - * Create a certificate from a file containing the DER or PEM - * encoded certificate. - * @param filename the name of the certificate file - */ - X509_Certificate(const std::string& filename); - private: - void force_decode(); - friend class X509_CA; - X509_Certificate() {} - - Data_Store subject, issuer; - bool self_signed; - }; - -/** -* Check two certificates for inequality -* @return true if the arguments represent different certificates, -* false if they are binary identical -*/ -BOTAN_DLL bool operator!=(const X509_Certificate&, const X509_Certificate&); - -/* -* Data Store Extraction Operations -*/ -BOTAN_DLL X509_DN create_dn(const Data_Store&); -BOTAN_DLL AlternativeName create_alt_name(const Data_Store&); - -} - - -namespace Botan { - -/** -* This class represents CRL entries -*/ -class BOTAN_DLL CRL_Entry : public ASN1_Object - { - public: - void encode_into(class DER_Encoder&) const; - void decode_from(class BER_Decoder&); - - /** - * Get the serial number of the certificate associated with this entry. - * @return certificate's serial number - */ - MemoryVector serial_number() const { return serial; } - - /** - * Get the revocation date of the certificate associated with this entry - * @return certificate's revocation date - */ - X509_Time expire_time() const { return time; } - - /** - * Get the entries reason code - * @return reason code - */ - CRL_Code reason_code() const { return reason; } - - /** - * Construct an empty CRL entry. - */ - CRL_Entry(bool throw_on_unknown_critical_extension = false); - - /** - * Construct an CRL entry. - * @param cert the certificate to revoke - * @param reason the reason code to set in the entry - */ - CRL_Entry(const X509_Certificate& cert, - CRL_Code reason = UNSPECIFIED); - - private: - bool throw_on_unknown_critical; - MemoryVector serial; - X509_Time time; - CRL_Code reason; - }; - -/** -* Test two CRL entries for equality in all fields. -*/ -BOTAN_DLL bool operator==(const CRL_Entry&, const CRL_Entry&); - -/** -* Test two CRL entries for inequality in at least one field. -*/ -BOTAN_DLL bool operator!=(const CRL_Entry&, const CRL_Entry&); - -} - - -namespace Botan { - -/** -* This class represents X.509 Certificate Revocation Lists (CRLs). -*/ -class BOTAN_DLL X509_CRL : public X509_Object - { - public: - /** - * This class represents CRL related errors. - */ - struct BOTAN_DLL X509_CRL_Error : public Exception - { - X509_CRL_Error(const std::string& error) : - Exception("X509_CRL: " + error) {} - }; - - /** - * Get the entries of this CRL in the form of a vector. - * @return vector containing the entries of this CRL. - */ - std::vector get_revoked() const; - - /** - * Get the issuer DN of this CRL. - * @return CRLs issuer DN - */ - X509_DN issuer_dn() const; - - /** - * Get the AuthorityKeyIdentifier of this CRL. - * @return this CRLs AuthorityKeyIdentifier - */ - MemoryVector authority_key_id() const; - - /** - * Get the serial number of this CRL. - * @return CRLs serial number - */ - u32bit crl_number() const; - - /** - * Get the CRL's thisUpdate value. - * @return CRLs thisUpdate - */ - X509_Time this_update() const; - - /** - * Get the CRL's nextUpdate value. - * @return CRLs nextdUpdate - */ - X509_Time next_update() const; - - /** - * Construct a CRL from a data source. - * @param source the data source providing the DER or PEM encoded CRL. - * @param throw_on_unknown_critical should we throw an exception - * if an unknown CRL extension marked as critical is encountered. - */ - X509_CRL(DataSource& source, bool throw_on_unknown_critical = false); - - /** - * Construct a CRL from a file containing the DER or PEM encoded CRL. - * @param filename the name of the CRL file - * @param throw_on_unknown_critical should we throw an exception - * if an unknown CRL extension marked as critical is encountered. - */ - X509_CRL(const std::string& filename, - bool throw_on_unknown_critical = false); - private: - void force_decode(); - - bool throw_on_unknown_critical; - std::vector revoked; - Data_Store info; - }; - -} - - -namespace Botan { - -/** -* Luby-Rackoff block cipher construction -*/ -class BOTAN_DLL LubyRackoff : public BlockCipher - { - public: - void encrypt_n(const byte in[], byte out[], size_t blocks) const; - void decrypt_n(const byte in[], byte out[], size_t blocks) const; - - size_t block_size() const { return 2 * hash->output_length(); } - - Key_Length_Specification key_spec() const - { - return Key_Length_Specification(2, 32, 2); - } - - void clear(); - std::string name() const; - BlockCipher* clone() const; - - /** - * @param hash function to use to form the block cipher - */ - LubyRackoff(HashFunction* hash); - ~LubyRackoff() { delete hash; } - private: - void key_schedule(const byte[], size_t); - - HashFunction* hash; - SecureVector K1, K2; - }; - -} - - -namespace Botan { - -/** -* EMSA2 from IEEE 1363 -* Useful for Rabin-Williams -*/ -class BOTAN_DLL EMSA2 : public EMSA - { - public: - /** - * @param hash the hash object to use - */ - EMSA2(HashFunction* hash); - ~EMSA2() { delete hash; } - private: - void update(const byte[], size_t); - SecureVector raw_data(); - - SecureVector encoding_of(const MemoryRegion&, size_t, - RandomNumberGenerator& rng); - - bool verify(const MemoryRegion&, const MemoryRegion&, - size_t); - - SecureVector empty_hash; - HashFunction* hash; - byte hash_id; - }; - -} - - -namespace Botan { - -/** -* Fused multiply-add -* @param a an integer -* @param b an integer -* @param c an integer -* @return (a*b)+c -*/ -BigInt BOTAN_DLL mul_add(const BigInt& a, - const BigInt& b, - const BigInt& c); - -/** -* Fused subtract-multiply -* @param a an integer -* @param b an integer -* @param c an integer -* @return (a-b)*c -*/ -BigInt BOTAN_DLL sub_mul(const BigInt& a, - const BigInt& b, - const BigInt& c); - -/** -* Return the absolute value -* @param n an integer -* @return absolute value of n -*/ -inline BigInt abs(const BigInt& n) { return n.abs(); } - -/** -* Compute the greatest common divisor -* @param x a positive integer -* @param y a positive integer -* @return gcd(x,y) -*/ -BigInt BOTAN_DLL gcd(const BigInt& x, const BigInt& y); - -/** -* Least common multiple -* @param x a positive integer -* @param y a positive integer -* @return z, smallest integer such that z % x == 0 and z % y == 0 -*/ -BigInt BOTAN_DLL lcm(const BigInt& x, const BigInt& y); - -/** -* @param x an integer -* @return (x*x) -*/ -BigInt BOTAN_DLL square(const BigInt& x); - -/** -* Modular inversion -* @param x a positive integer -* @param modulus a positive integer -* @return y st (x*y) % modulus == 1 -*/ -BigInt BOTAN_DLL inverse_mod(const BigInt& x, - const BigInt& modulus); - -/** -* Compute the Jacobi symbol. If n is prime, this is equivalent -* to the Legendre symbol. -* @see http://mathworld.wolfram.com/JacobiSymbol.html -* -* @param a is a non-negative integer -* @param n is an odd integer > 1 -* @return (n / m) -*/ -s32bit BOTAN_DLL jacobi(const BigInt& a, - const BigInt& n); - -/** -* Modular exponentation -* @param b an integer base -* @param x a positive exponent -* @param m a positive modulus -* @return (b^x) % m -*/ -BigInt BOTAN_DLL power_mod(const BigInt& b, - const BigInt& x, - const BigInt& m); - -/** -* Compute the square root of x modulo a prime using the -* Shanks-Tonnelli algorithm -* -* @param x the input -* @param p the prime -* @return y such that (y*y)%p == x, or -1 if no such integer -*/ -BigInt BOTAN_DLL ressol(const BigInt& x, const BigInt& p); - -/** -* @param x an integer -* @return count of the zero bits in x, or, equivalently, the largest -* value of n such that 2^n divides x evently -*/ -size_t BOTAN_DLL low_zero_bits(const BigInt& x); - -/** -* Primality Testing -* @param n a positive integer to test for primality -* @param rng a random number generator -* @param level how hard to test -* @return true if all primality tests passed, otherwise false -*/ -bool BOTAN_DLL primality_test(const BigInt& n, - RandomNumberGenerator& rng, - size_t level = 1); - -/** -* Quickly check for primality -* @param n a positive integer to test for primality -* @param rng a random number generator -* @return true if all primality tests passed, otherwise false -*/ -inline bool quick_check_prime(const BigInt& n, RandomNumberGenerator& rng) - { return primality_test(n, rng, 0); } - -/** -* Check for primality -* @param n a positive integer to test for primality -* @param rng a random number generator -* @return true if all primality tests passed, otherwise false -*/ -inline bool check_prime(const BigInt& n, RandomNumberGenerator& rng) - { return primality_test(n, rng, 1); } - -/** -* Verify primality - this function is slow but useful if you want to -* ensure that a possibly malicious entity did not provide you with -* something that 'looks like' a prime -* @param n a positive integer to test for primality -* @param rng a random number generator -* @return true if all primality tests passed, otherwise false -*/ -inline bool verify_prime(const BigInt& n, RandomNumberGenerator& rng) - { return primality_test(n, rng, 2); } - -/** -* Randomly generate a prime -* @param rng a random number generator -* @param bits how large the resulting prime should be in bits -* @param coprime a positive integer the result should be coprime to -* @param equiv a non-negative number that the result should be - equivalent to modulo equiv_mod -* @param equiv_mod the modulus equiv should be checked against -* @return random prime with the specified criteria -*/ -BigInt BOTAN_DLL random_prime(RandomNumberGenerator& rng, - size_t bits, const BigInt& coprime = 1, - size_t equiv = 1, size_t equiv_mod = 2); - -/** -* Return a 'safe' prime, of the form p=2*q+1 with q prime -* @param rng a random number generator -* @param bits is how long the resulting prime should be -* @return prime randomly chosen from safe primes of length bits -*/ -BigInt BOTAN_DLL random_safe_prime(RandomNumberGenerator& rng, - size_t bits); - -class Algorithm_Factory; - -/** -* Generate DSA parameters using the FIPS 186 kosherizer -* @param rng a random number generator -* @param af an algorithm factory -* @param p_out where the prime p will be stored -* @param q_out where the prime q will be stored -* @param pbits how long p will be in bits -* @param qbits how long q will be in bits -* @return random seed used to generate this parameter set -*/ -SecureVector BOTAN_DLL -generate_dsa_primes(RandomNumberGenerator& rng, - Algorithm_Factory& af, - BigInt& p_out, BigInt& q_out, - size_t pbits, size_t qbits); - -/** -* Generate DSA parameters using the FIPS 186 kosherizer -* @param rng a random number generator -* @param af an algorithm factory -* @param p_out where the prime p will be stored -* @param q_out where the prime q will be stored -* @param pbits how long p will be in bits -* @param qbits how long q will be in bits -* @param seed the seed used to generate the parameters -* @return true if seed generated a valid DSA parameter set, otherwise - false. p_out and q_out are only valid if true was returned. -*/ -bool BOTAN_DLL -generate_dsa_primes(RandomNumberGenerator& rng, - Algorithm_Factory& af, - BigInt& p_out, BigInt& q_out, - size_t pbits, size_t qbits, - const MemoryRegion& seed); - -/** -* The size of the PRIMES[] array -*/ -const size_t PRIME_TABLE_SIZE = 6541; - -/** -* A const array of all primes less than 65535 -*/ -extern const u16bit BOTAN_DLL PRIMES[]; - -} - - -namespace Botan { - -/** -* This class represents an elliptic curve over GF(p) -*/ -class BOTAN_DLL CurveGFp - { - public: - - /** - * Create an uninitialized CurveGFp - */ - CurveGFp() : p_words(0), p_dash(0) {} - - /** - * Construct the elliptic curve E: y^2 = x^3 + ax + b over GF(p) - * @param p prime number of the field - * @param a first coefficient - * @param b second coefficient - */ - CurveGFp(const BigInt& p, const BigInt& a, const BigInt& b) : - p(p), a(a), b(b), p_words(p.sig_words()) - { - BigInt r(BigInt::Power2, p_words * BOTAN_MP_WORD_BITS); - - p_dash = (((r * inverse_mod(r, p)) - 1) / p).word_at(0); - - r2 = (r * r) % p; - a_r = (a * r) % p; - b_r = (b * r) % p; - } - - // CurveGFp(const CurveGFp& other) = default; - // CurveGFp& operator=(const CurveGFp& other) = default; - - /** - * @return curve coefficient a - */ - const BigInt& get_a() const { return a; } - - /** - * @return curve coefficient b - */ - const BigInt& get_b() const { return b; } - - /** - * Get prime modulus of the field of the curve - * @return prime modulus of the field of the curve - */ - const BigInt& get_p() const { return p; } - - /** - * @return Montgomery parameter r^2 % p - */ - const BigInt& get_r2() const { return r2; } - - /** - * @return a * r mod p - */ - const BigInt& get_a_r() const { return a_r; } - - /** - * @return b * r mod p - */ - const BigInt& get_b_r() const { return b_r; } - - /** - * @return Montgomery parameter p-dash - */ - word get_p_dash() const { return p_dash; } - - /** - * @return p.sig_words() - */ - size_t get_p_words() const { return p_words; } - - /** - * swaps the states of *this and other, does not throw - * @param other curve to swap values with - */ - void swap(CurveGFp& other) - { - std::swap(p, other.p); - - std::swap(a, other.a); - std::swap(b, other.b); - - std::swap(a_r, other.a_r); - std::swap(b_r, other.b_r); - - std::swap(p_words, other.p_words); - - std::swap(r2, other.r2); - std::swap(p_dash, other.p_dash); - } - - /** - * Equality operator - * @param other curve to compare with - * @return true iff this is the same curve as other - */ - bool operator==(const CurveGFp& other) const - { - /* - Relies on choice of R, but that is fixed by constructor based - on size of p - */ - return (p == other.p && a_r == other.a_r && b_r == other.b_r); - } - - private: - // Curve parameters - BigInt p, a, b; - - size_t p_words; // cache of p.sig_words() - - // Montgomery parameters - BigInt r2, a_r, b_r; - word p_dash; - }; - -/** -* Equality operator -* @param lhs a curve -* @param rhs a curve -* @return true iff lhs is not the same as rhs -*/ -inline bool operator!=(const CurveGFp& lhs, const CurveGFp& rhs) - { - return !(lhs == rhs); - } - -} - -namespace std { - -template<> inline -void swap(Botan::CurveGFp& curve1, - Botan::CurveGFp& curve2) - { - curve1.swap(curve2); - } - -} // namespace std - - -namespace Botan { - -/** -* Exception thrown if you try to convert a zero point to an affine -* coordinate -*/ -struct BOTAN_DLL Illegal_Transformation : public Exception - { - Illegal_Transformation(const std::string& err = - "Requested transformation is not possible") : - Exception(err) {} - }; - -/** -* Exception thrown if some form of illegal point is decoded -*/ -struct BOTAN_DLL Illegal_Point : public Exception - { - Illegal_Point(const std::string& err = "Malformed ECP point detected") : - Exception(err) {} - }; - -/** -* This class represents one point on a curve of GF(p) -*/ -class BOTAN_DLL PointGFp - { - public: - enum Compression_Type { - UNCOMPRESSED = 0, - COMPRESSED = 1, - HYBRID = 2 - }; - - /** - * Construct an uninitialized PointGFp - */ - PointGFp() {} - - /** - * Construct the zero point - * @param curve The base curve - */ - PointGFp(const CurveGFp& curve); - - /** - * Construct a point from its affine coordinates - * @param curve the base curve - * @param x affine x coordinate - * @param y affine y coordinate - */ - PointGFp(const CurveGFp& curve, const BigInt& x, const BigInt& y); - - //PointGFp(const PointGFp& other) = default; - //PointGFp& operator=(const PointGFp& other) = default; - - /** - * += Operator - * @param rhs the PointGFp to add to the local value - * @result resulting PointGFp - */ - PointGFp& operator+=(const PointGFp& rhs); - - /** - * -= Operator - * @param rhs the PointGFp to subtract from the local value - * @result resulting PointGFp - */ - PointGFp& operator-=(const PointGFp& rhs); - - /** - * *= Operator - * @param scalar the PointGFp to multiply with *this - * @result resulting PointGFp - */ - PointGFp& operator*=(const BigInt& scalar); - - /** - * Multiplication Operator - * @param scalar the scalar value - * @param point the point value - * @return scalar*point on the curve - */ - friend BOTAN_DLL PointGFp operator*(const BigInt& scalar, const PointGFp& point); - - /** - * Multiexponentiation - * @param p1 a point - * @param z1 a scalar - * @param p2 a point - * @param z2 a scalar - * @result (p1 * z1 + p2 * z2) - */ - friend BOTAN_DLL PointGFp multi_exponentiate( - const PointGFp& p1, const BigInt& z1, - const PointGFp& p2, const BigInt& z2); - - /** - * Negate this point - * @return *this - */ - PointGFp& negate() - { - if(!is_zero()) - coord_y = curve.get_p() - coord_y; - return *this; - } - - /** - * Return base curve of this point - * @result the curve over GF(p) of this point - */ - const CurveGFp& get_curve() const { return curve; } - - /** - * get affine x coordinate - * @result affine x coordinate - */ - BigInt get_affine_x() const; - - /** - * get affine y coordinate - * @result affine y coordinate - */ - BigInt get_affine_y() const; - - /** - * Is this the point at infinity? - * @result true, if this point is at infinity, false otherwise. - */ - bool is_zero() const - { return (coord_x.is_zero() && coord_z.is_zero()); } - - /** - * Checks whether the point is to be found on the underlying - * curve; used to prevent fault attacks. - * @return if the point is on the curve - */ - bool on_the_curve() const; - - /** - * swaps the states of *this and other, does not throw! - * @param other the object to swap values with - */ - void swap(PointGFp& other); - - /** - * Equality operator - */ - bool operator==(const PointGFp& other) const; - private: - - /** - * Montgomery multiplication/reduction - * @param x first multiplicand - * @param y second multiplicand - * @param workspace temp space - */ - BigInt monty_mult(const BigInt& x, const BigInt& y) const - { - BigInt result; - monty_mult(result, x, y); - return result; - } - - /** - * Montgomery multiplication/reduction - * @warning z cannot alias x or y - * @param z output - * @param x first multiplicand - * @param y second multiplicand - */ - void monty_mult(BigInt& z, const BigInt& x, const BigInt& y) const; - - /** - * Montgomery squaring/reduction - * @param x multiplicand - */ - BigInt monty_sqr(const BigInt& x) const - { - BigInt result; - monty_sqr(result, x); - return result; - } - - /** - * Montgomery squaring/reduction - * @warning z cannot alias x - * @param z output - * @param x multiplicand - */ - void monty_sqr(BigInt& z, const BigInt& x) const; - - /** - * Point addition - * @param workspace temp space, at least 11 elements - */ - void add(const PointGFp& other, std::vector& workspace); - - /** - * Point doubling - * @param workspace temp space, at least 9 elements - */ - void mult2(std::vector& workspace); - - CurveGFp curve; - BigInt coord_x, coord_y, coord_z; - mutable SecureVector ws; // workspace for Montgomery - }; - -// relational operators -inline bool operator!=(const PointGFp& lhs, const PointGFp& rhs) - { - return !(rhs == lhs); - } - -// arithmetic operators -inline PointGFp operator-(const PointGFp& lhs) - { - return PointGFp(lhs).negate(); - } - -inline PointGFp operator+(const PointGFp& lhs, const PointGFp& rhs) - { - PointGFp tmp(lhs); - return tmp += rhs; - } - -inline PointGFp operator-(const PointGFp& lhs, const PointGFp& rhs) - { - PointGFp tmp(lhs); - return tmp -= rhs; - } - -inline PointGFp operator*(const PointGFp& point, const BigInt& scalar) - { - return scalar * point; - } - -// encoding and decoding -SecureVector BOTAN_DLL EC2OSP(const PointGFp& point, byte format); - -PointGFp BOTAN_DLL OS2ECP(const byte data[], size_t data_len, - const CurveGFp& curve); - -inline PointGFp OS2ECP(const MemoryRegion& data, const CurveGFp& curve) - { return OS2ECP(&data[0], data.size(), curve); } - -} - -namespace std { - -template<> -inline void swap(Botan::PointGFp& x, Botan::PointGFp& y) - { x.swap(y); } - -} - - -namespace Botan { - -/** -* This class represents elliptic curce domain parameters -*/ -enum EC_Group_Encoding { - EC_DOMPAR_ENC_EXPLICIT = 0, - EC_DOMPAR_ENC_IMPLICITCA = 1, - EC_DOMPAR_ENC_OID = 2 -}; - -/** -* Class representing an elliptic curve -*/ -class BOTAN_DLL EC_Group - { - public: - - /** - * Construct Domain paramers from specified parameters - * @param curve elliptic curve - * @param base_point a base point - * @param order the order of the base point - * @param cofactor the cofactor - */ - EC_Group(const CurveGFp& curve, - const PointGFp& base_point, - const BigInt& order, - const BigInt& cofactor) : - curve(curve), - base_point(base_point), - order(order), - cofactor(cofactor), - oid("") - {} - - /** - * Decode a BER encoded ECC domain parameter set - * @param ber_encoding the bytes of the BER encoding - */ - EC_Group(const MemoryRegion& ber_encoding); - - /** - * Create an EC domain by OID (or throw if unknown) - * @param oid the OID of the EC domain to create - */ - EC_Group(const OID& oid); - - /** - * Create an EC domain from PEM encoding (as from PEM_encode), - * or from an OID name (eg "secp160r1", or "1.3.132.0.8") - * @param pem_or_oid PEM-encoded data, or an OID - */ - EC_Group(const std::string& pem_or_oid = ""); - - /** - * Create the DER encoding of this domain - * @param form of encoding to use - * @returns bytes encododed as DER - */ - SecureVector DER_encode(EC_Group_Encoding form) const; - - /** - * Return the PEM encoding (always in explicit form) - * @return string containing PEM data - */ - std::string PEM_encode() const; - - /** - * Return domain parameter curve - * @result domain parameter curve - */ - const CurveGFp& get_curve() const { return curve; } - - /** - * Return domain parameter curve - * @result domain parameter curve - */ - const PointGFp& get_base_point() const { return base_point; } - - /** - * Return the order of the base point - * @result order of the base point - */ - const BigInt& get_order() const { return order; } - - /** - * Return the cofactor - * @result the cofactor - */ - const BigInt& get_cofactor() const { return cofactor; } - - bool initialized() const { return !base_point.is_zero(); } - - /** - * Return the OID of these domain parameters - * @result the OID - */ - std::string get_oid() const { return oid; } - - bool operator==(const EC_Group& other) const - { - return ((get_curve() == other.get_curve()) && - (get_base_point() == other.get_base_point()) && - (get_order() == other.get_order()) && - (get_cofactor() == other.get_cofactor())); - } - - private: - CurveGFp curve; - PointGFp base_point; - BigInt order, cofactor; - std::string oid; - }; - -inline bool operator!=(const EC_Group& lhs, - const EC_Group& rhs) - { - return !(lhs == rhs); - } - -// For compatability with 1.8 -typedef EC_Group EC_Domain_Params; - -} - - -namespace Botan { - -/** -* User Interface -* Only really used for callbacks for PKCS #8 decryption -*/ -class BOTAN_DLL User_Interface - { - public: - enum UI_Result { OK, CANCEL_ACTION }; - - virtual std::string get_passphrase(const std::string&, - const std::string&, - UI_Result&) const; - User_Interface(const std::string& = ""); - virtual ~User_Interface() {} - protected: - std::string preset_passphrase; - mutable bool first_try; - }; - -} - - -namespace Botan { - -/** -* PKCS #8 General Exception -*/ -struct BOTAN_DLL PKCS8_Exception : public Decoding_Error - { - PKCS8_Exception(const std::string& error) : - Decoding_Error("PKCS #8: " + error) {} - }; - -/** -* This namespace contains functions for handling PKCS #8 private keys -*/ -namespace PKCS8 { - -/** -* BER encode a private key -* @param key the private key to encode -* @return BER encoded key -*/ -BOTAN_DLL SecureVector BER_encode(const Private_Key& key); - -/** -* Get a string containing a PEM encoded private key. -* @param key the key to encode -* @return encoded key -*/ -BOTAN_DLL std::string PEM_encode(const Private_Key& key); - -/** -* Encrypt a key using PKCS #8 encryption -* @param key the key to encode -* @param rng the rng to use -* @param pass the password to use for encryption -* @param pbe_algo the name of the desired password-based encryption - algorithm; if empty ("") a reasonable (portable/secure) - default will be chosen. -* @return encrypted key in binary BER form -*/ -BOTAN_DLL SecureVector BER_encode(const Private_Key& key, - RandomNumberGenerator& rng, - const std::string& pass, - const std::string& pbe_algo = ""); - -/** -* Get a string containing a PEM encoded private key, encrypting it with a -* password. -* @param key the key to encode -* @param rng the rng to use -* @param pass the password to use for encryption -* @param pbe_algo the name of the desired password-based encryption - algorithm; if empty ("") a reasonable (portable/secure) - default will be chosen. -* @return encrypted key in PEM form -*/ -BOTAN_DLL std::string PEM_encode(const Private_Key& key, - RandomNumberGenerator& rng, - const std::string& pass, - const std::string& pbe_algo = ""); - - -/** -* Encode a private key into a pipe. -* @deprecated Use PEM_encode or BER_encode instead -* -* @param key the private key to encode -* @param pipe the pipe to feed the encoded key into -* @param encoding the encoding type to use -*/ -BOTAN_DEPRECATED("Use PEM_encode or BER_encode") -inline void encode(const Private_Key& key, - Pipe& pipe, - X509_Encoding encoding = PEM) - { - if(encoding == PEM) - pipe.write(PKCS8::PEM_encode(key)); - else - pipe.write(PKCS8::BER_encode(key)); - } - -/** -* Encode and encrypt a private key into a pipe. -* @deprecated Use PEM_encode or BER_encode instead -* -* @param key the private key to encode -* @param pipe the pipe to feed the encoded key into -* @param pass the password to use for encryption -* @param rng the rng to use -* @param pbe_algo the name of the desired password-based encryption - algorithm; if empty ("") a reasonable (portable/secure) - default will be chosen. -* @param encoding the encoding type to use -*/ -BOTAN_DEPRECATED("Use PEM_encode or BER_encode") -inline void encrypt_key(const Private_Key& key, - Pipe& pipe, - RandomNumberGenerator& rng, - const std::string& pass, - const std::string& pbe_algo = "", - X509_Encoding encoding = PEM) - { - if(encoding == PEM) - pipe.write(PKCS8::PEM_encode(key, rng, pass, pbe_algo)); - else - pipe.write(PKCS8::BER_encode(key, rng, pass, pbe_algo)); - } - -/** -* Load a key from a data source. -* @param source the data source providing the encoded key -* @param rng the rng to use -* @param ui the user interface to be used for passphrase dialog -* @return loaded private key object -*/ -BOTAN_DLL Private_Key* load_key(DataSource& source, - RandomNumberGenerator& rng, - const User_Interface& ui); - -/** Load a key from a data source. -* @param source the data source providing the encoded key -* @param rng the rng to use -* @param pass the passphrase to decrypt the key. Provide an empty -* string if the key is not encoded. -* @return loaded private key object -*/ -BOTAN_DLL Private_Key* load_key(DataSource& source, - RandomNumberGenerator& rng, - const std::string& pass = ""); - -/** -* Load a key from a file. -* @param filename the path to the file containing the encoded key -* @param rng the rng to use -* @param ui the user interface to be used for passphrase dialog -* @return loaded private key object -*/ -BOTAN_DLL Private_Key* load_key(const std::string& filename, - RandomNumberGenerator& rng, - const User_Interface& ui); - -/** Load a key from a file. -* @param filename the path to the file containing the encoded key -* @param rng the rng to use -* @param pass the passphrase to decrypt the key. Provide an empty -* string if the key is not encoded. -* @return loaded private key object -*/ -BOTAN_DLL Private_Key* load_key(const std::string& filename, - RandomNumberGenerator& rng, - const std::string& pass = ""); - -/** -* Copy an existing encoded key object. -* @param key the key to copy -* @param rng the rng to use -* @return new copy of the key -*/ -BOTAN_DLL Private_Key* copy_key(const Private_Key& key, - RandomNumberGenerator& rng); - -} - -} - - -namespace Botan { - -/** -* This class represents abstract ECC public keys. When encoding a key -* via an encoder that can be accessed via the corresponding member -* functions, the key will decide upon its internally stored encoding -* information whether to encode itself with or without domain -* parameters, or using the domain parameter oid. Furthermore, a public -* key without domain parameters can be decoded. In that case, it -* cannot be used for verification until its domain parameters are set -* by calling the corresponding member function. -*/ -class BOTAN_DLL EC_PublicKey : public virtual Public_Key - { - public: - EC_PublicKey(const EC_Group& dom_par, - const PointGFp& pub_point); - - EC_PublicKey(const AlgorithmIdentifier& alg_id, - const MemoryRegion& key_bits); - - /** - * Get the public point of this key. - * @throw Invalid_State is thrown if the - * domain parameters of this point are not set - * @result the public point of this key - */ - const PointGFp& public_point() const { return public_key; } - - AlgorithmIdentifier algorithm_identifier() const; - - MemoryVector x509_subject_public_key() const; - - bool check_key(RandomNumberGenerator& rng, - bool strong) const; - - /** - * Get the domain parameters of this key. - * @throw Invalid_State is thrown if the - * domain parameters of this point are not set - * @result the domain parameters of this key - */ - const EC_Group& domain() const { return domain_params; } - - /** - * Set the domain parameter encoding to be used when encoding this key. - * @param enc the encoding to use - */ - void set_parameter_encoding(EC_Group_Encoding enc); - - /** - * Return the DER encoding of this keys domain in whatever format - * is preset for this particular key - */ - MemoryVector DER_domain() const - { return domain().DER_encode(domain_format()); } - - /** - * Get the domain parameter encoding to be used when encoding this key. - * @result the encoding to use - */ - EC_Group_Encoding domain_format() const - { return domain_encoding; } - protected: - EC_PublicKey() : domain_encoding(EC_DOMPAR_ENC_EXPLICIT) {} - - EC_Group domain_params; - PointGFp public_key; - EC_Group_Encoding domain_encoding; - }; - -/** -* This abstract class represents ECC private keys -*/ -class BOTAN_DLL EC_PrivateKey : public virtual EC_PublicKey, - public virtual Private_Key - { - public: - EC_PrivateKey(RandomNumberGenerator& rng, - const EC_Group& domain, - const BigInt& private_key); - - EC_PrivateKey(const AlgorithmIdentifier& alg_id, - const MemoryRegion& key_bits); - - MemoryVector pkcs8_private_key() const; - - /** - * Get the private key value of this key object. - * @result the private key value of this key object - */ - const BigInt& private_value() const; - protected: - EC_PrivateKey() {} - - BigInt private_key; - }; - -} - - -namespace Botan { - -/** -* GOST-34.10 Public Key -*/ -class BOTAN_DLL GOST_3410_PublicKey : public virtual EC_PublicKey - { - public: - - /** - * Construct a public key from a given public point. - * @param dom_par the domain parameters associated with this key - * @param public_point the public point defining this key - */ - GOST_3410_PublicKey(const EC_Group& dom_par, - const PointGFp& public_point) : - EC_PublicKey(dom_par, public_point) {} - - /** - * Construct from X.509 algorithm id and subject public key bits - */ - GOST_3410_PublicKey(const AlgorithmIdentifier& alg_id, - const MemoryRegion& key_bits); - - /** - * Get this keys algorithm name. - * @result this keys algorithm name - */ - std::string algo_name() const { return "GOST-34.10"; } - - AlgorithmIdentifier algorithm_identifier() const; - - MemoryVector x509_subject_public_key() const; - - /** - * Get the maximum number of bits allowed to be fed to this key. - * This is the bitlength of the order of the base point. - - * @result the maximum number of input bits - */ - size_t max_input_bits() const { return domain().get_order().bits(); } - - size_t message_parts() const { return 2; } - - size_t message_part_size() const - { return domain().get_order().bytes(); } - - protected: - GOST_3410_PublicKey() {} - }; - -/** -* GOST-34.10 Private Key -*/ -class BOTAN_DLL GOST_3410_PrivateKey : public GOST_3410_PublicKey, - public EC_PrivateKey - { - public: - - GOST_3410_PrivateKey(const AlgorithmIdentifier& alg_id, - const MemoryRegion& key_bits) : - EC_PrivateKey(alg_id, key_bits) {} - - /** - * Generate a new private key - * @param rng a random number generator - * @param domain parameters to used for this key - * @param x the private key; if zero, a new random key is generated - */ - GOST_3410_PrivateKey(RandomNumberGenerator& rng, - const EC_Group& domain, - const BigInt& x = 0) : - EC_PrivateKey(rng, domain, x) {} - - AlgorithmIdentifier pkcs8_algorithm_identifier() const - { return EC_PublicKey::algorithm_identifier(); } - }; - -/** -* GOST-34.10 signature operation -*/ -class BOTAN_DLL GOST_3410_Signature_Operation : public PK_Ops::Signature - { - public: - GOST_3410_Signature_Operation(const GOST_3410_PrivateKey& gost_3410); - - size_t message_parts() const { return 2; } - size_t message_part_size() const { return order.bytes(); } - size_t max_input_bits() const { return order.bits(); } - - SecureVector sign(const byte msg[], size_t msg_len, - RandomNumberGenerator& rng); - - private: - const PointGFp& base_point; - const BigInt& order; - const BigInt& x; - }; - -/** -* GOST-34.10 verification operation -*/ -class BOTAN_DLL GOST_3410_Verification_Operation : public PK_Ops::Verification - { - public: - GOST_3410_Verification_Operation(const GOST_3410_PublicKey& gost); - - size_t message_parts() const { return 2; } - size_t message_part_size() const { return order.bytes(); } - size_t max_input_bits() const { return order.bits(); } - - bool with_recovery() const { return false; } - - bool verify(const byte msg[], size_t msg_len, - const byte sig[], size_t sig_len); - private: - const PointGFp& base_point; - const PointGFp& public_point; - const BigInt& order; - }; - -} - - -namespace Botan { - -/** -* MDx Hash Function Base Class -*/ -class BOTAN_DLL MDx_HashFunction : public HashFunction - { - public: - /** - * @param block_length is the number of bytes per block - * @param big_byte_endian specifies if the hash uses big-endian bytes - * @param big_bit_endian specifies if the hash uses big-endian bits - * @param counter_size specifies the size of the counter var in bytes - */ - MDx_HashFunction(size_t block_length, - bool big_byte_endian, - bool big_bit_endian, - size_t counter_size = 8); - - size_t hash_block_size() const { return buffer.size(); } - protected: - void add_data(const byte input[], size_t length); - void final_result(byte output[]); - - /** - * Run the hash's compression function over a set of blocks - * @param blocks the input - * @param block_n the number of blocks - */ - virtual void compress_n(const byte blocks[], size_t block_n) = 0; - - void clear(); - - /** - * Copy the output to the buffer - * @param buffer to put the output into - */ - virtual void copy_out(byte buffer[]) = 0; - - /** - * Write the count, if used, to this spot - * @param out where to write the counter to - */ - virtual void write_count(byte out[]); - private: - SecureVector buffer; - u64bit count; - size_t position; - - const bool BIG_BYTE_ENDIAN, BIG_BIT_ENDIAN; - const size_t COUNT_SIZE; - }; - -} - - -namespace Botan { - -/** -* HAS-160, a Korean hash function standardized in -* TTAS.KO-12.0011/R1. Used in conjuction with KCDSA -*/ -class BOTAN_DLL HAS_160 : public MDx_HashFunction - { - public: - std::string name() const { return "HAS-160"; } - size_t output_length() const { return 20; } - HashFunction* clone() const { return new HAS_160; } - - void clear(); - - HAS_160() : MDx_HashFunction(64, false, true), X(20), digest(5) - { clear(); } - private: - void compress_n(const byte[], size_t blocks); - void copy_out(byte[]); - - SecureVector X, digest; - }; - -} - - -namespace Botan { - -/** -* This class represents the Library Initialization/Shutdown Object. It -* has to exceed the lifetime of any Botan object used in an -* application. You can call initialize/deinitialize or use -* LibraryInitializer in the RAII style. -*/ -class BOTAN_DLL LibraryInitializer - { - public: - /** - * Initialize the library - * @param options a string listing initialization options - */ - static void initialize(const std::string& options = ""); - - /** - * Shutdown the library - */ - static void deinitialize(); - - /** - * Initialize the library - * @param options a string listing initialization options - */ - LibraryInitializer(const std::string& options = "") - { LibraryInitializer::initialize(options); } - - ~LibraryInitializer() { LibraryInitializer::deinitialize(); } - }; - -} - - -namespace Botan { - -/* -* Forward declare to avoid recursive dependency between this header -* and libstate.h -*/ -class Library_State; - -/** -* Namespace for management of the global state -*/ -namespace Global_State_Management { - -/** -* Access the global library state -* @return reference to the global library state -*/ -BOTAN_DLL Library_State& global_state(); - -/** -* Set the global state object -* @param state the new global state to use -*/ -BOTAN_DLL void set_global_state(Library_State* state); - -/** -* Set the global state object unless it is already set -* @param state the new global state to use -* @return true if the state parameter is now being used as the global -* state, or false if one was already set, in which case the -* parameter was deleted immediately -*/ -BOTAN_DLL bool set_global_state_unless_set(Library_State* state); - -/** -* Swap the current state for another -* @param new_state the new state object to use -* @return previous state (or NULL if none) -*/ -BOTAN_DLL Library_State* swap_global_state(Library_State* new_state); - -/** -* Query if the library is currently initialized -* @return true iff the library is initialized -*/ -BOTAN_DLL bool global_state_exists(); - -} - -/* -* Insert into Botan ns for convenience/backwards compatability -*/ -using Global_State_Management::global_state; - -} - - -namespace Botan { - -/** -* Forward declarations (don't need full definitions here) -*/ -class BlockCipher; -class StreamCipher; -class HashFunction; -class MessageAuthenticationCode; -class PBKDF; - -template class Algorithm_Cache; - -class Engine; -class Mutex_Factory; - -/** -* Algorithm Factory -*/ -class BOTAN_DLL Algorithm_Factory - { - public: - /** - * Constructor - * @param mf a mutex factory - */ - Algorithm_Factory(Mutex_Factory& mf); - - /** - * Destructor - */ - ~Algorithm_Factory(); - - /** - * @param engine to add (Algorithm_Factory takes ownership) - */ - void add_engine(Engine* engine); - - /** - * Clear out any cached objects - */ - void clear_caches(); - - /** - * @param algo_spec the algorithm we are querying - * @returns list of providers of this algorithm - */ - std::vector providers_of(const std::string& algo_spec); - - /** - * @param algo_spec the algorithm we are setting a provider for - * @param provider the provider we would like to use - */ - void set_preferred_provider(const std::string& algo_spec, - const std::string& provider); - - /** - * @param algo_spec the algorithm we want - * @param provider the provider we would like to use - * @returns pointer to const prototype object, ready to clone(), or NULL - */ - const BlockCipher* - prototype_block_cipher(const std::string& algo_spec, - const std::string& provider = ""); - - /** - * @param algo_spec the algorithm we want - * @param provider the provider we would like to use - * @returns pointer to freshly created instance of the request algorithm - */ - BlockCipher* make_block_cipher(const std::string& algo_spec, - const std::string& provider = ""); - - /** - * @param algo the algorithm to add - * @param provider the provider of this algorithm - */ - void add_block_cipher(BlockCipher* algo, const std::string& provider); - - /** - * @param algo_spec the algorithm we want - * @param provider the provider we would like to use - * @returns pointer to const prototype object, ready to clone(), or NULL - */ - const StreamCipher* - prototype_stream_cipher(const std::string& algo_spec, - const std::string& provider = ""); - - /** - * @param algo_spec the algorithm we want - * @param provider the provider we would like to use - * @returns pointer to freshly created instance of the request algorithm - */ - StreamCipher* make_stream_cipher(const std::string& algo_spec, - const std::string& provider = ""); - - /** - * @param algo the algorithm to add - * @param provider the provider of this algorithm - */ - void add_stream_cipher(StreamCipher* algo, const std::string& provider); - - /** - * @param algo_spec the algorithm we want - * @param provider the provider we would like to use - * @returns pointer to const prototype object, ready to clone(), or NULL - */ - const HashFunction* - prototype_hash_function(const std::string& algo_spec, - const std::string& provider = ""); - - /** - * @param algo_spec the algorithm we want - * @param provider the provider we would like to use - * @returns pointer to freshly created instance of the request algorithm - */ - HashFunction* make_hash_function(const std::string& algo_spec, - const std::string& provider = ""); - - /** - * @param algo the algorithm to add - * @param provider the provider of this algorithm - */ - void add_hash_function(HashFunction* algo, const std::string& provider); - - /** - * @param algo_spec the algorithm we want - * @param provider the provider we would like to use - * @returns pointer to const prototype object, ready to clone(), or NULL - */ - const MessageAuthenticationCode* - prototype_mac(const std::string& algo_spec, - const std::string& provider = ""); - - /** - * @param algo_spec the algorithm we want - * @param provider the provider we would like to use - * @returns pointer to freshly created instance of the request algorithm - */ - MessageAuthenticationCode* make_mac(const std::string& algo_spec, - const std::string& provider = ""); - - /** - * @param algo the algorithm to add - * @param provider the provider of this algorithm - */ - void add_mac(MessageAuthenticationCode* algo, - const std::string& provider); - - /** - * @param algo_spec the algorithm we want - * @param provider the provider we would like to use - * @returns pointer to const prototype object, ready to clone(), or NULL - */ - const PBKDF* prototype_pbkdf(const std::string& algo_spec, - const std::string& provider = ""); - - /** - * @param algo_spec the algorithm we want - * @param provider the provider we would like to use - * @returns pointer to freshly created instance of the request algorithm - */ - PBKDF* make_pbkdf(const std::string& algo_spec, - const std::string& provider = ""); - - /** - * @param algo the algorithm to add - * @param provider the provider of this algorithm - */ - void add_pbkdf(PBKDF* algo, const std::string& provider); - - /** - * An iterator for the engines in this factory - * @deprecated Avoid in new code - */ - class BOTAN_DLL Engine_Iterator - { - public: - /** - * @return next engine in the sequence - */ - Engine* next() { return af.get_engine_n(n++); } - - /** - * @param a an algorithm factory - */ - Engine_Iterator(const Algorithm_Factory& a) : - af(a) { n = 0; } - private: - const Algorithm_Factory& af; - size_t n; - }; - friend class Engine_Iterator; - - private: - Algorithm_Factory(const Algorithm_Factory&) {} - Algorithm_Factory& operator=(const Algorithm_Factory&) - { return (*this); } - - Engine* get_engine_n(size_t n) const; - - std::vector engines; - - Algorithm_Cache* block_cipher_cache; - Algorithm_Cache* stream_cipher_cache; - Algorithm_Cache* hash_cache; - Algorithm_Cache* mac_cache; - Algorithm_Cache* pbkdf_cache; - }; - -} - - - -namespace Botan { - -class Mutex; - -/** -* Global state container aka the buritto at the center of it all -*/ -class BOTAN_DLL Library_State - { - public: - Library_State(); - ~Library_State(); - - /** - * @param thread_safe should a mutex be used for serialization - */ - void initialize(bool thread_safe); - - /** - * @return global Algorithm_Factory - */ - Algorithm_Factory& algorithm_factory() const; - - /** - * @return global RandomNumberGenerator - */ - RandomNumberGenerator& global_rng(); - - /** - * @param name the name of the allocator - * @return allocator matching this name, or NULL - */ - Allocator* get_allocator(const std::string& name = "") const; - - /** - * Add a new allocator to the list of available ones - * @param alloc the allocator to add - */ - void add_allocator(Allocator* alloc); - - /** - * Set the default allocator - * @param name the name of the allocator to use as the default - */ - void set_default_allocator(const std::string& name); - - /** - * Get a parameter value as std::string. - * @param section the section of the desired key - * @param key the desired keys name - * @result the value of the parameter - */ - std::string get(const std::string& section, - const std::string& key) const; - - /** - * Check whether a certain parameter is set or not. - * @param section the section of the desired key - * @param key the desired keys name - * @result true if the parameters value is set, - * false otherwise - */ - bool is_set(const std::string& section, - const std::string& key) const; - - /** - * Set a configuration parameter. - * @param section the section of the desired key - * @param key the desired keys name - * @param value the new value - * @param overwrite if set to true, the parameters value - * will be overwritten even if it is already set, otherwise - * no existing values will be overwritten. - */ - void set(const std::string& section, - const std::string& key, - const std::string& value, - bool overwrite = true); - - /** - * Add a parameter value to the "alias" section. - * @param key the name of the parameter which shall have a new alias - * @param value the new alias - */ - void add_alias(const std::string& key, - const std::string& value); - - /** - * Resolve an alias. - * @param alias the alias to resolve. - * @return what the alias stands for - */ - std::string deref_alias(const std::string& alias) const; - - /** - * @return newly created Mutex (free with delete) - */ - Mutex* get_mutex() const; - private: - static RandomNumberGenerator* make_global_rng(Algorithm_Factory& af, - Mutex* mutex); - - void load_default_config(); - - Library_State(const Library_State&) {} - Library_State& operator=(const Library_State&) { return (*this); } - - class Mutex_Factory* mutex_factory; - - Mutex* global_rng_lock; - RandomNumberGenerator* global_rng_ptr; - - Mutex* config_lock; - std::map config; - - Mutex* allocator_lock; - std::string default_allocator_name; - std::map alloc_factory; - mutable Allocator* cached_default_allocator; - std::vector allocators; - - Algorithm_Factory* m_algorithm_factory; - }; - -} - - - -namespace Botan { - -/** -* BitBucket is a filter which simply discards all inputs -*/ -struct BOTAN_DLL BitBucket : public Filter - { - void write(const byte[], size_t) {} - - std::string name() const { return "BitBucket"; } - }; - -/** -* This class represents Filter chains. A Filter chain is an ordered -* concatenation of Filters, the input to a Chain sequentially passes -* through all the Filters contained in the Chain. -*/ - -class BOTAN_DLL Chain : public Fanout_Filter - { - public: - void write(const byte input[], size_t length) { send(input, length); } - - std::string name() const; - - /** - * Construct a chain of up to four filters. The filters are set - * up in the same order as the arguments. - */ - Chain(Filter* = 0, Filter* = 0, Filter* = 0, Filter* = 0); - - /** - * Construct a chain from range of filters - * @param filter_arr the list of filters - * @param length how many filters - */ - Chain(Filter* filter_arr[], size_t length); - }; - -/** -* This class represents a fork filter, whose purpose is to fork the -* flow of data. It causes an input message to result in n messages at -* the end of the filter, where n is the number of forks. -*/ -class BOTAN_DLL Fork : public Fanout_Filter - { - public: - void write(const byte input[], size_t length) { send(input, length); } - void set_port(size_t n) { Fanout_Filter::set_port(n); } - - std::string name() const; - - /** - * Construct a Fork filter with up to four forks. - */ - Fork(Filter*, Filter*, Filter* = 0, Filter* = 0); - - /** - * Construct a Fork from range of filters - * @param filter_arr the list of filters - * @param length how many filters - */ - Fork(Filter* filter_arr[], size_t length); - }; - -} - - -namespace Botan { - -/** -* This class represents keyed filters, i.e. filters that have to be -* fed with a key in order to function. -*/ -class BOTAN_DLL Keyed_Filter : public Filter - { - public: - /** - * Set the key of this filter - * @param key the key to use - */ - virtual void set_key(const SymmetricKey& key) = 0; - - /** - * Set the initialization vector of this filter. Note: you should - * call set_iv() only after you have called set_key() - * @param iv the initialization vector to use - */ - virtual void set_iv(const InitializationVector& iv); - - /** - * Check whether a key length is valid for this filter - * @param length the key length to be checked for validity - * @return true if the key length is valid, false otherwise - */ - virtual bool valid_keylength(size_t length) const = 0; - - /** - * Check whether an IV length is valid for this filter - * @param length the IV length to be checked for validity - * @return true if the IV length is valid, false otherwise - */ - virtual bool valid_iv_length(size_t length) const - { return (length == 0); } - }; - -} - - -namespace Botan { - -/** -* This class represents abstract data sink objects. -*/ -class BOTAN_DLL DataSink : public Filter - { - public: - bool attachable() { return false; } - DataSink() {} - virtual ~DataSink() {} - private: - DataSink& operator=(const DataSink&) { return (*this); } - DataSink(const DataSink&); - }; - -/** -* This class represents a data sink which writes its output to a stream. -*/ -class BOTAN_DLL DataSink_Stream : public DataSink - { - public: - std::string name() const { return identifier; } - - void write(const byte[], size_t); - - /** - * Construct a DataSink_Stream from a stream. - * @param stream the stream to write to - * @param name identifier - */ - DataSink_Stream(std::ostream& stream, - const std::string& name = ""); - - /** - * Construct a DataSink_Stream from a stream. - * @param pathname the name of the file to open a stream to - * @param use_binary indicates whether to treat the file - * as a binary file or not - */ - DataSink_Stream(const std::string& pathname, - bool use_binary = false); - - ~DataSink_Stream(); - private: - const std::string identifier; - - std::ostream* sink_p; - std::ostream& sink; - }; - -} - - - -#if defined(BOTAN_HAS_CODEC_FILTERS) - -namespace Botan { - -/** -* This class represents a Base64 encoder. -*/ -class BOTAN_DLL Base64_Encoder : public Filter - { - public: - std::string name() const { return "Base64_Encoder"; } - - /** - * Input a part of a message to the encoder. - * @param input the message to input as a byte array - * @param length the length of the byte array input - */ - void write(const byte input[], size_t length); - - /** - * Inform the Encoder that the current message shall be closed. - */ - void end_msg(); - - /** - * Create a base64 encoder. - * @param breaks whether to use line breaks in the output - * @param length the length of the lines of the output - * @param t_n whether to use a trailing newline - */ - Base64_Encoder(bool breaks = false, size_t length = 72, - bool t_n = false); - private: - void encode_and_send(const byte input[], size_t length, - bool final_inputs = false); - void do_output(const byte output[], size_t length); - - const size_t line_length; - const bool trailing_newline; - MemoryVector in, out; - size_t position, out_position; - }; - -/** -* This object represents a Base64 decoder. -*/ -class BOTAN_DLL Base64_Decoder : public Filter - { - public: - std::string name() const { return "Base64_Decoder"; } - - /** - * Input a part of a message to the decoder. - * @param input the message to input as a byte array - * @param length the length of the byte array input - */ - void write(const byte input[], size_t length); - - /** - * Finish up the current message - */ - void end_msg(); - - /** - * Create a base64 decoder. - * @param checking the type of checking that shall be performed by - * the decoder - */ - Base64_Decoder(Decoder_Checking checking = NONE); - private: - const Decoder_Checking checking; - MemoryVector in, out; - size_t position; - }; - -} - - -namespace Botan { - -/** -* Converts arbitrary binary data to hex strings, optionally with -* newlines inserted -*/ -class BOTAN_DLL Hex_Encoder : public Filter - { - public: - /** - * Whether to use uppercase or lowercase letters for the encoded string. - */ - enum Case { Uppercase, Lowercase }; - - std::string name() const { return "Hex_Encoder"; } - - void write(const byte in[], size_t length); - void end_msg(); - - /** - * Create a hex encoder. - * @param the_case the case to use in the encoded strings. - */ - Hex_Encoder(Case the_case); - - /** - * Create a hex encoder. - * @param newlines should newlines be used - * @param line_length if newlines are used, how long are lines - * @param the_case the case to use in the encoded strings - */ - Hex_Encoder(bool newlines = false, - size_t line_length = 72, - Case the_case = Uppercase); - private: - void encode_and_send(const byte[], size_t); - - const Case casing; - const size_t line_length; - MemoryVector in, out; - size_t position, counter; - }; - -/** -* Converts hex strings to bytes -*/ -class BOTAN_DLL Hex_Decoder : public Filter - { - public: - std::string name() const { return "Hex_Decoder"; } - - void write(const byte[], size_t); - void end_msg(); - - /** - * Construct a Hex Decoder using the specified - * character checking. - * @param checking the checking to use during decoding. - */ - Hex_Decoder(Decoder_Checking checking = NONE); - private: - const Decoder_Checking checking; - MemoryVector in, out; - size_t position; - }; - -} - -#endif - -namespace Botan { - -/** -* Stream Cipher Filter. -*/ -class BOTAN_DLL StreamCipher_Filter : public Keyed_Filter - { - public: - - std::string name() const { return cipher->name(); } - - /** - * Write input data - * @param input data - * @param input_len length of input in bytes - */ - void write(const byte input[], size_t input_len); - - bool valid_iv_length(size_t iv_len) const - { return cipher->valid_iv_length(iv_len); } - - /** - * Set the initialization vector for this filter. - * @param iv the initialization vector to set - */ - void set_iv(const InitializationVector& iv); - - /** - * Set the key of this filter. - * @param key the key to set - */ - void set_key(const SymmetricKey& key) { cipher->set_key(key); } - - /** - * Check whether a key length is valid for this filter. - * @param length the key length to be checked for validity - * @return true if the key length is valid, false otherwise - */ - bool valid_keylength(size_t length) const - { return cipher->valid_keylength(length); } - - /** - * Construct a stream cipher filter. - * @param cipher_obj a cipher object to use - */ - StreamCipher_Filter(StreamCipher* cipher_obj); - - /** - * Construct a stream cipher filter. - * @param cipher_obj a cipher object to use - * @param key the key to use inside this filter - */ - StreamCipher_Filter(StreamCipher* cipher_obj, const SymmetricKey& key); - - /** - * Construct a stream cipher filter. - * @param cipher the name of the desired cipher - */ - StreamCipher_Filter(const std::string& cipher); - - /** - * Construct a stream cipher filter. - * @param cipher the name of the desired cipher - * @param key the key to use inside this filter - */ - StreamCipher_Filter(const std::string& cipher, const SymmetricKey& key); - - ~StreamCipher_Filter() { delete cipher; } - private: - SecureVector buffer; - StreamCipher* cipher; - }; - -/** -* Hash Filter. -*/ -class BOTAN_DLL Hash_Filter : public Filter - { - public: - void write(const byte input[], size_t len) { hash->update(input, len); } - void end_msg(); - - std::string name() const { return hash->name(); } - - /** - * Construct a hash filter. - * @param hash_fun the hash function to use - * @param len the output length of this filter. Leave the default - * value 0 if you want to use the full output of the hashfunction - * hash. Otherwise, specify a smaller value here so that the - * output of the hash algorithm will be cut off. - */ - Hash_Filter(HashFunction* hash_fun, size_t len = 0) : - OUTPUT_LENGTH(len), hash(hash_fun) {} - - /** - * Construct a hash filter. - * @param request the name of the hash algorithm to use - * @param len the output length of this filter. Leave the default - * value 0 if you want to use the full output of the hashfunction - * hash. Otherwise, specify a smaller value here so that the - * output of the hash algorithm will be cut off. - */ - Hash_Filter(const std::string& request, size_t len = 0); - - ~Hash_Filter() { delete hash; } - private: - const size_t OUTPUT_LENGTH; - HashFunction* hash; - }; - -/** -* MessageAuthenticationCode Filter. -*/ -class BOTAN_DLL MAC_Filter : public Keyed_Filter - { - public: - void write(const byte input[], size_t len) { mac->update(input, len); } - void end_msg(); - - std::string name() const { return mac->name(); } - - /** - * Set the key of this filter. - * @param key the key to set - */ - void set_key(const SymmetricKey& key) { mac->set_key(key); } - - /** - * Check whether a key length is valid for this filter. - * @param length the key length to be checked for validity - * @return true if the key length is valid, false otherwise - */ - bool valid_keylength(size_t length) const - { return mac->valid_keylength(length); } - - /** - * Construct a MAC filter. The MAC key will be left empty. - * @param mac_obj the MAC to use - * @param out_len the output length of this filter. Leave the default - * value 0 if you want to use the full output of the - * MAC. Otherwise, specify a smaller value here so that the - * output of the MAC will be cut off. - */ - MAC_Filter(MessageAuthenticationCode* mac_obj, - size_t out_len = 0) : OUTPUT_LENGTH(out_len) - { - mac = mac_obj; - } - - /** - * Construct a MAC filter. - * @param mac_obj the MAC to use - * @param key the MAC key to use - * @param out_len the output length of this filter. Leave the default - * value 0 if you want to use the full output of the - * MAC. Otherwise, specify a smaller value here so that the - * output of the MAC will be cut off. - */ - MAC_Filter(MessageAuthenticationCode* mac_obj, - const SymmetricKey& key, - size_t out_len = 0) : OUTPUT_LENGTH(out_len) - { - mac = mac_obj; - mac->set_key(key); - } - - /** - * Construct a MAC filter. The MAC key will be left empty. - * @param mac the name of the MAC to use - * @param len the output length of this filter. Leave the default - * value 0 if you want to use the full output of the - * MAC. Otherwise, specify a smaller value here so that the - * output of the MAC will be cut off. - */ - MAC_Filter(const std::string& mac, size_t len = 0); - - /** - * Construct a MAC filter. - * @param mac the name of the MAC to use - * @param key the MAC key to use - * @param len the output length of this filter. Leave the default - * value 0 if you want to use the full output of the - * MAC. Otherwise, specify a smaller value here so that the - * output of the MAC will be cut off. - */ - MAC_Filter(const std::string& mac, const SymmetricKey& key, - size_t len = 0); - - ~MAC_Filter() { delete mac; } - private: - const size_t OUTPUT_LENGTH; - MessageAuthenticationCode* mac; - }; - -} - - -namespace Botan { - -/** -* Block Cipher Mode Padding Method -* This class is pretty limited, it cannot deal well with -* randomized padding methods, or any padding method that -* wants to add more than one block. For instance, it should -* be possible to define cipher text stealing mode as simply -* a padding mode for CBC, which happens to consume the last -* two block (and requires use of the block cipher). -*/ -class BOTAN_DLL BlockCipherModePaddingMethod - { - public: - /** - * @param block output buffer - * @param size of the block - * @param current_position in the last block - */ - virtual void pad(byte block[], - size_t size, - size_t current_position) const = 0; - - /** - * @param block the last block - * @param size the of the block - */ - virtual size_t unpad(const byte block[], - size_t size) const = 0; - - /** - * @param block_size of the cipher - * @param position in the current block - * @return number of padding bytes that will be appended - */ - virtual size_t pad_bytes(size_t block_size, - size_t position) const; - - /** - * @param block_size of the cipher - * @return valid block size for this padding mode - */ - virtual bool valid_blocksize(size_t block_size) const = 0; - - /** - * @return name of the mode - */ - virtual std::string name() const = 0; - - /** - * virtual destructor - */ - virtual ~BlockCipherModePaddingMethod() {} - }; - -/** -* PKCS#7 Padding -*/ -class BOTAN_DLL PKCS7_Padding : public BlockCipherModePaddingMethod - { - public: - void pad(byte[], size_t, size_t) const; - size_t unpad(const byte[], size_t) const; - bool valid_blocksize(size_t) const; - std::string name() const { return "PKCS7"; } - }; - -/** -* ANSI X9.23 Padding -*/ -class BOTAN_DLL ANSI_X923_Padding : public BlockCipherModePaddingMethod - { - public: - void pad(byte[], size_t, size_t) const; - size_t unpad(const byte[], size_t) const; - bool valid_blocksize(size_t) const; - std::string name() const { return "X9.23"; } - }; - -/** -* One And Zeros Padding -*/ -class BOTAN_DLL OneAndZeros_Padding : public BlockCipherModePaddingMethod - { - public: - void pad(byte[], size_t, size_t) const; - size_t unpad(const byte[], size_t) const; - bool valid_blocksize(size_t) const; - std::string name() const { return "OneAndZeros"; } - }; - -/** -* Null Padding -*/ -class BOTAN_DLL Null_Padding : public BlockCipherModePaddingMethod - { - public: - void pad(byte[], size_t, size_t) const { return; } - size_t unpad(const byte[], size_t size) const { return size; } - size_t pad_bytes(size_t, size_t) const { return 0; } - bool valid_blocksize(size_t) const { return true; } - std::string name() const { return "NoPadding"; } - }; - -} - - -namespace Botan { - -/** -* Key Derivation Function -*/ -class BOTAN_DLL KDF : public Algorithm - { - public: - /** - * Derive a key - * @param key_len the desired output length in bytes - * @param secret the secret input - * @param salt a diversifier - */ - SecureVector derive_key(size_t key_len, - const MemoryRegion& secret, - const std::string& salt = "") const; - - /** - * Derive a key - * @param key_len the desired output length in bytes - * @param secret the secret input - * @param salt a diversifier - */ - SecureVector derive_key(size_t key_len, - const MemoryRegion& secret, - const MemoryRegion& salt) const; - - /** - * Derive a key - * @param key_len the desired output length in bytes - * @param secret the secret input - * @param salt a diversifier - * @param salt_len size of salt in bytes - */ - SecureVector derive_key(size_t key_len, - const MemoryRegion& secret, - const byte salt[], - size_t salt_len) const; - - /** - * Derive a key - * @param key_len the desired output length in bytes - * @param secret the secret input - * @param secret_len size of secret in bytes - * @param salt a diversifier - */ - SecureVector derive_key(size_t key_len, - const byte secret[], - size_t secret_len, - const std::string& salt = "") const; - - /** - * Derive a key - * @param key_len the desired output length in bytes - * @param secret the secret input - * @param secret_len size of secret in bytes - * @param salt a diversifier - * @param salt_len size of salt in bytes - */ - SecureVector derive_key(size_t key_len, - const byte secret[], - size_t secret_len, - const byte salt[], - size_t salt_len) const; - - void clear() {} - - virtual KDF* clone() const = 0; - private: - virtual SecureVector - derive(size_t key_len, - const byte secret[], size_t secret_len, - const byte salt[], size_t salt_len) const = 0; - }; - -/** -* Mask Generation Function -*/ -class BOTAN_DLL MGF - { - public: - virtual void mask(const byte in[], size_t in_len, - byte out[], size_t out_len) const = 0; - - virtual ~MGF() {} - }; - -} - - -namespace Botan { - -/** -* Encoding Method for Encryption -*/ -class BOTAN_DLL EME - { - public: - /** - * Return the maximum input size in bytes we can support - * @param keybits the size of the key in bits - * @return upper bound of input in bytes - */ - virtual size_t maximum_input_size(size_t keybits) const = 0; - - /** - * Encode an input - * @param in the plaintext - * @param in_length length of plaintext in bytes - * @param key_length length of the key in bits - * @param rng a random number generator - * @return encoded plaintext - */ - SecureVector encode(const byte in[], - size_t in_length, - size_t key_length, - RandomNumberGenerator& rng) const; - - /** - * Encode an input - * @param in the plaintext - * @param key_length length of the key in bits - * @param rng a random number generator - * @return encoded plaintext - */ - SecureVector encode(const MemoryRegion& in, - size_t key_length, - RandomNumberGenerator& rng) const; - - /** - * Decode an input - * @param in the encoded plaintext - * @param in_length length of encoded plaintext in bytes - * @param key_length length of the key in bits - * @return plaintext - */ - SecureVector decode(const byte in[], - size_t in_length, - size_t key_length) const; - - /** - * Decode an input - * @param in the encoded plaintext - * @param key_length length of the key in bits - * @return plaintext - */ - SecureVector decode(const MemoryRegion& in, - size_t key_length) const; - - virtual ~EME() {} - private: - /** - * Encode an input - * @param in the plaintext - * @param in_length length of plaintext in bytes - * @param key_length length of the key in bits - * @param rng a random number generator - * @return encoded plaintext - */ - virtual SecureVector pad(const byte in[], - size_t in_length, - size_t key_length, - RandomNumberGenerator& rng) const = 0; - - /** - * Decode an input - * @param in the encoded plaintext - * @param in_length length of encoded plaintext in bytes - * @param key_length length of the key in bits - * @return plaintext - */ - virtual SecureVector unpad(const byte in[], - size_t in_length, - size_t key_length) const = 0; - }; - -} - - -namespace Botan { - -/** -* Retrieve an object prototype from the global factory -* @param algo_spec an algorithm name -* @return constant prototype object (use clone to create usable object), - library retains ownership -*/ -inline const BlockCipher* -retrieve_block_cipher(const std::string& algo_spec) - { - Algorithm_Factory& af = global_state().algorithm_factory(); - return af.prototype_block_cipher(algo_spec); - } - -/** -* Retrieve an object prototype from the global factory -* @param algo_spec an algorithm name -* @return constant prototype object (use clone to create usable object), - library retains ownership -*/ -inline const StreamCipher* -retrieve_stream_cipher(const std::string& algo_spec) - { - Algorithm_Factory& af = global_state().algorithm_factory(); - return af.prototype_stream_cipher(algo_spec); - } - -/** -* Retrieve an object prototype from the global factory -* @param algo_spec an algorithm name -* @return constant prototype object (use clone to create usable object), - library retains ownership -*/ -inline const HashFunction* -retrieve_hash(const std::string& algo_spec) - { - Algorithm_Factory& af = global_state().algorithm_factory(); - return af.prototype_hash_function(algo_spec); - } - -/** -* Retrieve an object prototype from the global factory -* @param algo_spec an algorithm name -* @return constant prototype object (use clone to create usable object), - library retains ownership -*/ -inline const MessageAuthenticationCode* -retrieve_mac(const std::string& algo_spec) - { - Algorithm_Factory& af = global_state().algorithm_factory(); - return af.prototype_mac(algo_spec); - } - -/* -* Get an algorithm object -* NOTE: these functions create and return new objects, letting the -* caller assume ownership of them -*/ - -/** -* Block cipher factory method. -* @deprecated Call algorithm_factory() directly -* -* @param algo_spec the name of the desired block cipher -* @return pointer to the block cipher object -*/ -inline BlockCipher* get_block_cipher(const std::string& algo_spec) - { - Algorithm_Factory& af = global_state().algorithm_factory(); - return af.make_block_cipher(algo_spec); - } - -/** -* Stream cipher factory method. -* @deprecated Call algorithm_factory() directly -* -* @param algo_spec the name of the desired stream cipher -* @return pointer to the stream cipher object -*/ -inline StreamCipher* get_stream_cipher(const std::string& algo_spec) - { - Algorithm_Factory& af = global_state().algorithm_factory(); - return af.make_stream_cipher(algo_spec); - } - -/** -* Hash function factory method. -* @deprecated Call algorithm_factory() directly -* -* @param algo_spec the name of the desired hash function -* @return pointer to the hash function object -*/ -inline HashFunction* get_hash(const std::string& algo_spec) - { - Algorithm_Factory& af = global_state().algorithm_factory(); - return af.make_hash_function(algo_spec); - } - -/** -* MAC factory method. -* @deprecated Call algorithm_factory() directly -* -* @param algo_spec the name of the desired MAC -* @return pointer to the MAC object -*/ -inline MessageAuthenticationCode* get_mac(const std::string& algo_spec) - { - Algorithm_Factory& af = global_state().algorithm_factory(); - return af.make_mac(algo_spec); - } - -/** -* Password based key derivation function factory method -* @param algo_spec the name of the desired PBKDF algorithm -* @return pointer to newly allocated object of that type -*/ -BOTAN_DLL PBKDF* get_pbkdf(const std::string& algo_spec); - -/** -* @deprecated Use get_pbkdf -* @param algo_spec the name of the desired algorithm -* @return pointer to newly allocated object of that type -*/ -inline PBKDF* get_s2k(const std::string& algo_spec) - { - return get_pbkdf(algo_spec); - } - -/* -* Get an EMSA/EME/KDF/MGF function -*/ -// NOTE: these functions create and return new objects, letting the -// caller assume ownership of them - -/** -* Factory method for EME (message-encoding methods for encryption) objects -* @param algo_spec the name of the EME to create -* @return pointer to newly allocated object of that type -*/ -BOTAN_DLL EME* get_eme(const std::string& algo_spec); - -/** -* Factory method for EMSA (message-encoding methods for signatures -* with appendix) objects -* @param algo_spec the name of the EME to create -* @return pointer to newly allocated object of that type -*/ -BOTAN_DLL EMSA* get_emsa(const std::string& algo_spec); - -/** -* Factory method for KDF (key derivation function) -* @param algo_spec the name of the KDF to create -* @return pointer to newly allocated object of that type -*/ -BOTAN_DLL KDF* get_kdf(const std::string& algo_spec); - -/* -* Get a cipher object -*/ - -/** -* Factory method for general symmetric cipher filters. -* @param algo_spec the name of the desired cipher -* @param key the key to be used for encryption/decryption performed by -* the filter -* @param iv the initialization vector to be used -* @param direction determines whether the filter will be an encrypting -* or decrypting filter -* @return pointer to newly allocated encryption or decryption filter -*/ -BOTAN_DLL Keyed_Filter* get_cipher(const std::string& algo_spec, - const SymmetricKey& key, - const InitializationVector& iv, - Cipher_Dir direction); - -/** -* Factory method for general symmetric cipher filters. -* @param algo_spec the name of the desired cipher -* @param key the key to be used for encryption/decryption performed by -* the filter -* @param direction determines whether the filter will be an encrypting -* or decrypting filter -* @return pointer to the encryption or decryption filter -*/ -BOTAN_DLL Keyed_Filter* get_cipher(const std::string& algo_spec, - const SymmetricKey& key, - Cipher_Dir direction); - -/** -* Factory method for general symmetric cipher filters. No key will be -* set in the filter. -* -* @param algo_spec the name of the desired cipher -* @param direction determines whether the filter will be an encrypting or -* decrypting filter -* @return pointer to the encryption or decryption filter -*/ -BOTAN_DLL Keyed_Filter* get_cipher(const std::string& algo_spec, - Cipher_Dir direction); - -/** -* Check if an algorithm exists. -* @param algo_spec the name of the algorithm to check for -* @return true if the algorithm exists, false otherwise -*/ -BOTAN_DLL bool have_algorithm(const std::string& algo_spec); - -/** -* Check if a block cipher algorithm exists. -* @deprecated Call algorithm_factory() directly -* -* @param algo_spec the name of the algorithm to check for -* @return true if the algorithm exists, false otherwise -*/ -inline bool have_block_cipher(const std::string& algo_spec) - { - Algorithm_Factory& af = global_state().algorithm_factory(); - return (af.prototype_block_cipher(algo_spec) != 0); - } - -/** -* Check if a stream cipher algorithm exists. -* @deprecated Call algorithm_factory() directly -* -* @param algo_spec the name of the algorithm to check for -* @return true if the algorithm exists, false otherwise -*/ -inline bool have_stream_cipher(const std::string& algo_spec) - { - Algorithm_Factory& af = global_state().algorithm_factory(); - return (af.prototype_stream_cipher(algo_spec) != 0); - } - -/** -* Check if a hash algorithm exists. -* @deprecated Call algorithm_factory() directly -* -* @param algo_spec the name of the algorithm to check for -* @return true if the algorithm exists, false otherwise -*/ -inline bool have_hash(const std::string& algo_spec) - { - Algorithm_Factory& af = global_state().algorithm_factory(); - return (af.prototype_hash_function(algo_spec) != 0); - } - -/** -* Check if a MAC algorithm exists. -* @deprecated Call algorithm_factory() directly -* -* @param algo_spec the name of the algorithm to check for -* @return true if the algorithm exists, false otherwise -*/ -inline bool have_mac(const std::string& algo_spec) - { - Algorithm_Factory& af = global_state().algorithm_factory(); - return (af.prototype_mac(algo_spec) != 0); - } - -/* -* Query information about an algorithm -*/ - -/** -* Find out the block size of a certain symmetric algorithm. -* @deprecated Call algorithm_factory() directly -* -* @param algo_spec the name of the algorithm -* @return block size of the specified algorithm -*/ -BOTAN_DLL size_t block_size_of(const std::string& algo_spec); - -/** -* Find out the output length of a certain symmetric algorithm. -* @deprecated Call algorithm_factory() directly -* -* @param algo_spec the name of the algorithm -* @return output length of the specified algorithm -*/ -BOTAN_DLL size_t output_length_of(const std::string& algo_spec); - -/** -* Find out the minimum key size of a certain symmetric algorithm. -* @deprecated Call algorithm_factory() directly -* -* @param algo_spec the name of the algorithm -* @return minimum key length of the specified algorithm -*/ -BOTAN_DEPRECATED("Retrieve object you want and then call key_spec") -BOTAN_DLL size_t min_keylength_of(const std::string& algo_spec); - -/** -* Find out the maximum key size of a certain symmetric algorithm. -* @deprecated Call algorithm_factory() directly -* -* @param algo_spec the name of the algorithm -* @return maximum key length of the specified algorithm -*/ -BOTAN_DEPRECATED("Retrieve object you want and then call key_spec") -BOTAN_DLL size_t max_keylength_of(const std::string& algo_spec); - -/** -* Find out the size any valid key is a multiple of for a certain algorithm. -* @deprecated Call algorithm_factory() directly -* -* @param algo_spec the name of the algorithm -* @return size any valid key is a multiple of -*/ -BOTAN_DEPRECATED("Retrieve object you want and then call key_spec") -BOTAN_DLL size_t keylength_multiple_of(const std::string& algo_spec); - -} - - -namespace Botan { - -/* -* Get information describing the version -*/ - -/** -* Get a human-readable string identifying the version of Botan. -* No particular format should be assumed. -* @return version string -*/ -BOTAN_DLL std::string version_string(); - -/** -* Return the date this version of botan was released, in an integer of -* the form YYYYMMDD. For instance a version released on May 21, 2013 -* would return the integer 20130521. If the currently running version -* is not an official release, this function will return 0 instead. -* -* @return release date, or zero if unreleased -*/ -BOTAN_DLL u32bit version_datestamp(); - -/** -* Get the major version number. -* @return major version number -*/ -BOTAN_DLL u32bit version_major(); - -/** -* Get the minor version number. -* @return minor version number -*/ -BOTAN_DLL u32bit version_minor(); - -/** -* Get the patch number. -* @return patch number -*/ -BOTAN_DLL u32bit version_patch(); - -/* -* Macros for compile-time version checks -*/ -#define BOTAN_VERSION_CODE_FOR(a,b,c) ((a << 16) | (b << 8) | (c)) - -/** -* Compare using BOTAN_VERSION_CODE_FOR, as in -* # if BOTAN_VERSION_CODE < BOTAN_VERSION_CODE_FOR(1,8,0) -* # error "Botan version too old" -* # endif -*/ -#define BOTAN_VERSION_CODE BOTAN_VERSION_CODE_FOR(BOTAN_VERSION_MAJOR, \ - BOTAN_VERSION_MINOR, \ - BOTAN_VERSION_PATCH) - -} - - - -#if defined(BOTAN_HAS_AUTO_SEEDING_RNG) - -namespace Botan { - -/** -* An automatically seeded PRNG -*/ -class BOTAN_DLL AutoSeeded_RNG : public RandomNumberGenerator - { - public: - void randomize(byte out[], size_t len) - { rng->randomize(out, len); } - - bool is_seeded() const { return rng->is_seeded(); } - - void clear() { rng->clear(); } - - std::string name() const { return rng->name(); } - - void reseed(size_t poll_bits = 256) { rng->reseed(poll_bits); } - - void add_entropy_source(EntropySource* es) - { rng->add_entropy_source(es); } - - void add_entropy(const byte in[], size_t len) - { rng->add_entropy(in, len); } - - AutoSeeded_RNG() { rng = &global_state().global_rng(); } - private: - RandomNumberGenerator* rng; - }; - -} - -#endif - - -namespace Botan { - -/** -* PKCS #10 Certificate Request. -*/ -class BOTAN_DLL PKCS10_Request : public X509_Object - { - public: - /** - * Get the subject public key. - * @return subject public key - */ - Public_Key* subject_public_key() const; - - /** - * Get the raw DER encoded public key. - * @return raw DER encoded public key - */ - MemoryVector raw_public_key() const; - - /** - * Get the subject DN. - * @return subject DN - */ - X509_DN subject_dn() const; - - /** - * Get the subject alternative name. - * @return subject alternative name. - */ - AlternativeName subject_alt_name() const; - - /** - * Get the key constraints for the key associated with this - * PKCS#10 object. - * @return key constraints - */ - Key_Constraints constraints() const; - - /** - * Get the extendend key constraints (if any). - * @return extended key constraints - */ - std::vector ex_constraints() const; - - /** - * Find out whether this is a CA request. - * @result true if it is a CA request, false otherwise. - */ - bool is_CA() const; - - /** - * Return the constraint on the path length defined - * in the BasicConstraints extension. - * @return path limit - */ - u32bit path_limit() const; - - /** - * Get the challenge password for this request - * @return challenge password for this request - */ - std::string challenge_password() const; - - /** - * Create a PKCS#10 Request from a data source. - * @param source the data source providing the DER encoded request - */ - PKCS10_Request(DataSource& source); - - /** - * Create a PKCS#10 Request from a file. - * @param filename the name of the file containing the DER or PEM - * encoded request file - */ - PKCS10_Request(const std::string& filename); - private: - void force_decode(); - void handle_attribute(const Attribute&); - - Data_Store info; - }; - -} - - -namespace Botan { - -/** -* Options for X.509 certificates. -*/ -class BOTAN_DLL X509_Cert_Options - { - public: - /** - * the subject common name - */ - std::string common_name; - - /** - * the subject counry - */ - std::string country; - - /** - * the subject organization - */ - std::string organization; - - /** - * the subject organizational unit - */ - std::string org_unit; - - /** - * the subject locality - */ - std::string locality; - - /** - * the subject state - */ - std::string state; - - /** - * the subject serial number - */ - std::string serial_number; - - /** - * the subject email adress - */ - std::string email; - - /** - * the subject URI - */ - std::string uri; - - /** - * the subject IPv4 address - */ - std::string ip; - - /** - * the subject DNS - */ - std::string dns; - - /** - * the subject XMPP - */ - std::string xmpp; - - /** - * the subject challenge password - */ - std::string challenge; - - /** - * the subject notBefore - */ - X509_Time start; - /** - * the subject notAfter - */ - X509_Time end; - - /** - * Indicates whether the certificate request - */ - bool is_CA; - - /** - * Indicates the BasicConstraints path limit - */ - size_t path_limit; - - /** - * The key constraints for the subject public key - */ - Key_Constraints constraints; - - /** - * The key extended constraints for the subject public key - */ - std::vector ex_constraints; - - /** - * Check the options set in this object for validity. - */ - void sanity_check() const; - - /** - * Mark the certificate as a CA certificate and set the path limit. - * @param limit the path limit to be set in the BasicConstraints extension. - */ - void CA_key(size_t limit = 1); - - /** - * Set the notBefore of the certificate. - * @param time the notBefore value of the certificate - */ - void not_before(const std::string& time); - - /** - * Set the notAfter of the certificate. - * @param time the notAfter value of the certificate - */ - void not_after(const std::string& time); - - /** - * Add the key constraints of the KeyUsage extension. - * @param constr the constraints to set - */ - void add_constraints(Key_Constraints constr); - - /** - * Add constraints to the ExtendedKeyUsage extension. - * @param oid the oid to add - */ - void add_ex_constraint(const OID& oid); - - /** - * Add constraints to the ExtendedKeyUsage extension. - * @param name the name to look up the oid to add - */ - void add_ex_constraint(const std::string& name); - - /** - * Construct a new options object - * @param opts define the common name of this object. An example for this - * parameter would be "common_name/country/organization/organizational_unit". - * @param expire_time the expiration time (from the current clock in seconds) - */ - X509_Cert_Options(const std::string& opts = "", - u32bit expire_time = 365 * 24 * 60 * 60); - }; - -namespace X509 { - -/** -* Create a self-signed X.509 certificate. -* @param opts the options defining the certificate to create -* @param key the private key used for signing, i.e. the key -* associated with this self-signed certificate -* @param hash_fn the hash function to use -* @param rng the rng to use -* @return newly created self-signed certificate -*/ -BOTAN_DLL X509_Certificate -create_self_signed_cert(const X509_Cert_Options& opts, - const Private_Key& key, - const std::string& hash_fn, - RandomNumberGenerator& rng); - -/** -* Create a PKCS#10 certificate request. -* @param opts the options defining the request to create -* @param key the key used to sign this request -* @param rng the rng to use -* @param hash_fn the hash function to use -* @return newly created PKCS#10 request -*/ -BOTAN_DLL PKCS10_Request create_cert_req(const X509_Cert_Options& opts, - const Private_Key& key, - const std::string& hash_fn, - RandomNumberGenerator& rng); - -} - -} - - -namespace Botan { - -class BigInt; -class ASN1_Object; - -/** -* General DER Encoding Object -*/ -class BOTAN_DLL DER_Encoder - { - public: - SecureVector get_contents(); - - DER_Encoder& start_cons(ASN1_Tag type_tag, - ASN1_Tag class_tag = UNIVERSAL); - DER_Encoder& end_cons(); - - DER_Encoder& start_explicit(u16bit type_tag); - DER_Encoder& end_explicit(); - - DER_Encoder& raw_bytes(const byte val[], size_t len); - DER_Encoder& raw_bytes(const MemoryRegion& val); - - DER_Encoder& encode_null(); - DER_Encoder& encode(bool b); - DER_Encoder& encode(size_t s); - DER_Encoder& encode(const BigInt& n); - DER_Encoder& encode(const MemoryRegion& v, ASN1_Tag real_type); - DER_Encoder& encode(const byte val[], size_t len, ASN1_Tag real_type); - - DER_Encoder& encode(bool b, - ASN1_Tag type_tag, - ASN1_Tag class_tag = CONTEXT_SPECIFIC); - - DER_Encoder& encode(size_t s, - ASN1_Tag type_tag, - ASN1_Tag class_tag = CONTEXT_SPECIFIC); - - DER_Encoder& encode(const BigInt& n, - ASN1_Tag type_tag, - ASN1_Tag class_tag = CONTEXT_SPECIFIC); - - DER_Encoder& encode(const MemoryRegion& v, - ASN1_Tag real_type, - ASN1_Tag type_tag, - ASN1_Tag class_tag = CONTEXT_SPECIFIC); - - DER_Encoder& encode(const byte v[], size_t len, - ASN1_Tag real_type, - ASN1_Tag type_tag, - ASN1_Tag class_tag = CONTEXT_SPECIFIC); - - template - DER_Encoder& encode_optional(const T& value, const T& default_value) - { - if(value != default_value) - encode(value); - return (*this); - } - - template - DER_Encoder& encode_list(const std::vector& values) - { - for(size_t i = 0; i != values.size(); ++i) - encode(values[i]); - return (*this); - } - - DER_Encoder& encode(const ASN1_Object& obj); - DER_Encoder& encode_if(bool pred, DER_Encoder& enc); - - DER_Encoder& add_object(ASN1_Tag type_tag, ASN1_Tag class_tag, - const byte rep[], size_t length); - - DER_Encoder& add_object(ASN1_Tag type_tag, ASN1_Tag class_tag, - const MemoryRegion& rep); - - DER_Encoder& add_object(ASN1_Tag type_tag, ASN1_Tag class_tag, - const std::string& str); - - DER_Encoder& add_object(ASN1_Tag type_tag, ASN1_Tag class_tag, - byte val); - - private: - class DER_Sequence - { - public: - ASN1_Tag tag_of() const; - SecureVector get_contents(); - void add_bytes(const byte[], size_t); - DER_Sequence(ASN1_Tag, ASN1_Tag); - private: - ASN1_Tag type_tag, class_tag; - SecureVector contents; - std::vector< SecureVector > set_contents; - }; - - SecureVector contents; - std::vector subsequences; - }; - -} - - -namespace Botan { - -/** -* EME1, aka OAEP -*/ -class BOTAN_DLL EME1 : public EME - { - public: - size_t maximum_input_size(size_t) const; - - /** - * @param hash object to use for hashing (takes ownership) - * @param P an optional label. Normally empty. - */ - EME1(HashFunction* hash, const std::string& P = ""); - - ~EME1() { delete mgf; } - private: - SecureVector pad(const byte[], size_t, size_t, - RandomNumberGenerator&) const; - SecureVector unpad(const byte[], size_t, size_t) const; - - SecureVector Phash; - MGF* mgf; - }; - -} - - -namespace Botan { - -/** -* The two types of signature format supported by Botan. -*/ -enum Signature_Format { IEEE_1363, DER_SEQUENCE }; - -/** -* Enum marking if protection against fault attacks should be used -*/ -enum Fault_Protection { - ENABLE_FAULT_PROTECTION, - DISABLE_FAULT_PROTECTION -}; - -/** -* Public Key Encryptor -*/ -class BOTAN_DLL PK_Encryptor - { - public: - - /** - * Encrypt a message. - * @param in the message as a byte array - * @param length the length of the above byte array - * @param rng the random number source to use - * @return encrypted message - */ - SecureVector encrypt(const byte in[], size_t length, - RandomNumberGenerator& rng) const - { - return enc(in, length, rng); - } - - /** - * Encrypt a message. - * @param in the message - * @param rng the random number source to use - * @return encrypted message - */ - SecureVector encrypt(const MemoryRegion& in, - RandomNumberGenerator& rng) const - { - return enc(&in[0], in.size(), rng); - } - - /** - * Return the maximum allowed message size in bytes. - * @return maximum message size in bytes - */ - virtual size_t maximum_input_size() const = 0; - - PK_Encryptor() {} - virtual ~PK_Encryptor() {} - private: - PK_Encryptor(const PK_Encryptor&) {} - PK_Encryptor& operator=(const PK_Encryptor&) { return *this; } - - virtual SecureVector enc(const byte[], size_t, - RandomNumberGenerator&) const = 0; - }; - -/** -* Public Key Decryptor -*/ -class BOTAN_DLL PK_Decryptor - { - public: - /** - * Decrypt a ciphertext. - * @param in the ciphertext as a byte array - * @param length the length of the above byte array - * @return decrypted message - */ - SecureVector decrypt(const byte in[], size_t length) const - { - return dec(in, length); - } - - /** - * Decrypt a ciphertext. - * @param in the ciphertext - * @return decrypted message - */ - SecureVector decrypt(const MemoryRegion& in) const - { - return dec(&in[0], in.size()); - } - - PK_Decryptor() {} - virtual ~PK_Decryptor() {} - private: - PK_Decryptor(const PK_Decryptor&) {} - PK_Decryptor& operator=(const PK_Decryptor&) { return *this; } - - virtual SecureVector dec(const byte[], size_t) const = 0; - }; - -/** -* Public Key Signer. Use the sign_message() functions for small -* messages. Use multiple calls update() to process large messages and -* generate the signature by finally calling signature(). -*/ -class BOTAN_DLL PK_Signer - { - public: - /** - * Sign a message. - * @param in the message to sign as a byte array - * @param length the length of the above byte array - * @param rng the rng to use - * @return signature - */ - SecureVector sign_message(const byte in[], size_t length, - RandomNumberGenerator& rng); - - /** - * Sign a message. - * @param in the message to sign - * @param rng the rng to use - * @return signature - */ - SecureVector sign_message(const MemoryRegion& in, - RandomNumberGenerator& rng) - { return sign_message(&in[0], in.size(), rng); } - - /** - * Add a message part (single byte). - * @param in the byte to add - */ - void update(byte in) { update(&in, 1); } - - /** - * Add a message part. - * @param in the message part to add as a byte array - * @param length the length of the above byte array - */ - void update(const byte in[], size_t length); - - /** - * Add a message part. - * @param in the message part to add - */ - void update(const MemoryRegion& in) { update(&in[0], in.size()); } - - /** - * Get the signature of the so far processed message (provided by the - * calls to update()). - * @param rng the rng to use - * @return signature of the total message - */ - SecureVector signature(RandomNumberGenerator& rng); - - /** - * Set the output format of the signature. - * @param format the signature format to use - */ - void set_output_format(Signature_Format format) { sig_format = format; } - - /** - * Construct a PK Signer. - * @param key the key to use inside this signer - * @param emsa the EMSA to use - * An example would be "EMSA1(SHA-224)". - * @param format the signature format to use - * @param prot says if fault protection should be enabled - */ - PK_Signer(const Private_Key& key, - const std::string& emsa, - Signature_Format format = IEEE_1363, - Fault_Protection prot = ENABLE_FAULT_PROTECTION); - - ~PK_Signer() { delete op; delete verify_op; delete emsa; } - private: - bool self_test_signature(const MemoryRegion& msg, - const MemoryRegion& sig) const; - - PK_Signer(const PK_Signer&) {} - PK_Signer& operator=(const PK_Signer&) { return *this; } - - PK_Ops::Signature* op; - PK_Ops::Verification* verify_op; - EMSA* emsa; - Signature_Format sig_format; - }; - -/** -* Public Key Verifier. Use the verify_message() functions for small -* messages. Use multiple calls update() to process large messages and -* verify the signature by finally calling check_signature(). -*/ -class BOTAN_DLL PK_Verifier - { - public: - /** - * Verify a signature. - * @param msg the message that the signature belongs to, as a byte array - * @param msg_length the length of the above byte array msg - * @param sig the signature as a byte array - * @param sig_length the length of the above byte array sig - * @return true if the signature is valid - */ - bool verify_message(const byte msg[], size_t msg_length, - const byte sig[], size_t sig_length); - /** - * Verify a signature. - * @param msg the message that the signature belongs to - * @param sig the signature - * @return true if the signature is valid - */ - bool verify_message(const MemoryRegion& msg, - const MemoryRegion& sig) - { - return verify_message(&msg[0], msg.size(), - &sig[0], sig.size()); - } - - /** - * Add a message part (single byte) of the message corresponding to the - * signature to be verified. - * @param in the byte to add - */ - void update(byte in) { update(&in, 1); } - - /** - * Add a message part of the message corresponding to the - * signature to be verified. - * @param msg_part the new message part as a byte array - * @param length the length of the above byte array - */ - void update(const byte msg_part[], size_t length); - - /** - * Add a message part of the message corresponding to the - * signature to be verified. - * @param in the new message part - */ - void update(const MemoryRegion& in) - { update(&in[0], in.size()); } - - /** - * Check the signature of the buffered message, i.e. the one build - * by successive calls to update. - * @param sig the signature to be verified as a byte array - * @param length the length of the above byte array - * @return true if the signature is valid, false otherwise - */ - bool check_signature(const byte sig[], size_t length); - - /** - * Check the signature of the buffered message, i.e. the one build - * by successive calls to update. - * @param sig the signature to be verified - * @return true if the signature is valid, false otherwise - */ - bool check_signature(const MemoryRegion& sig) - { - return check_signature(&sig[0], sig.size()); - } - - /** - * Set the format of the signatures fed to this verifier. - * @param format the signature format to use - */ - void set_input_format(Signature_Format format); - - /** - * Construct a PK Verifier. - * @param pub_key the public key to verify against - * @param emsa the EMSA to use (eg "EMSA3(SHA-1)") - * @param format the signature format to use - */ - PK_Verifier(const Public_Key& pub_key, - const std::string& emsa, - Signature_Format format = IEEE_1363); - - ~PK_Verifier() { delete op; delete emsa; } - private: - PK_Verifier(const PK_Verifier&) {} - PK_Verifier& operator=(const PK_Verifier&) { return *this; } - - bool validate_signature(const MemoryRegion& msg, - const byte sig[], size_t sig_len); - - PK_Ops::Verification* op; - EMSA* emsa; - Signature_Format sig_format; - }; - -/** -* Key used for key agreement -*/ -class BOTAN_DLL PK_Key_Agreement - { - public: - - /* - * 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 - */ - SymmetricKey derive_key(size_t key_len, - const byte in[], - size_t in_len, - const byte 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 - */ - SymmetricKey derive_key(size_t key_len, - const MemoryRegion& in, - const byte params[], - size_t params_len) const - { - return derive_key(key_len, &in[0], in.size(), - params, params_len); - } - - /* - * 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 - */ - SymmetricKey derive_key(size_t key_len, - const byte in[], size_t in_len, - const std::string& params = "") const - { - return derive_key(key_len, in, in_len, - reinterpret_cast(params.data()), - params.length()); - } - - /* - * Perform Key Agreement Operation - * @param key_len the desired key output size - * @param in the other parties key - * @param params extra derivation params - */ - SymmetricKey derive_key(size_t key_len, - const MemoryRegion& in, - const std::string& params = "") const - { - return derive_key(key_len, &in[0], in.size(), - reinterpret_cast(params.data()), - params.length()); - } - - /** - * Construct a PK Key Agreement. - * @param key the key to use - * @param kdf name of the KDF to use (or 'Raw' for no KDF) - */ - PK_Key_Agreement(const PK_Key_Agreement_Key& key, - const std::string& kdf); - - ~PK_Key_Agreement() { delete op; delete kdf; } - private: - PK_Key_Agreement(const PK_Key_Agreement_Key&) {} - PK_Key_Agreement& operator=(const PK_Key_Agreement&) { return *this; } - - PK_Ops::Key_Agreement* op; - KDF* kdf; - }; - -/** -* Encryption with an MR algorithm and an EME. -*/ -class BOTAN_DLL PK_Encryptor_EME : public PK_Encryptor - { - public: - size_t maximum_input_size() const; - - /** - * Construct an instance. - * @param key the key to use inside the decryptor - * @param eme the EME to use - */ - PK_Encryptor_EME(const Public_Key& key, - const std::string& eme); - - ~PK_Encryptor_EME() { delete op; delete eme; } - private: - SecureVector enc(const byte[], size_t, - RandomNumberGenerator& rng) const; - - PK_Ops::Encryption* op; - const EME* eme; - }; - -/** -* Decryption with an MR algorithm and an EME. -*/ -class BOTAN_DLL PK_Decryptor_EME : public PK_Decryptor - { - public: - /** - * Construct an instance. - * @param key the key to use inside the encryptor - * @param eme the EME to use - */ - PK_Decryptor_EME(const Private_Key& key, - const std::string& eme); - - ~PK_Decryptor_EME() { delete op; delete eme; } - private: - SecureVector dec(const byte[], size_t) const; - - PK_Ops::Decryption* op; - const EME* eme; - }; - -/* -* Typedefs for compatability with 1.8 -*/ -typedef PK_Encryptor_EME PK_Encryptor_MR_with_EME; -typedef PK_Decryptor_EME PK_Decryptor_MR_with_EME; - -} - - -namespace Botan { - -/** -* DES -*/ -class BOTAN_DLL DES : public Block_Cipher_Fixed_Params<8, 8> - { - public: - void encrypt_n(const byte in[], byte out[], size_t blocks) const; - void decrypt_n(const byte in[], byte out[], size_t blocks) const; - - void clear() { zeroise(round_key); } - std::string name() const { return "DES"; } - BlockCipher* clone() const { return new DES; } - - DES() : round_key(32) {} - private: - void key_schedule(const byte[], size_t); - - SecureVector round_key; - }; - -/** -* Triple DES -*/ -class BOTAN_DLL TripleDES : public Block_Cipher_Fixed_Params<8, 16, 24, 8> - { - public: - void encrypt_n(const byte in[], byte out[], size_t blocks) const; - void decrypt_n(const byte in[], byte out[], size_t blocks) const; - - void clear() { zeroise(round_key); } - std::string name() const { return "TripleDES"; } - BlockCipher* clone() const { return new TripleDES; } - - TripleDES() : round_key(96) {} - private: - void key_schedule(const byte[], size_t); - - SecureVector round_key; - }; - -/* -* DES Tables -*/ -extern const u32bit DES_SPBOX1[256]; -extern const u32bit DES_SPBOX2[256]; -extern const u32bit DES_SPBOX3[256]; -extern const u32bit DES_SPBOX4[256]; -extern const u32bit DES_SPBOX5[256]; -extern const u32bit DES_SPBOX6[256]; -extern const u32bit DES_SPBOX7[256]; -extern const u32bit DES_SPBOX8[256]; - -extern const u64bit DES_IPTAB1[256]; -extern const u64bit DES_IPTAB2[256]; -extern const u64bit DES_FPTAB1[256]; -extern const u64bit DES_FPTAB2[256]; - -} - - -namespace Botan { - -/** -* DESX -*/ -class BOTAN_DLL DESX : public Block_Cipher_Fixed_Params<8, 24> - { - public: - void encrypt_n(const byte in[], byte out[], size_t blocks) const; - void decrypt_n(const byte in[], byte out[], size_t blocks) const; - - void clear() { des.clear(); zeroise(K1); zeroise(K2); } - std::string name() const { return "DESX"; } - BlockCipher* clone() const { return new DESX; } - - DESX() : K1(8), K2(8) {} - private: - void key_schedule(const byte[], size_t); - SecureVector K1, K2; - DES des; - }; - -} - - -namespace Botan { - -/** -* The GOST 28147-89 block cipher uses a set of 4 bit Sboxes, however -* the standard does not actually define these Sboxes; they are -* considered a local configuration issue. Several different sets are -* used. -*/ -class BOTAN_DLL GOST_28147_89_Params - { - public: - /** - * @param row the row - * @param col the column - * @return sbox entry at this row/column - */ - byte sbox_entry(size_t row, size_t col) const; - - /** - * @return name of this parameter set - */ - std::string param_name() const { return name; } - - /** - * Default GOST parameters are the ones given in GOST R 34.11 for - * testing purposes; these sboxes are also used by Crypto++, and, - * at least according to Wikipedia, the Central Bank of Russian - * Federation - * @param name of the parameter set - */ - GOST_28147_89_Params(const std::string& name = "R3411_94_TestParam"); - private: - const byte* sboxes; - std::string name; - }; - -/** -* GOST 28147-89 -*/ -class BOTAN_DLL GOST_28147_89 : public Block_Cipher_Fixed_Params<8, 32> - { - public: - void encrypt_n(const byte in[], byte out[], size_t blocks) const; - void decrypt_n(const byte in[], byte out[], size_t blocks) const; - - void clear() { zeroise(EK); } - - std::string name() const; - BlockCipher* clone() const { return new GOST_28147_89(SBOX); } - - /** - * @param params the sbox parameters to use - */ - GOST_28147_89(const GOST_28147_89_Params& params); - private: - GOST_28147_89(const SecureVector& other_SBOX) : - SBOX(other_SBOX), EK(8) {} - - void key_schedule(const byte[], size_t); - - SecureVector SBOX; - SecureVector EK; - }; - -} - - -namespace Botan { - -/** -* GOST 34.11 -*/ -class BOTAN_DLL GOST_34_11 : public HashFunction - { - public: - std::string name() const { return "GOST-R-34.11-94" ; } - size_t output_length() const { return 32; } - size_t hash_block_size() const { return 32; } - HashFunction* clone() const { return new GOST_34_11; } - - void clear(); - - GOST_34_11(); - private: - void compress_n(const byte input[], size_t blocks); - - void add_data(const byte[], size_t); - void final_result(byte[]); - - GOST_28147_89 cipher; - SecureVector buffer, sum, hash; - size_t position; - u64bit count; - }; - -} - - -namespace Botan { - -/** -* SHA-384 -*/ -class BOTAN_DLL SHA_384 : public MDx_HashFunction - { - public: - std::string name() const { return "SHA-384"; } - size_t output_length() const { return 48; } - HashFunction* clone() const { return new SHA_384; } - - void clear(); - - SHA_384() : MDx_HashFunction(128, true, true, 16), digest(8) - { clear(); } - private: - void compress_n(const byte[], size_t blocks); - void copy_out(byte[]); - - SecureVector digest; - }; - -/** -* SHA-512 -*/ -class BOTAN_DLL SHA_512 : public MDx_HashFunction - { - public: - std::string name() const { return "SHA-512"; } - size_t output_length() const { return 64; } - HashFunction* clone() const { return new SHA_512; } - - void clear(); - - SHA_512() : MDx_HashFunction(128, true, true, 16), digest(8) - { clear(); } - private: - void compress_n(const byte[], size_t blocks); - void copy_out(byte[]); - - SecureVector digest; - }; - -} - - -namespace Botan { - -/** -* Password Based Encryption (PBE) Filter. -*/ -class BOTAN_DLL PBE : public Filter - { - public: - /** - * Set this filter's key. - * @param pw the password to be used for the encryption - */ - virtual void set_key(const std::string& pw) = 0; - - /** - * Create a new random salt value and set the default iterations value. - * @param rng a random number generator - */ - virtual void new_params(RandomNumberGenerator& rng) = 0; - - /** - * DER encode the params (the number of iterations and the salt value) - * @return encoded params - */ - virtual MemoryVector encode_params() const = 0; - - /** - * Decode params and use them inside this Filter. - * @param src a data source to read the encoded params from - */ - virtual void decode_params(DataSource& src) = 0; - - /** - * Get this PBE's OID. - * @return object identifier - */ - virtual OID get_oid() const = 0; - }; - -} - - -namespace Botan { - -/** -* KDF1, from IEEE 1363 -*/ -class BOTAN_DLL KDF1 : public KDF - { - public: - SecureVector derive(size_t, - const byte secret[], size_t secret_len, - const byte P[], size_t P_len) const; - - std::string name() const { return "KDF1(" + hash->name() + ")"; } - KDF* clone() const { return new KDF1(hash->clone()); } - - KDF1(HashFunction* h) : hash(h) {} - KDF1(const KDF1& other) : KDF(), hash(other.hash->clone()) {} - - ~KDF1() { delete hash; } - private: - HashFunction* hash; - }; - -} - - -namespace Botan { - -/** -* MISTY1 -*/ -class BOTAN_DLL MISTY1 : public Block_Cipher_Fixed_Params<8, 16> - { - public: - void encrypt_n(const byte in[], byte out[], size_t blocks) const; - void decrypt_n(const byte in[], byte out[], size_t blocks) const; - - void clear() { zeroise(EK); zeroise(DK); } - std::string name() const { return "MISTY1"; } - BlockCipher* clone() const { return new MISTY1; } - - /** - * @param rounds the number of rounds. Must be 8 with the current - * implementation - */ - MISTY1(size_t rounds = 8); - private: - void key_schedule(const byte[], size_t); - - SecureVector EK, DK; - }; - -} - - -namespace Botan { - -/** -* 32-bit cyclic redundancy check -*/ -class BOTAN_DLL CRC32 : public HashFunction - { - public: - std::string name() const { return "CRC32"; } - size_t output_length() const { return 4; } - HashFunction* clone() const { return new CRC32; } - - void clear() { crc = 0xFFFFFFFF; } - - CRC32() { clear(); } - ~CRC32() { clear(); } - private: - void add_data(const byte[], size_t); - void final_result(byte[]); - u32bit crc; - }; - -} - - -namespace Botan { - -namespace PEM_Code { - -/* -* PEM Encoding/Decoding -*/ -BOTAN_DLL std::string encode(const byte[], size_t, - const std::string&, size_t = 64); -BOTAN_DLL std::string encode(const MemoryRegion&, - const std::string&, size_t = 64); - -BOTAN_DLL SecureVector decode(DataSource&, std::string&); -BOTAN_DLL SecureVector decode_check_label(DataSource&, - const std::string&); -BOTAN_DLL bool matches(DataSource&, const std::string& = "", - size_t search_range = 4096); - -} - -} - - -namespace Botan { - -/** -* XTEA -*/ -class BOTAN_DLL XTEA : public Block_Cipher_Fixed_Params<8, 16> - { - public: - void encrypt_n(const byte in[], byte out[], size_t blocks) const; - void decrypt_n(const byte in[], byte out[], size_t blocks) const; - - void clear() { zeroise(EK); } - std::string name() const { return "XTEA"; } - BlockCipher* clone() const { return new XTEA; } - - XTEA() : EK(64) {} - protected: - /** - * @return const reference to the key schedule - */ - const SecureVector& get_EK() const { return EK; } - - private: - void key_schedule(const byte[], size_t); - SecureVector EK; - }; - -} - - -namespace Botan { - -/** -* KASUMI, the block cipher used in 3G telephony -*/ -class BOTAN_DLL KASUMI : public Block_Cipher_Fixed_Params<8, 16> - { - public: - void encrypt_n(const byte in[], byte out[], size_t blocks) const; - void decrypt_n(const byte in[], byte out[], size_t blocks) const; - - void clear() { zeroise(EK); } - std::string name() const { return "KASUMI"; } - BlockCipher* clone() const { return new KASUMI; } - - KASUMI() : EK(64) {} - private: - void key_schedule(const byte[], size_t); - - SecureVector EK; - }; - -} - - -namespace Botan { - -/** -* This class represents discrete logarithm groups. It holds a prime p, -* a prime q = (p-1)/2 and g = x^((p-1)/q) mod p. -*/ -class BOTAN_DLL DL_Group - { - public: - /** - * Get the prime p. - * @return prime p - */ - const BigInt& get_p() const; - - /** - * Get the prime q. - * @return prime q - */ - const BigInt& get_q() const; - - /** - * Get the base g. - * @return base g - */ - const BigInt& get_g() const; - - /** - * The DL group encoding format variants. - */ - enum Format { - ANSI_X9_42, - ANSI_X9_57, - PKCS_3, - - DSA_PARAMETERS = ANSI_X9_57, - DH_PARAMETERS = ANSI_X9_42, - X942_DH_PARAMETERS = ANSI_X9_42, - PKCS3_DH_PARAMETERS = PKCS_3 - }; - - /** - * Determine the prime creation for DL groups. - */ - enum PrimeType { Strong, Prime_Subgroup, DSA_Kosherizer }; - - /** - * Perform validity checks on the group. - * @param rng the rng to use - * @param strong whether to perform stronger by lengthier tests - * @return true if the object is consistent, false otherwise - */ - bool verify_group(RandomNumberGenerator& rng, bool strong) const; - - /** - * Encode this group into a string using PEM encoding. - * @param format the encoding format - * @return string holding the PEM encoded group - */ - std::string PEM_encode(Format format) const; - - /** - * Encode this group into a string using DER encoding. - * @param format the encoding format - * @return string holding the DER encoded group - */ - SecureVector DER_encode(Format format) const; - - /** - * Decode a DER/BER encoded group into this instance. - * @param src a DataSource providing the encoded group - * @param format the format of the encoded group - */ - void BER_decode(DataSource& src, Format format); - - /** - * Decode a PEM encoded group into this instance. - * @param src a DataSource providing the encoded group - */ - void PEM_decode(DataSource& src); - - /** - * Construct a DL group with uninitialized internal value. - * Use this constructor is you wish to set the groups values - * from a DER or PEM encoded group. - */ - DL_Group(); - - /** - * Construct a DL group that is registered in the configuration. - * @param name the name that is configured in the global configuration - * for the desired group. If no configuration file is specified, - * the default values from the file policy.cpp will be used. For instance, - * use "modp/ietf/768" as name. - */ - DL_Group(const std::string& name); - - /** - * Create a new group randomly. - * @param rng the random number generator to use - * @param type specifies how the creation of primes p and q shall - * be performed. If type=Strong, then p will be determined as a - * safe prime, and q will be chosen as (p-1)/2. If - * type=Prime_Subgroup and qbits = 0, then the size of q will be - * determined according to the estimated difficulty of the DL - * problem. If type=DSA_Kosherizer, DSA primes will be created. - * @param pbits the number of bits of p - * @param qbits the number of bits of q. Leave it as 0 to have - * the value determined according to pbits. - */ - DL_Group(RandomNumberGenerator& rng, PrimeType type, - size_t pbits, size_t qbits = 0); - - /** - * Create a DSA group with a given seed. - * @param rng the random number generator to use - * @param seed the seed to use to create the random primes - * @param pbits the desired bit size of the prime p - * @param qbits the desired bit size of the prime q. - */ - DL_Group(RandomNumberGenerator& rng, const MemoryRegion& seed, - size_t pbits = 1024, size_t qbits = 0); - - /** - * Create a DL group. The prime q will be determined according to p. - * @param p the prime p - * @param g the base g - */ - DL_Group(const BigInt& p, const BigInt& g); - - /** - * Create a DL group. - * @param p the prime p - * @param q the prime q - * @param g the base g - */ - DL_Group(const BigInt& p, const BigInt& q, const BigInt& g); - private: - static BigInt make_dsa_generator(const BigInt&, const BigInt&); - - void init_check() const; - void initialize(const BigInt&, const BigInt&, const BigInt&); - bool initialized; - BigInt p, q, g; - }; - -} - - -namespace Botan { - -/** -* This class represents discrete logarithm (DL) public keys. -*/ -class BOTAN_DLL DL_Scheme_PublicKey : public virtual Public_Key - { - public: - bool check_key(RandomNumberGenerator& rng, bool) const; - - AlgorithmIdentifier algorithm_identifier() const; - - MemoryVector x509_subject_public_key() const; - - /** - * Get the DL domain parameters of this key. - * @return DL domain parameters of this key - */ - const DL_Group& get_domain() const { return group; } - - /** - * Get the public value y with y = g^x mod p where x is the secret key. - */ - const BigInt& get_y() const { return y; } - - /** - * Get the prime p of the underlying DL group. - * @return prime p - */ - const BigInt& group_p() const { return group.get_p(); } - - /** - * Get the prime q of the underlying DL group. - * @return prime q - */ - const BigInt& group_q() const { return group.get_q(); } - - /** - * Get the generator g of the underlying DL group. - * @return generator g - */ - const BigInt& group_g() const { return group.get_g(); } - - /** - * Get the underlying groups encoding format. - * @return encoding format - */ - virtual DL_Group::Format group_format() const = 0; - - DL_Scheme_PublicKey(const AlgorithmIdentifier& alg_id, - const MemoryRegion& key_bits, - DL_Group::Format group_format); - - protected: - DL_Scheme_PublicKey() {} - - /** - * The DL public key - */ - BigInt y; - - /** - * The DL group - */ - DL_Group group; - }; - -/** -* This class represents discrete logarithm (DL) private keys. -*/ -class BOTAN_DLL DL_Scheme_PrivateKey : public virtual DL_Scheme_PublicKey, - public virtual Private_Key - { - public: - bool check_key(RandomNumberGenerator& rng, bool) const; - - /** - * Get the secret key x. - * @return secret key - */ - const BigInt& get_x() const { return x; } - - MemoryVector pkcs8_private_key() const; - - DL_Scheme_PrivateKey(const AlgorithmIdentifier& alg_id, - const MemoryRegion& key_bits, - DL_Group::Format group_format); - - protected: - DL_Scheme_PrivateKey() {} - - /** - * The DL private key - */ - BigInt x; - }; - -} - - -namespace Botan { - -/** -* Modular Reducer (using Barrett's technique) -*/ -class BOTAN_DLL Modular_Reducer - { - public: - const BigInt& get_modulus() const { return modulus; } - - BigInt reduce(const BigInt& x) const; - - /** - * Multiply mod p - * @param x - * @param y - * @return (x * y) % p - */ - BigInt multiply(const BigInt& x, const BigInt& y) const - { return reduce(x * y); } - - /** - * Square mod p - * @param x - * @return (x * x) % p - */ - BigInt square(const BigInt& x) const - { return reduce(Botan::square(x)); } - - /** - * Cube mod p - * @param x - * @return (x * x * x) % p - */ - BigInt cube(const BigInt& x) const - { return multiply(x, this->square(x)); } - - bool initialized() const { return (mod_words != 0); } - - Modular_Reducer() { mod_words = 0; } - Modular_Reducer(const BigInt& mod); - private: - BigInt modulus, modulus_2, mu; - size_t mod_words; - }; - -} - - -namespace Botan { - -/** -* Blinding Function Object -*/ -class BOTAN_DLL Blinder - { - public: - BigInt blind(const BigInt& x) const; - BigInt unblind(const BigInt& x) const; - - bool initialized() const { return reducer.initialized(); } - - Blinder() {} - - /** - * Construct a blinder - * @param mask the forward (blinding) mask - * @param inverse_mask the inverse of mask (depends on algo) - * @param modulus of the group operations are performed in - */ - Blinder(const BigInt& mask, - const BigInt& inverse_mask, - const BigInt& modulus); - - private: - Modular_Reducer reducer; - mutable BigInt e, d; - }; - -} - - -namespace Botan { - -/** -* This class represents Diffie-Hellman public keys. -*/ -class BOTAN_DLL DH_PublicKey : public virtual DL_Scheme_PublicKey - { - public: - std::string algo_name() const { return "DH"; } - - MemoryVector public_value() const; - size_t max_input_bits() const { return group_p().bits(); } - - DL_Group::Format group_format() const { return DL_Group::ANSI_X9_42; } - - DH_PublicKey(const AlgorithmIdentifier& alg_id, - const MemoryRegion& key_bits) : - DL_Scheme_PublicKey(alg_id, key_bits, DL_Group::ANSI_X9_42) {} - - /** - * Construct a public key with the specified parameters. - * @param grp the DL group to use in the key - * @param y the public value y - */ - DH_PublicKey(const DL_Group& grp, const BigInt& y); - protected: - DH_PublicKey() {} - }; - -/** -* This class represents Diffie-Hellman private keys. -*/ -class BOTAN_DLL DH_PrivateKey : public DH_PublicKey, - public PK_Key_Agreement_Key, - public virtual DL_Scheme_PrivateKey - { - public: - MemoryVector public_value() const; - - /** - * Load a DH private key - * @param alg_id the algorithm id - * @param key_bits the subject public key - * @param rng a random number generator - */ - DH_PrivateKey(const AlgorithmIdentifier& alg_id, - const MemoryRegion& key_bits, - RandomNumberGenerator& rng); - - /** - * Construct a private key with predetermined value. - * @param rng random number generator to use - * @param grp the group to be used in the key - * @param x the key's secret value (or if zero, generate a new key) - */ - DH_PrivateKey(RandomNumberGenerator& rng, const DL_Group& grp, - const BigInt& x = 0); - }; - -/** -* DH operation -*/ -class BOTAN_DLL DH_KA_Operation : public PK_Ops::Key_Agreement - { - public: - DH_KA_Operation(const DH_PrivateKey& key); - - SecureVector agree(const byte w[], size_t w_len); - private: - const BigInt& p; - - Fixed_Exponent_Power_Mod powermod_x_p; - Blinder blinder; - }; - -} - - -namespace Botan { - -/** -* CAST-256 -*/ -class BOTAN_DLL CAST_256 : public Block_Cipher_Fixed_Params<16, 4, 32, 4> - { - public: - void encrypt_n(const byte in[], byte out[], size_t blocks) const; - void decrypt_n(const byte in[], byte out[], size_t blocks) const; - - void clear() { zeroise(MK); zeroise(RK); } - std::string name() const { return "CAST-256"; } - BlockCipher* clone() const { return new CAST_256; } - - CAST_256() : MK(48), RK(48) {} - private: - void key_schedule(const byte[], size_t); - - static const u32bit KEY_MASK[192]; - static const byte KEY_ROT[32]; - - SecureVector MK; - SecureVector RK; - }; - -extern const u32bit CAST_SBOX1[256]; -extern const u32bit CAST_SBOX2[256]; -extern const u32bit CAST_SBOX3[256]; -extern const u32bit CAST_SBOX4[256]; - -} - - -namespace Botan { - -/** -* MD2 -*/ -class BOTAN_DLL MD2 : public HashFunction - { - public: - std::string name() const { return "MD2"; } - size_t output_length() const { return 16; } - size_t hash_block_size() const { return 16; } - HashFunction* clone() const { return new MD2; } - - void clear(); - - MD2() : X(48), checksum(16), buffer(16) - { clear(); } - private: - void add_data(const byte[], size_t); - void hash(const byte[]); - void final_result(byte[]); - - SecureVector X, checksum, buffer; - size_t position; - }; - -} - - -namespace Botan { - -/** -* RC6, Ron Rivest's AES candidate -*/ -class BOTAN_DLL RC6 : public Block_Cipher_Fixed_Params<16, 1, 32> - { - public: - void encrypt_n(const byte in[], byte out[], size_t blocks) const; - void decrypt_n(const byte in[], byte out[], size_t blocks) const; - - void clear() { zeroise(S); } - std::string name() const { return "RC6"; } - BlockCipher* clone() const { return new RC6; } - - RC6() : S(44) {} - private: - void key_schedule(const byte[], size_t); - - SecureVector S; - }; - -} - - -namespace Botan { - -/** -* WiderWake4+1-BE -* -* Note: quite old and possibly not safe; use XSalsa20 or a block -* cipher in counter mode. -*/ -class BOTAN_DLL WiderWake_41_BE : public StreamCipher - { - public: - void cipher(const byte[], byte[], size_t); - void set_iv(const byte[], size_t); - - bool valid_iv_length(size_t iv_len) const - { return (iv_len == 8); } - - Key_Length_Specification key_spec() const - { - return Key_Length_Specification(16); - } - - void clear(); - std::string name() const { return "WiderWake4+1-BE"; } - StreamCipher* clone() const { return new WiderWake_41_BE; } - - WiderWake_41_BE() : T(256), state(5), t_key(4), - buffer(DEFAULT_BUFFERSIZE), position(0) - {} - - private: - void key_schedule(const byte[], size_t); - - void generate(size_t); - - SecureVector T; - SecureVector state; - SecureVector t_key; - SecureVector buffer; - size_t position; - }; - -} - - -namespace Botan { - -/** -* ElGamal Public Key -*/ -class BOTAN_DLL ElGamal_PublicKey : public virtual DL_Scheme_PublicKey - { - public: - std::string algo_name() const { return "ElGamal"; } - DL_Group::Format group_format() const { return DL_Group::ANSI_X9_42; } - - size_t max_input_bits() const { return (group_p().bits() - 1); } - - ElGamal_PublicKey(const AlgorithmIdentifier& alg_id, - const MemoryRegion& key_bits) : - DL_Scheme_PublicKey(alg_id, key_bits, DL_Group::ANSI_X9_42) - {} - - ElGamal_PublicKey(const DL_Group& group, const BigInt& y); - protected: - ElGamal_PublicKey() {} - }; - -/** -* ElGamal Private Key -*/ -class BOTAN_DLL ElGamal_PrivateKey : public ElGamal_PublicKey, - public virtual DL_Scheme_PrivateKey - { - public: - bool check_key(RandomNumberGenerator& rng, bool) const; - - ElGamal_PrivateKey(const AlgorithmIdentifier& alg_id, - const MemoryRegion& key_bits, - RandomNumberGenerator& rng); - - ElGamal_PrivateKey(RandomNumberGenerator& rng, - const DL_Group& group, - const BigInt& priv_key = 0); - }; - -/** -* ElGamal encryption operation -*/ -class BOTAN_DLL ElGamal_Encryption_Operation : public PK_Ops::Encryption - { - public: - size_t max_input_bits() const { return mod_p.get_modulus().bits() - 1; } - - ElGamal_Encryption_Operation(const ElGamal_PublicKey& key); - - SecureVector encrypt(const byte msg[], size_t msg_len, - RandomNumberGenerator& rng); - - private: - Fixed_Base_Power_Mod powermod_g_p, powermod_y_p; - Modular_Reducer mod_p; - }; - -/** -* ElGamal decryption operation -*/ -class BOTAN_DLL ElGamal_Decryption_Operation : public PK_Ops::Decryption - { - public: - size_t max_input_bits() const { return mod_p.get_modulus().bits() - 1; } - - ElGamal_Decryption_Operation(const ElGamal_PrivateKey& key); - - SecureVector decrypt(const byte msg[], size_t msg_len); - private: - Fixed_Exponent_Power_Mod powermod_x_p; - Modular_Reducer mod_p; - Blinder blinder; - }; - -} - - -namespace Botan { - -/** -HMAC_RNG - based on the design described in "On Extract-then-Expand -Key Derivation Functions and an HMAC-based KDF" by Hugo Krawczyk -(henceforce, 'E-t-E') - -However it actually can be parameterized with any two MAC functions, -not restricted to HMAC (this variation is also described in Krawczyk's -paper), for instance one could use HMAC(SHA-512) as the extractor -and CMAC(AES-256) as the PRF. -*/ -class BOTAN_DLL HMAC_RNG : public RandomNumberGenerator - { - public: - void randomize(byte buf[], size_t len); - bool is_seeded() const { return seeded; } - void clear(); - std::string name() const; - - void reseed(size_t poll_bits); - void add_entropy_source(EntropySource* es); - void add_entropy(const byte[], size_t); - - /** - * @param extractor a MAC used for extracting the entropy - * @param prf a MAC used as a PRF using HKDF construction - */ - HMAC_RNG(MessageAuthenticationCode* extractor, - MessageAuthenticationCode* prf); - - ~HMAC_RNG(); - private: - MessageAuthenticationCode* extractor; - MessageAuthenticationCode* prf; - - std::vector entropy_sources; - bool seeded; - - SecureVector K, io_buffer; - size_t user_input_len; - u32bit counter; - }; - -} - - -namespace Botan { - -/** -* A MAC only used in SSLv3. Do not use elsewhere! Use HMAC instead. -*/ -class BOTAN_DLL SSL3_MAC : public MessageAuthenticationCode - { - public: - std::string name() const; - size_t output_length() const { return hash->output_length(); } - MessageAuthenticationCode* clone() const; - - void clear(); - - Key_Length_Specification key_spec() const - { - return Key_Length_Specification(hash->output_length()); - } - - /** - * @param hash the underlying hash to use - */ - SSL3_MAC(HashFunction* hash); - ~SSL3_MAC() { delete hash; } - private: - void add_data(const byte[], size_t); - void final_result(byte[]); - void key_schedule(const byte[], size_t); - - HashFunction* hash; - SecureVector i_key, o_key; - }; - -} - - -namespace Botan { - -/** -EMSA1_BSI is a variant of EMSA1 specified by the BSI. It accepts only -hash values which are less or equal than the maximum key length. The -implementation comes from InSiTo -*/ -class BOTAN_DLL EMSA1_BSI : public EMSA1 - { - public: - /** - * @param hash the hash object to use - */ - EMSA1_BSI(HashFunction* hash) : EMSA1(hash) {} - private: - SecureVector encoding_of(const MemoryRegion&, size_t, - RandomNumberGenerator& rng); - }; - -} - - -namespace Botan { - -/** -* Serpent, an AES finalist -*/ -class BOTAN_DLL Serpent : public Block_Cipher_Fixed_Params<16, 16, 32, 8> - { - public: - void encrypt_n(const byte in[], byte out[], size_t blocks) const; - void decrypt_n(const byte in[], byte out[], size_t blocks) const; - - void clear() { zeroise(round_key); } - std::string name() const { return "Serpent"; } - BlockCipher* clone() const { return new Serpent; } - - Serpent() : round_key(132) {} - protected: - /** - * For use by subclasses using SIMD, asm, etc - * @return const reference to the key schedule - */ - const SecureVector& get_round_keys() const - { return round_key; } - - /** - * For use by subclasses that implement the key schedule - * @param ks is the new key schedule value to set - */ - void set_round_keys(const u32bit ks[132]) - { - copy_mem(&round_key[0], ks, 132); - } - - private: - void key_schedule(const byte key[], size_t length); - SecureVector round_key; - }; - -} - - -namespace Botan { - -/** -* NIST's SHA-160 -*/ -class BOTAN_DLL SHA_160 : public MDx_HashFunction - { - public: - std::string name() const { return "SHA-160"; } - size_t output_length() const { return 20; } - HashFunction* clone() const { return new SHA_160; } - - void clear(); - - SHA_160() : MDx_HashFunction(64, true, true), digest(5), W(80) - { - clear(); - } - protected: - /** - * Set a custom size for the W array. Normally 80, but some - * subclasses need slightly more for best performance/internal - * constraints - * @param W_size how big to make W - */ - SHA_160(size_t W_size) : - MDx_HashFunction(64, true, true), digest(5), W(W_size) - { - clear(); - } - - void compress_n(const byte[], size_t blocks); - void copy_out(byte[]); - - /** - * The digest value, exposed for use by subclasses (asm, SSE2) - */ - SecureVector digest; - - /** - * The message buffer, exposed for use by subclasses (asm, SSE2) - */ - SecureVector W; - }; - -} - - -namespace Botan { - -/** -* ANSI X9.31 RNG -*/ -class BOTAN_DLL ANSI_X931_RNG : public RandomNumberGenerator - { - public: - void randomize(byte[], size_t); - bool is_seeded() const; - void clear(); - std::string name() const; - - void reseed(size_t poll_bits); - void add_entropy_source(EntropySource*); - void add_entropy(const byte[], size_t); - - /** - * @param cipher the block cipher to use in this PRNG - * @param rng the underlying PRNG for generating inputs - * (eg, an HMAC_RNG) - */ - ANSI_X931_RNG(BlockCipher* cipher, - RandomNumberGenerator* rng); - ~ANSI_X931_RNG(); - private: - void rekey(); - void update_buffer(); - - BlockCipher* cipher; - RandomNumberGenerator* prng; - SecureVector V, R; - size_t position; - }; - -} - - -namespace Botan { - -/** -* This class represents ECDSA Public Keys. -*/ -class BOTAN_DLL ECDSA_PublicKey : public virtual EC_PublicKey - { - public: - - /** - * Construct a public key from a given public point. - * @param dom_par the domain parameters associated with this key - * @param public_point the public point defining this key - */ - ECDSA_PublicKey(const EC_Group& dom_par, - const PointGFp& public_point) : - EC_PublicKey(dom_par, public_point) {} - - ECDSA_PublicKey(const AlgorithmIdentifier& alg_id, - const MemoryRegion& key_bits) : - EC_PublicKey(alg_id, key_bits) {} - - /** - * Get this keys algorithm name. - * @result this keys algorithm name ("ECDSA") - */ - std::string algo_name() const { return "ECDSA"; } - - /** - * Get the maximum number of bits allowed to be fed to this key. - * This is the bitlength of the order of the base point. - * @result the maximum number of input bits - */ - size_t max_input_bits() const { return domain().get_order().bits(); } - - size_t message_parts() const { return 2; } - - size_t message_part_size() const - { return domain().get_order().bytes(); } - - protected: - ECDSA_PublicKey() {} - }; - -/** -* This class represents ECDSA Private Keys -*/ -class BOTAN_DLL ECDSA_PrivateKey : public ECDSA_PublicKey, - public EC_PrivateKey - { - public: - - /** - * Load a private key - * @param alg_id the X.509 algorithm identifier - * @param key_bits PKCS #8 structure - */ - ECDSA_PrivateKey(const AlgorithmIdentifier& alg_id, - const MemoryRegion& key_bits) : - EC_PrivateKey(alg_id, key_bits) {} - - /** - * Generate a new private key - * @param rng a random number generator - * @param domain parameters to used for this key - * @param x the private key (if zero, generate a ney random key) - */ - ECDSA_PrivateKey(RandomNumberGenerator& rng, - const EC_Group& domain, - const BigInt& x = 0) : - EC_PrivateKey(rng, domain, x) {} - - bool check_key(RandomNumberGenerator& rng, bool) const; - }; - -/** -* ECDSA signature operation -*/ -class BOTAN_DLL ECDSA_Signature_Operation : public PK_Ops::Signature - { - public: - ECDSA_Signature_Operation(const ECDSA_PrivateKey& ecdsa); - - SecureVector sign(const byte msg[], size_t msg_len, - RandomNumberGenerator& rng); - - size_t message_parts() const { return 2; } - size_t message_part_size() const { return order.bytes(); } - size_t max_input_bits() const { return order.bits(); } - - private: - const PointGFp& base_point; - const BigInt& order; - const BigInt& x; - Modular_Reducer mod_order; - }; - -/** -* ECDSA verification operation -*/ -class BOTAN_DLL ECDSA_Verification_Operation : public PK_Ops::Verification - { - public: - ECDSA_Verification_Operation(const ECDSA_PublicKey& ecdsa); - - size_t message_parts() const { return 2; } - size_t message_part_size() const { return order.bytes(); } - size_t max_input_bits() const { return order.bits(); } - - bool with_recovery() const { return false; } - - bool verify(const byte msg[], size_t msg_len, - const byte sig[], size_t sig_len); - private: - const PointGFp& base_point; - const PointGFp& public_point; - const BigInt& order; - }; - -} - - -namespace Botan { - -/** -* BigInt Division -* @param x an integer -* @param y a non-zero integer -* @param q will be set to x / y -* @param r will be set to x % y -*/ -void BOTAN_DLL divide(const BigInt& x, - const BigInt& y, - BigInt& q, - BigInt& r); - -} - - -namespace Botan { - -/** -* Square -*/ -class BOTAN_DLL Square : public Block_Cipher_Fixed_Params<16, 16> - { - public: - void encrypt_n(const byte in[], byte out[], size_t blocks) const; - void decrypt_n(const byte in[], byte out[], size_t blocks) const; - - void clear(); - std::string name() const { return "Square"; } - BlockCipher* clone() const { return new Square; } - - Square() : EK(28), DK(28), ME(32), MD(32) {} - private: - void key_schedule(const byte[], size_t); - - static void transform(u32bit[4]); - - static const byte SE[256]; - static const byte SD[256]; - static const byte Log[256]; - static const byte ALog[255]; - - static const u32bit TE0[256]; - static const u32bit TE1[256]; - static const u32bit TE2[256]; - static const u32bit TE3[256]; - static const u32bit TD0[256]; - static const u32bit TD1[256]; - static const u32bit TD2[256]; - static const u32bit TD3[256]; - - SecureVector EK, DK; - SecureVector ME, MD; - }; - -} - - -namespace Botan { - -/** -* Perform hex encoding -* @param output an array of at least input_length*2 bytes -* @param input is some binary data -* @param input_length length of input in bytes -* @param uppercase should output be upper or lower case? -*/ -void BOTAN_DLL hex_encode(char output[], - const byte input[], - size_t input_length, - bool uppercase = true); - -/** -* Perform hex encoding -* @param input some input -* @param input_length length of input in bytes -* @param uppercase should output be upper or lower case? -* @return hexadecimal representation of input -*/ -std::string BOTAN_DLL hex_encode(const byte input[], - size_t input_length, - bool uppercase = true); - -/** -* Perform hex encoding -* @param input some input -* @param uppercase should output be upper or lower case? -* @return hexadecimal representation of input -*/ -std::string BOTAN_DLL hex_encode(const MemoryRegion& input, - bool uppercase = true); - -/** -* Perform hex decoding -* @param output an array of at least input_length/2 bytes -* @param input some hex input -* @param input_length length of input in bytes -* @param input_consumed is an output parameter which says how many -* bytes of input were actually consumed. If less than -* input_length, then the range input[consumed:length] -* should be passed in later along with more input. -* @param ignore_ws ignore whitespace on input; if false, throw an - exception if whitespace is encountered -* @return number of bytes written to output -*/ -size_t BOTAN_DLL hex_decode(byte output[], - const char input[], - size_t input_length, - size_t& input_consumed, - bool ignore_ws = true); - -/** -* Perform hex decoding -* @param output an array of at least input_length/2 bytes -* @param input some hex input -* @param input_length length of input in bytes -* @param ignore_ws ignore whitespace on input; if false, throw an - exception if whitespace is encountered -* @return number of bytes written to output -*/ -size_t BOTAN_DLL hex_decode(byte output[], - const char input[], - size_t input_length, - bool ignore_ws = true); - -/** -* Perform hex decoding -* @param output an array of at least input_length/2 bytes -* @param input some hex input -* @param ignore_ws ignore whitespace on input; if false, throw an - exception if whitespace is encountered -* @return number of bytes written to output -*/ -size_t BOTAN_DLL hex_decode(byte output[], - const std::string& input, - bool ignore_ws = true); - -/** -* Perform hex decoding -* @param input some hex input -* @param input_length the length of input in bytes -* @param ignore_ws ignore whitespace on input; if false, throw an - exception if whitespace is encountered -* @return decoded hex output -*/ -SecureVector BOTAN_DLL hex_decode(const char input[], - size_t input_length, - bool ignore_ws = true); - -/** -* Perform hex decoding -* @param input some hex input -* @param ignore_ws ignore whitespace on input; if false, throw an - exception if whitespace is encountered -* @return decoded hex output -*/ -SecureVector BOTAN_DLL hex_decode(const std::string& input, - bool ignore_ws = true); - -} - - -namespace Botan { - -/** -* Block Cipher Cascade -*/ -class BOTAN_DLL Cascade_Cipher : public BlockCipher - { - public: - void encrypt_n(const byte in[], byte out[], size_t blocks) const; - void decrypt_n(const byte in[], byte out[], size_t blocks) const; - - size_t block_size() const { return block; } - - Key_Length_Specification key_spec() const - { - return Key_Length_Specification(cipher1->maximum_keylength() + - cipher2->maximum_keylength()); - } - - void clear(); - std::string name() const; - BlockCipher* clone() const; - - /** - * Create a cascade of two block ciphers - * @param cipher1 the first cipher - * @param cipher2 the second cipher - */ - Cascade_Cipher(BlockCipher* cipher1, BlockCipher* cipher2); - - ~Cascade_Cipher(); - private: - void key_schedule(const byte[], size_t); - - size_t block; - BlockCipher* cipher1; - BlockCipher* cipher2; - }; - - -} - - -namespace Botan { - -/** -* EME from PKCS #1 v1.5 -*/ -class BOTAN_DLL EME_PKCS1v15 : public EME - { - public: - size_t maximum_input_size(size_t) const; - private: - SecureVector pad(const byte[], size_t, size_t, - RandomNumberGenerator&) const; - SecureVector unpad(const byte[], size_t, size_t) const; - }; - -} - - -namespace Botan { - -/** -* Bit rotation left -* @param input the input word -* @param rot the number of bits to rotate -* @return input rotated left by rot bits -*/ -template inline T rotate_left(T input, size_t rot) - { - return static_cast((input << rot) | (input >> (8*sizeof(T)-rot)));; - } - -/** -* Bit rotation right -* @param input the input word -* @param rot the number of bits to rotate -* @return input rotated right by rot bits -*/ -template inline T rotate_right(T input, size_t rot) - { - return static_cast((input >> rot) | (input << (8*sizeof(T)-rot))); - } - -} - - -#if defined(BOTAN_TARGET_CPU_HAS_SSE2) && !defined(BOTAN_NO_SSE_INTRINSICS) - #include -#endif - -namespace Botan { - -/** -* Swap a 16 bit integer -*/ -inline u16bit reverse_bytes(u16bit val) - { - return rotate_left(val, 8); - } - -/** -* Swap a 32 bit integer -*/ -inline u32bit reverse_bytes(u32bit val) - { -#if BOTAN_GCC_VERSION >= 430 && !defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY) - /* - GCC intrinsic added in 4.3, works for a number of CPUs - - However avoid under ARM, as it branches to a function in libgcc - instead of generating inline asm, so slower even than the generic - rotate version below. - */ - return __builtin_bswap32(val); - -#elif BOTAN_USE_GCC_INLINE_ASM && defined(BOTAN_TARGET_CPU_IS_X86_FAMILY) - - // GCC-style inline assembly for x86 or x86-64 - asm("bswapl %0" : "=r" (val) : "0" (val)); - return val; - -#elif BOTAN_USE_GCC_INLINE_ASM && defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY) - - asm ("eor r3, %1, %1, ror #16\n\t" - "bic r3, r3, #0x00FF0000\n\t" - "mov %0, %1, ror #8\n\t" - "eor %0, %0, r3, lsr #8" - : "=r" (val) - : "0" (val) - : "r3", "cc"); - - return val; - -#else - - // Generic implementation - return (rotate_right(val, 8) & 0xFF00FF00) | - (rotate_left (val, 8) & 0x00FF00FF); - -#endif - } - -/** -* Swap a 64 bit integer -*/ -inline u64bit reverse_bytes(u64bit val) - { -#if BOTAN_GCC_VERSION >= 430 - - // GCC intrinsic added in 4.3, works for a number of CPUs - return __builtin_bswap64(val); - -#elif BOTAN_USE_GCC_INLINE_ASM && defined(BOTAN_TARGET_ARCH_IS_X86_64) - // GCC-style inline assembly for x86-64 - asm("bswapq %0" : "=r" (val) : "0" (val)); - return val; - -#else - /* Generic implementation. Defined in terms of 32-bit bswap so any - * optimizations in that version can help here (particularly - * useful for 32-bit x86). - */ - - u32bit hi = static_cast(val >> 32); - u32bit lo = static_cast(val); - - hi = reverse_bytes(hi); - lo = reverse_bytes(lo); - - return (static_cast(lo) << 32) | hi; -#endif - } - -/** -* Swap 4 Ts in an array -*/ -template -inline void bswap_4(T x[4]) - { - x[0] = reverse_bytes(x[0]); - x[1] = reverse_bytes(x[1]); - x[2] = reverse_bytes(x[2]); - x[3] = reverse_bytes(x[3]); - } - -#if defined(BOTAN_TARGET_CPU_HAS_SSE2) && !defined(BOTAN_NO_SSE_INTRINSICS) - -/** -* Swap 4 u32bits in an array using SSE2 shuffle instructions -*/ -template<> -inline void bswap_4(u32bit x[4]) - { - __m128i T = _mm_loadu_si128(reinterpret_cast(x)); - - T = _mm_shufflehi_epi16(T, _MM_SHUFFLE(2, 3, 0, 1)); - T = _mm_shufflelo_epi16(T, _MM_SHUFFLE(2, 3, 0, 1)); - - T = _mm_or_si128(_mm_srli_epi16(T, 8), _mm_slli_epi16(T, 8)); - - _mm_storeu_si128(reinterpret_cast<__m128i*>(x), T); - } - -#endif - -} - - -namespace Botan { - -/** -* MD5 -*/ -class BOTAN_DLL MD5 : public MDx_HashFunction - { - public: - std::string name() const { return "MD5"; } - size_t output_length() const { return 16; } - HashFunction* clone() const { return new MD5; } - - void clear(); - - MD5() : MDx_HashFunction(64, false, true), M(16), digest(4) - { clear(); } - protected: - void compress_n(const byte[], size_t blocks); - void copy_out(byte[]); - - /** - * The message buffer, exposed for use by subclasses (x86 asm) - */ - SecureVector M; - - /** - * The digest value, exposed for use by subclasses (x86 asm) - */ - SecureVector digest; - }; - -} - - -namespace Botan { - -/** -* Filter mixin that breaks input into blocks, useful for -* cipher modes -*/ -class BOTAN_DLL Buffered_Filter - { - public: - /** - * Write bytes into the buffered filter, which will them emit them - * in calls to buffered_block in the subclass - * @param in the input bytes - * @param length of in in bytes - */ - void write(const byte in[], size_t length); - - /** - * Finish a message, emitting to buffered_block and buffered_final - * Will throw an exception if less than final_minimum bytes were - * written into the filter. - */ - void end_msg(); - - /** - * Initialize a Buffered_Filter - * @param block_size the function buffered_block will be called - * with inputs which are a multiple of this size - * @param final_minimum the function buffered_final will be called - * with at least this many bytes. - */ - Buffered_Filter(size_t block_size, size_t final_minimum); - - virtual ~Buffered_Filter() {} - protected: - /** - * The block processor, implemented by subclasses - * @param input some input bytes - * @param length the size of input, guaranteed to be a multiple - * of block_size - */ - virtual void buffered_block(const byte input[], size_t length) = 0; - - /** - * The final block, implemented by subclasses - * @param input some input bytes - * @param length the size of input, guaranteed to be at least - * final_minimum bytes - */ - virtual void buffered_final(const byte input[], size_t length) = 0; - - /** - * @return block size of inputs - */ - size_t buffered_block_size() const { return main_block_mod; } - - /** - * @return current position in the buffer - */ - size_t current_position() const { return buffer_pos; } - - /** - * Reset the buffer position - */ - void buffer_reset() { buffer_pos = 0; } - private: - size_t main_block_mod, final_minimum; - - SecureVector buffer; - size_t buffer_pos; - }; - -} - - -namespace Botan { - -/** -* ECB Encryption -*/ -class BOTAN_DLL ECB_Encryption : public Keyed_Filter, - private Buffered_Filter - { - public: - std::string name() const; - - void set_key(const SymmetricKey& key) { cipher->set_key(key); } - - bool valid_keylength(size_t key_len) const - { return cipher->valid_keylength(key_len); } - - ECB_Encryption(BlockCipher* ciph, - BlockCipherModePaddingMethod* pad); - - ECB_Encryption(BlockCipher* ciph, - BlockCipherModePaddingMethod* pad, - const SymmetricKey& key); - - ~ECB_Encryption(); - private: - void buffered_block(const byte input[], size_t input_length); - void buffered_final(const byte input[], size_t input_length); - - void write(const byte input[], size_t input_length); - void end_msg(); - - BlockCipher* cipher; - BlockCipherModePaddingMethod* padder; - SecureVector temp; - }; - -/** -* ECB Decryption -*/ -class BOTAN_DLL ECB_Decryption : public Keyed_Filter, - public Buffered_Filter - { - public: - std::string name() const; - - void set_key(const SymmetricKey& key) { cipher->set_key(key); } - - bool valid_keylength(size_t key_len) const - { return cipher->valid_keylength(key_len); } - - ECB_Decryption(BlockCipher* ciph, - BlockCipherModePaddingMethod* pad); - - ECB_Decryption(BlockCipher* ciph, - BlockCipherModePaddingMethod* pad, - const SymmetricKey& key); - - ~ECB_Decryption(); - private: - void buffered_block(const byte input[], size_t input_length); - void buffered_final(const byte input[], size_t input_length); - - void write(const byte input[], size_t input_length); - void end_msg(); - - BlockCipher* cipher; - BlockCipherModePaddingMethod* padder; - SecureVector temp; - }; - -} - - -namespace Botan { - -/** -* The different charsets (nominally) supported by Botan. -*/ -enum Character_Set { - LOCAL_CHARSET, - UCS2_CHARSET, - UTF8_CHARSET, - LATIN1_CHARSET -}; - -namespace Charset { - -/* -* Character Set Handling -*/ -std::string BOTAN_DLL transcode(const std::string& str, - Character_Set to, - Character_Set from); - -bool BOTAN_DLL is_digit(char c); -bool BOTAN_DLL is_space(char c); -bool BOTAN_DLL caseless_cmp(char x, char y); - -byte BOTAN_DLL char2digit(char c); -char BOTAN_DLL digit2char(byte b); - -} - -} - - -namespace Botan { - -/** -* This class represents public keys -* of integer factorization based (IF) public key schemes. -*/ -class BOTAN_DLL IF_Scheme_PublicKey : public virtual Public_Key - { - public: - IF_Scheme_PublicKey(const AlgorithmIdentifier& alg_id, - const MemoryRegion& key_bits); - - IF_Scheme_PublicKey(const BigInt& n, const BigInt& e) : - n(n), e(e) {} - - bool check_key(RandomNumberGenerator& rng, bool) const; - - AlgorithmIdentifier algorithm_identifier() const; - - MemoryVector x509_subject_public_key() const; - - /** - * @return public modulus - */ - const BigInt& get_n() const { return n; } - - /** - * @return public exponent - */ - const BigInt& get_e() const { return e; } - - size_t max_input_bits() const { return (n.bits() - 1); } - - protected: - IF_Scheme_PublicKey() {} - - BigInt n, e; - }; - -/** -* This class represents public keys -* of integer factorization based (IF) public key schemes. -*/ -class BOTAN_DLL IF_Scheme_PrivateKey : public virtual IF_Scheme_PublicKey, - public virtual Private_Key - { - public: - - IF_Scheme_PrivateKey(RandomNumberGenerator& rng, - const BigInt& prime1, const BigInt& prime2, - const BigInt& exp, const BigInt& d_exp, - const BigInt& mod); - - IF_Scheme_PrivateKey(RandomNumberGenerator& rng, - const AlgorithmIdentifier& alg_id, - const MemoryRegion& key_bits); - - bool check_key(RandomNumberGenerator& rng, bool) const; - - /** - * Get the first prime p. - * @return prime p - */ - const BigInt& get_p() const { return p; } - - /** - * Get the second prime q. - * @return prime q - */ - const BigInt& get_q() const { return q; } - - /** - * Get d with exp * d = 1 mod (p - 1, q - 1). - * @return d - */ - const BigInt& get_d() const { return d; } - - const BigInt& get_c() const { return c; } - const BigInt& get_d1() const { return d1; } - const BigInt& get_d2() const { return d2; } - - MemoryVector pkcs8_private_key() const; - - protected: - IF_Scheme_PrivateKey() {} - - BigInt d, p, q, d1, d2, c; - }; - -} - - -namespace Botan { - -/** -* RSA Public Key -*/ -class BOTAN_DLL RSA_PublicKey : public virtual IF_Scheme_PublicKey - { - public: - std::string algo_name() const { return "RSA"; } - - RSA_PublicKey(const AlgorithmIdentifier& alg_id, - const MemoryRegion& key_bits) : - IF_Scheme_PublicKey(alg_id, key_bits) - {} - - /** - * Create a RSA_PublicKey - * @arg n the modulus - * @arg e the exponent - */ - RSA_PublicKey(const BigInt& n, const BigInt& e) : - IF_Scheme_PublicKey(n, e) - {} - - protected: - RSA_PublicKey() {} - }; - -/** -* RSA Private Key -*/ -class BOTAN_DLL RSA_PrivateKey : public RSA_PublicKey, - public IF_Scheme_PrivateKey - { - public: - bool check_key(RandomNumberGenerator& rng, bool) const; - - RSA_PrivateKey(const AlgorithmIdentifier& alg_id, - const MemoryRegion& key_bits, - RandomNumberGenerator& rng) : - IF_Scheme_PrivateKey(rng, alg_id, key_bits) {} - - /** - * Construct a private key from the specified parameters. - * @param rng a random number generator - * @param p the first prime - * @param q the second prime - * @param e the exponent - * @param d if specified, this has to be d with - * exp * d = 1 mod (p - 1, q - 1). Leave it as 0 if you wish to - * the constructor to calculate it. - * @param n if specified, this must be n = p * q. Leave it as 0 - * if you wish to the constructor to calculate it. - */ - RSA_PrivateKey(RandomNumberGenerator& rng, - const BigInt& p, const BigInt& q, - const BigInt& e, const BigInt& d = 0, - const BigInt& n = 0) : - IF_Scheme_PrivateKey(rng, p, q, e, d, n) {} - - /** - * Create a new private key with the specified bit length - * @param rng the random number generator to use - * @param bits the desired bit length of the private key - * @param exp the public exponent to be used - */ - RSA_PrivateKey(RandomNumberGenerator& rng, - size_t bits, size_t exp = 65537); - }; - -/** -* RSA private (decrypt/sign) operation -*/ -class BOTAN_DLL RSA_Private_Operation : public PK_Ops::Signature, - public PK_Ops::Decryption - { - public: - RSA_Private_Operation(const RSA_PrivateKey& rsa); - - size_t max_input_bits() const { return (n.bits() - 1); } - - SecureVector sign(const byte msg[], size_t msg_len, - RandomNumberGenerator& rng); - - SecureVector decrypt(const byte msg[], size_t msg_len); - - private: - BigInt private_op(const BigInt& m) const; - - const BigInt& n; - const BigInt& q; - const BigInt& c; - Fixed_Exponent_Power_Mod powermod_e_n, powermod_d1_p, powermod_d2_q; - Modular_Reducer mod_p; - Blinder blinder; - }; - -/** -* RSA public (encrypt/verify) operation -*/ -class BOTAN_DLL RSA_Public_Operation : public PK_Ops::Verification, - public PK_Ops::Encryption - { - public: - RSA_Public_Operation(const RSA_PublicKey& rsa) : - n(rsa.get_n()), powermod_e_n(rsa.get_e(), rsa.get_n()) - {} - - size_t max_input_bits() const { return (n.bits() - 1); } - bool with_recovery() const { return true; } - - SecureVector encrypt(const byte msg[], size_t msg_len, - RandomNumberGenerator&) - { - BigInt m(msg, msg_len); - return BigInt::encode_1363(public_op(m), n.bytes()); - } - - SecureVector verify_mr(const byte msg[], size_t msg_len) - { - BigInt m(msg, msg_len); - return BigInt::encode(public_op(m)); - } - - private: - BigInt public_op(const BigInt& m) const - { - if(m >= n) - throw Invalid_Argument("RSA public op - input is too large"); - return powermod_e_n(m); - } - - const BigInt& n; - Fixed_Exponent_Power_Mod powermod_e_n; - }; - -} - - -namespace Botan { - -/** -* RIPEMD-160 -*/ -class BOTAN_DLL RIPEMD_160 : public MDx_HashFunction - { - public: - std::string name() const { return "RIPEMD-160"; } - size_t output_length() const { return 20; } - HashFunction* clone() const { return new RIPEMD_160; } - - void clear(); - - RIPEMD_160() : MDx_HashFunction(64, false, true), M(16), digest(5) - { clear(); } - private: - void compress_n(const byte[], size_t blocks); - void copy_out(byte[]); - - SecureVector M, digest; - }; - -} - - -namespace Botan { - -/** -* Whirlpool -*/ -class BOTAN_DLL Whirlpool : public MDx_HashFunction - { - public: - std::string name() const { return "Whirlpool"; } - size_t output_length() const { return 64; } - HashFunction* clone() const { return new Whirlpool; } - - void clear(); - - Whirlpool() : MDx_HashFunction(64, true, true, 32), M(8), digest(8) - { clear(); } - private: - void compress_n(const byte[], size_t blocks); - void copy_out(byte[]); - - static const u64bit C0[256]; - static const u64bit C1[256]; - static const u64bit C2[256]; - static const u64bit C3[256]; - static const u64bit C4[256]; - static const u64bit C5[256]; - static const u64bit C6[256]; - static const u64bit C7[256]; - - SecureVector M, digest; - }; - -} - - -namespace Botan { - -/** -* Tiger -*/ -class BOTAN_DLL Tiger : public MDx_HashFunction - { - public: - std::string name() const; - size_t output_length() const { return hash_len; } - - HashFunction* clone() const - { - return new Tiger(output_length(), passes); - } - - void clear(); - - /** - * @param out_size specifies the output length; can be 16, 20, or 24 - * @param passes to make in the algorithm - */ - Tiger(size_t out_size = 24, size_t passes = 3); - private: - void compress_n(const byte[], size_t block); - void copy_out(byte[]); - - static void pass(u64bit& A, u64bit& B, u64bit& C, - const MemoryRegion& M, - byte mul); - - static const u64bit SBOX1[256]; - static const u64bit SBOX2[256]; - static const u64bit SBOX3[256]; - static const u64bit SBOX4[256]; - - SecureVector X, digest; - const size_t hash_len, passes; - }; - -} - - -namespace Botan { - -/** -* SEED, a Korean block cipher -*/ -class BOTAN_DLL SEED : public Block_Cipher_Fixed_Params<16, 16> - { - public: - void encrypt_n(const byte in[], byte out[], size_t blocks) const; - void decrypt_n(const byte in[], byte out[], size_t blocks) const; - - void clear() { zeroise(K); } - std::string name() const { return "SEED"; } - BlockCipher* clone() const { return new SEED; } - - SEED() : K(32) {} - private: - void key_schedule(const byte[], size_t); - - class G_FUNC - { - public: - u32bit operator()(u32bit) const; - private: - static const u32bit S0[256], S1[256], S2[256], S3[256]; - }; - - SecureVector K; - }; - -} - - -namespace Botan { - -/** -* EMSA3 from IEEE 1363 -* aka PKCS #1 v1.5 signature padding -* aka PKCS #1 block type 1 -*/ -class BOTAN_DLL EMSA3 : public EMSA - { - public: - /** - * @param hash the hash object to use - */ - EMSA3(HashFunction* hash); - ~EMSA3(); - - void update(const byte[], size_t); - - SecureVector raw_data(); - - SecureVector encoding_of(const MemoryRegion&, size_t, - RandomNumberGenerator& rng); - - bool verify(const MemoryRegion&, const MemoryRegion&, - size_t); - private: - HashFunction* hash; - SecureVector hash_id; - }; - -/** -* EMSA3_Raw which is EMSA3 without a hash or digest id (which -* according to QCA docs is "identical to PKCS#11's CKM_RSA_PKCS -* mechanism", something I have not confirmed) -*/ -class BOTAN_DLL EMSA3_Raw : public EMSA - { - public: - void update(const byte[], size_t); - - SecureVector raw_data(); - - SecureVector encoding_of(const MemoryRegion&, size_t, - RandomNumberGenerator& rng); - - bool verify(const MemoryRegion&, const MemoryRegion&, - size_t); - - private: - SecureVector message; - }; - -} - - -namespace Botan { - -/** -* Twofish, an AES finalist -*/ -class BOTAN_DLL Twofish : public Block_Cipher_Fixed_Params<16, 16, 32, 8> - { - public: - void encrypt_n(const byte in[], byte out[], size_t blocks) const; - void decrypt_n(const byte in[], byte out[], size_t blocks) const; - - void clear(); - std::string name() const { return "Twofish"; } - BlockCipher* clone() const { return new Twofish; } - - Twofish() : SB(1024), RK(40) {} - private: - void key_schedule(const byte[], size_t); - - static void rs_mul(byte[4], byte, size_t); - - static const u32bit MDS0[256]; - static const u32bit MDS1[256]; - static const u32bit MDS2[256]; - static const u32bit MDS3[256]; - static const byte Q0[256]; - static const byte Q1[256]; - static const byte RS[32]; - static const byte EXP_TO_POLY[255]; - static const byte POLY_TO_EXP[255]; - - SecureVector SB, RK; - }; - -} - - -namespace Botan { - -/** -* Create a password hash using PBKDF2 -* @param password the password -* @param rng a random number generator -* @param work_factor how much work to do to slow down guessing attacks -* @param alg_id specifies which PRF to use with PBKDF2 -* 0 is HMAC(SHA-1) -* 1 is HMAC(SHA-256) -* 2 is CMAC(Blowfish) -* all other values are currently undefined -*/ -std::string BOTAN_DLL generate_passhash9(const std::string& password, - RandomNumberGenerator& rng, - u16bit work_factor = 10, - byte alg_id = 0); - -/** -* Check a previously created password hash -* @param password the password to check against -* @param hash the stored hash to check against -*/ -bool BOTAN_DLL check_passhash9(const std::string& password, - const std::string& hash); - -} - - -namespace Botan { - -/** -* SHA-224 -*/ -class BOTAN_DLL SHA_224 : public MDx_HashFunction - { - public: - std::string name() const { return "SHA-224"; } - size_t output_length() const { return 28; } - HashFunction* clone() const { return new SHA_224; } - - void clear(); - - SHA_224() : MDx_HashFunction(64, true, true), digest(8) - { clear(); } - private: - void compress_n(const byte[], size_t blocks); - void copy_out(byte[]); - - SecureVector digest; - }; - -/** -* SHA-256 -*/ -class BOTAN_DLL SHA_256 : public MDx_HashFunction - { - public: - std::string name() const { return "SHA-256"; } - size_t output_length() const { return 32; } - HashFunction* clone() const { return new SHA_256; } - - void clear(); - - SHA_256() : MDx_HashFunction(64, true, true), digest(8) - { clear(); } - private: - void compress_n(const byte[], size_t blocks); - void copy_out(byte[]); - - SecureVector digest; - }; - -} - - -namespace Botan { - -/** -* Blue Midnight Wish 512 (Round 2 tweaked version) -*/ -class BOTAN_DLL BMW_512 : public MDx_HashFunction - { - public: - std::string name() const { return "BMW512"; } - size_t output_length() const { return 64; } - HashFunction* clone() const { return new BMW_512; } - - void clear(); - - BMW_512() : MDx_HashFunction(128, false, true), H(16), M(16), Q(32) - { clear(); } - private: - void compress_n(const byte input[], size_t blocks); - void copy_out(byte output[]); - - SecureVector H, M, Q; - }; - -} - - -namespace Botan { - -/** -* @param input the input data -* @param length length of input in bytes -* @param label the human-readable label -* @param headers a set of key/value pairs included in the header -*/ -BOTAN_DLL std::string PGP_encode( - const byte input[], - size_t length, - const std::string& label, - const std::map& headers); - -/** -* @param input the input data -* @param length length of input in bytes -* @param label the human-readable label -*/ -BOTAN_DLL std::string PGP_encode( - const byte input[], - size_t length, - const std::string& label); - -/** -* @param source the input source -* @param label is set to the human-readable label -* @param headers is set to any headers -* @return decoded output as raw binary -*/ -BOTAN_DLL SecureVector PGP_decode( - DataSource& source, - std::string& label, - std::map& headers); - -/** -* @param source the input source -* @param label is set to the human-readable label -* @return decoded output as raw binary -*/ -BOTAN_DLL SecureVector PGP_decode( - DataSource& source, - std::string& label); - -} - - -namespace Botan { - -/** -* Certificate Store Interface -*/ -class BOTAN_DLL Certificate_Store - { - public: - virtual ~Certificate_Store() {} - - virtual Certificate_Store* clone() const = 0; - - /** - * Add a certificate; this may fail if the store is write-only - */ - virtual void add_certificate(const X509_Certificate& cert) = 0; - - /** - * Add a CRL; this may fail if the store is write-only - */ - virtual void add_crl(const X509_CRL& crl) = 0; - - /** - * Subject DN and (optionally) key identifier - */ - virtual std::vector - find_cert_by_subject_and_key_id( - const X509_DN& subject_dn, - const MemoryRegion& key_id) const = 0; - - /** - * Find CRLs by the DN and key id of the issuer - */ - virtual std::vector - find_crl_by_subject_and_key_id( - const X509_DN& issuer_dn, - const MemoryRegion& key_id) const = 0; - }; - -/** -* In Memory Certificate Store -*/ -class BOTAN_DLL Certificate_Store_Memory : public Certificate_Store - { - public: - Certificate_Store* clone() const; - - void add_certificate(const X509_Certificate& cert); - - void add_crl(const X509_CRL& crl); - - std::vector find_cert_by_subject_and_key_id( - const X509_DN& subject_dn, - const MemoryRegion& key_id) const; - - std::vector find_crl_by_subject_and_key_id( - const X509_DN& issuer_dn, - const MemoryRegion& key_id) const; - - Certificate_Store_Memory() {} - private: - // TODO: Add indexing on the DN and key id to avoid linear search? - std::vector certs; - std::vector crls; - }; - -// TODO: file-backed store - -} - - -namespace Botan { - -/** -* KDF2, from IEEE 1363 -*/ -class BOTAN_DLL KDF2 : public KDF - { - public: - SecureVector derive(size_t, const byte[], size_t, - const byte[], size_t) const; - - std::string name() const { return "KDF2(" + hash->name() + ")"; } - KDF* clone() const { return new KDF2(hash->clone()); } - - KDF2(HashFunction* h) : hash(h) {} - KDF2(const KDF2& other) : KDF(), hash(other.hash->clone()) {} - ~KDF2() { delete hash; } - private: - HashFunction* hash; - }; - -} - - -namespace Botan { - -namespace KeyPair { - -/** -* Tests whether the key is consistent for encryption; whether -* encrypting and then decrypting gives to the original plaintext. -* @param rng the rng to use -* @param key the key to test -* @param padding the encryption padding method to use -* @return true if consistent otherwise false -*/ -BOTAN_DLL bool -encryption_consistency_check(RandomNumberGenerator& rng, - const Private_Key& key, - const std::string& padding); - -/** -* Tests whether the key is consistent for signatures; whether a -* signature can be created and then verified -* @param rng the rng to use -* @param key the key to test -* @param padding the signature padding method to use -* @return true if consistent otherwise false -*/ -BOTAN_DLL bool -signature_consistency_check(RandomNumberGenerator& rng, - const Private_Key& key, - const std::string& padding); - -} - -} - - -namespace Botan { - -/** -* This namespace holds various high-level crypto functions -*/ -namespace CryptoBox { - -/** -* Encrypt a message using a passphrase -* @param input the input data -* @param input_len the length of input in bytes -* @param passphrase the passphrase used to encrypt the message -* @param rng a ref to a random number generator, such as AutoSeeded_RNG -*/ -BOTAN_DLL std::string encrypt(const byte input[], size_t input_len, - const std::string& passphrase, - RandomNumberGenerator& rng); - -/** -* Decrypt a message encrypted with CryptoBox::encrypt -* @param input the input data -* @param input_len the length of input in bytes -* @param passphrase the passphrase used to encrypt the message -*/ -BOTAN_DLL std::string decrypt(const byte input[], size_t input_len, - const std::string& passphrase); - -/** -* Decrypt a message encrypted with CryptoBox::encrypt -* @param input the input data -* @param passphrase the passphrase used to encrypt the message -*/ -BOTAN_DLL std::string decrypt(const std::string& input, - const std::string& passphrase); - -} - -} - - -namespace Botan { - -/** -* X.509 Certificate Validation Result -*/ -enum X509_Code { - VERIFIED, - UNKNOWN_X509_ERROR, - CANNOT_ESTABLISH_TRUST, - CERT_CHAIN_TOO_LONG, - SIGNATURE_ERROR, - POLICY_ERROR, - INVALID_USAGE, - - CERT_FORMAT_ERROR, - CERT_ISSUER_NOT_FOUND, - CERT_NOT_YET_VALID, - CERT_HAS_EXPIRED, - CERT_IS_REVOKED, - - CRL_FORMAT_ERROR, - CRL_ISSUER_NOT_FOUND, - CRL_NOT_YET_VALID, - CRL_HAS_EXPIRED, - - CA_CERT_CANNOT_SIGN, - CA_CERT_NOT_FOR_CERT_ISSUER, - CA_CERT_NOT_FOR_CRL_ISSUER -}; - -/** -* X.509 Certificate Store -*/ -class BOTAN_DLL X509_Store - { - public: - enum Cert_Usage { - ANY = 0x00, - TLS_SERVER = 0x01, - TLS_CLIENT = 0x02, - CODE_SIGNING = 0x04, - EMAIL_PROTECTION = 0x08, - TIME_STAMPING = 0x10, - CRL_SIGNING = 0x20 - }; - - X509_Code validate_cert(const X509_Certificate&, Cert_Usage = ANY); - - std::vector get_cert_chain(const X509_Certificate&); - std::string PEM_encode() const; - - X509_Code add_crl(const X509_CRL&); - void add_cert(const X509_Certificate&, bool = false); - void add_certs(DataSource&); - void add_trusted_certs(DataSource&); - - void add_new_certstore(Certificate_Store*); - - X509_Store(u32bit time_slack = 24*60*60, - u32bit cache_results = 30*60); - - X509_Store(const X509_Store&); - ~X509_Store(); - private: - X509_Store& operator=(const X509_Store&) { return (*this); } - - class BOTAN_DLL CRL_Data - { - public: - X509_DN issuer; - MemoryVector serial, auth_key_id; - bool operator==(const CRL_Data&) const; - bool operator!=(const CRL_Data&) const; - bool operator<(const CRL_Data&) const; - }; - - class BOTAN_DLL Cert_Info - { - public: - bool is_verified(u32bit timeout) const; - bool is_trusted() const; - X509_Code verify_result() const; - void set_result(X509_Code) const; - Cert_Info(const X509_Certificate&, bool = false); - - X509_Certificate cert; - bool trusted; - private: - mutable bool checked; - mutable X509_Code result; - mutable u64bit last_checked; - }; - - static X509_Code check_sig(const X509_Object&, Public_Key*); - - size_t find_cert(const X509_DN&, const MemoryRegion&) const; - X509_Code check_sig(const Cert_Info&, const Cert_Info&) const; - void recompute_revoked_info() const; - - void do_add_certs(DataSource&, bool); - X509_Code construct_cert_chain(const X509_Certificate&, - std::vector&, bool = false); - - size_t find_parent_of(const X509_Certificate&); - bool is_revoked(const X509_Certificate&) const; - - static const size_t NO_CERT_FOUND = 0xFFFFFFFF; - std::vector certs; - std::vector revoked; - std::vector stores; - u32bit time_slack, validation_cache_timeout; - mutable bool revoked_info_valid; - }; - -} - - -namespace Botan { - -/** -* Noekeon -*/ -class BOTAN_DLL Noekeon : public Block_Cipher_Fixed_Params<16, 16> - { - public: - void encrypt_n(const byte in[], byte out[], size_t blocks) const; - void decrypt_n(const byte in[], byte out[], size_t blocks) const; - - void clear(); - std::string name() const { return "Noekeon"; } - BlockCipher* clone() const { return new Noekeon; } - - Noekeon() : EK(4), DK(4) {} - protected: - /** - * The Noekeon round constants - */ - static const byte RC[17]; - - /** - * @return const reference to encryption subkeys - */ - const SecureVector& get_EK() const { return EK; } - - /** - * @return const reference to decryption subkeys - */ - const SecureVector& get_DK() const { return DK; } - - private: - void key_schedule(const byte[], size_t); - SecureVector EK, DK; - }; - -} - - -namespace Botan { - -/** -* Create a password hash using Bcrypt -* @param password the password -* @param rng a random number generator -* @param work_factor how much work to do to slow down guessing attacks -* -* @see http://www.usenix.org/events/usenix99/provos/provos_html/ -*/ -std::string BOTAN_DLL generate_bcrypt(const std::string& password, - RandomNumberGenerator& rng, - u16bit work_factor = 10); - -/** -* Check a previously created password hash -* @param password the password to check against -* @param hash the stored hash to check against -*/ -bool BOTAN_DLL check_bcrypt(const std::string& password, - const std::string& hash); - -} - - -namespace Botan { - -/** -* CFB Encryption -*/ -class BOTAN_DLL CFB_Encryption : public Keyed_Filter - { - public: - std::string name() const { return cipher->name() + "/CFB"; } - - void set_iv(const InitializationVector&); - - void set_key(const SymmetricKey& key) { cipher->set_key(key); } - - bool valid_keylength(size_t key_len) const - { return cipher->valid_keylength(key_len); } - - bool valid_iv_length(size_t iv_len) const - { return (iv_len == cipher->block_size()); } - - CFB_Encryption(BlockCipher* cipher, size_t feedback = 0); - - CFB_Encryption(BlockCipher* cipher, - const SymmetricKey& key, - const InitializationVector& iv, - size_t feedback = 0); - - ~CFB_Encryption() { delete cipher; } - private: - void write(const byte[], size_t); - - BlockCipher* cipher; - SecureVector buffer, state; - size_t position, feedback; - }; - -/** -* CFB Decryption -*/ -class BOTAN_DLL CFB_Decryption : public Keyed_Filter - { - public: - std::string name() const { return cipher->name() + "/CFB"; } - - void set_iv(const InitializationVector&); - - void set_key(const SymmetricKey& key) { cipher->set_key(key); } - - bool valid_keylength(size_t key_len) const - { return cipher->valid_keylength(key_len); } - - bool valid_iv_length(size_t iv_len) const - { return (iv_len == cipher->block_size()); } - - CFB_Decryption(BlockCipher* cipher, size_t feedback = 0); - - CFB_Decryption(BlockCipher* cipher, - const SymmetricKey& key, - const InitializationVector& iv, - size_t feedback = 0); - - ~CFB_Decryption() { delete cipher; } - private: - void write(const byte[], size_t); - - BlockCipher* cipher; - SecureVector buffer, state; - size_t position, feedback; - }; - -} - - -namespace Botan { - -/** -* X.509 Certificate Extension -*/ -class BOTAN_DLL Certificate_Extension - { - public: - /** - * @return OID representing this extension - */ - OID oid_of() const; - - /** - * Make a copy of this extension - * @return copy of this - */ - virtual Certificate_Extension* copy() const = 0; - - /* - * Add the contents of this extension into the information - * for the subject and/or issuer, as necessary. - * @param subject the subject info - * @param issuer the issuer info - */ - virtual void contents_to(Data_Store& subject, - Data_Store& issuer) const = 0; - - /* - * @return short readable name - */ - virtual std::string config_id() const = 0; - - /* - * @return specific OID name - */ - virtual std::string oid_name() const = 0; - - virtual ~Certificate_Extension() {} - protected: - friend class Extensions; - virtual bool should_encode() const { return true; } - virtual MemoryVector encode_inner() const = 0; - virtual void decode_inner(const MemoryRegion&) = 0; - }; - -/** -* X.509 Certificate Extension List -*/ -class BOTAN_DLL Extensions : public ASN1_Object - { - public: - void encode_into(class DER_Encoder&) const; - void decode_from(class BER_Decoder&); - - void contents_to(Data_Store&, Data_Store&) const; - - void add(Certificate_Extension* extn, bool critical = false); - - Extensions& operator=(const Extensions&); - - Extensions(const Extensions&); - Extensions(bool st = true) : should_throw(st) {} - ~Extensions(); - private: - static Certificate_Extension* get_extension(const OID&); - - std::vector > extensions; - bool should_throw; - }; - -namespace Cert_Extension { - -static const size_t NO_CERT_PATH_LIMIT = 0xFFFFFFF0; - -/** -* Basic Constraints Extension -*/ -class BOTAN_DLL Basic_Constraints : public Certificate_Extension - { - public: - Basic_Constraints* copy() const - { return new Basic_Constraints(is_ca, path_limit); } - - Basic_Constraints(bool ca = false, size_t limit = 0) : - is_ca(ca), path_limit(limit) {} - - bool get_is_ca() const { return is_ca; } - size_t get_path_limit() const; - private: - std::string config_id() const { return "basic_constraints"; } - std::string oid_name() const { return "X509v3.BasicConstraints"; } - - MemoryVector encode_inner() const; - void decode_inner(const MemoryRegion&); - void contents_to(Data_Store&, Data_Store&) const; - - bool is_ca; - size_t path_limit; - }; - -/** -* Key Usage Constraints Extension -*/ -class BOTAN_DLL Key_Usage : public Certificate_Extension - { - public: - Key_Usage* copy() const { return new Key_Usage(constraints); } - - Key_Usage(Key_Constraints c = NO_CONSTRAINTS) : constraints(c) {} - - Key_Constraints get_constraints() const { return constraints; } - private: - std::string config_id() const { return "key_usage"; } - std::string oid_name() const { return "X509v3.KeyUsage"; } - - bool should_encode() const { return (constraints != NO_CONSTRAINTS); } - MemoryVector encode_inner() const; - void decode_inner(const MemoryRegion&); - void contents_to(Data_Store&, Data_Store&) const; - - Key_Constraints constraints; - }; - -/** -* Subject Key Identifier Extension -*/ -class BOTAN_DLL Subject_Key_ID : public Certificate_Extension - { - public: - Subject_Key_ID* copy() const { return new Subject_Key_ID(key_id); } - - Subject_Key_ID() {} - Subject_Key_ID(const MemoryRegion&); - - MemoryVector get_key_id() const { return key_id; } - private: - std::string config_id() const { return "subject_key_id"; } - std::string oid_name() const { return "X509v3.SubjectKeyIdentifier"; } - - bool should_encode() const { return (key_id.size() > 0); } - MemoryVector encode_inner() const; - void decode_inner(const MemoryRegion&); - void contents_to(Data_Store&, Data_Store&) const; - - MemoryVector key_id; - }; - -/** -* Authority Key Identifier Extension -*/ -class BOTAN_DLL Authority_Key_ID : public Certificate_Extension - { - public: - Authority_Key_ID* copy() const { return new Authority_Key_ID(key_id); } - - Authority_Key_ID() {} - Authority_Key_ID(const MemoryRegion& k) : key_id(k) {} - - MemoryVector get_key_id() const { return key_id; } - private: - std::string config_id() const { return "authority_key_id"; } - std::string oid_name() const { return "X509v3.AuthorityKeyIdentifier"; } - - bool should_encode() const { return (key_id.size() > 0); } - MemoryVector encode_inner() const; - void decode_inner(const MemoryRegion&); - void contents_to(Data_Store&, Data_Store&) const; - - MemoryVector key_id; - }; - -/** -* Alternative Name Extension Base Class -*/ -class BOTAN_DLL Alternative_Name : public Certificate_Extension - { - public: - AlternativeName get_alt_name() const { return alt_name; } - - protected: - Alternative_Name(const AlternativeName&, - const std::string&, const std::string&); - - Alternative_Name(const std::string&, const std::string&); - private: - std::string config_id() const { return config_name_str; } - std::string oid_name() const { return oid_name_str; } - - bool should_encode() const { return alt_name.has_items(); } - MemoryVector encode_inner() const; - void decode_inner(const MemoryRegion&); - void contents_to(Data_Store&, Data_Store&) const; - - std::string config_name_str, oid_name_str; - AlternativeName alt_name; - }; - -/** -* Subject Alternative Name Extension -*/ -class BOTAN_DLL Subject_Alternative_Name : public Alternative_Name - { - public: - Subject_Alternative_Name* copy() const - { return new Subject_Alternative_Name(get_alt_name()); } - - Subject_Alternative_Name(const AlternativeName& = AlternativeName()); - }; - -/** -* Issuer Alternative Name Extension -*/ -class BOTAN_DLL Issuer_Alternative_Name : public Alternative_Name - { - public: - Issuer_Alternative_Name* copy() const - { return new Issuer_Alternative_Name(get_alt_name()); } - - Issuer_Alternative_Name(const AlternativeName& = AlternativeName()); - }; - -/** -* Extended Key Usage Extension -*/ -class BOTAN_DLL Extended_Key_Usage : public Certificate_Extension - { - public: - Extended_Key_Usage* copy() const { return new Extended_Key_Usage(oids); } - - Extended_Key_Usage() {} - Extended_Key_Usage(const std::vector& o) : oids(o) {} - - std::vector get_oids() const { return oids; } - private: - std::string config_id() const { return "extended_key_usage"; } - std::string oid_name() const { return "X509v3.ExtendedKeyUsage"; } - - bool should_encode() const { return (oids.size() > 0); } - MemoryVector encode_inner() const; - void decode_inner(const MemoryRegion&); - void contents_to(Data_Store&, Data_Store&) const; - - std::vector oids; - }; - -/** -* Certificate Policies Extension -*/ -class BOTAN_DLL Certificate_Policies : public Certificate_Extension - { - public: - Certificate_Policies* copy() const - { return new Certificate_Policies(oids); } - - Certificate_Policies() {} - Certificate_Policies(const std::vector& o) : oids(o) {} - - std::vector get_oids() const { return oids; } - private: - std::string config_id() const { return "policy_info"; } - std::string oid_name() const { return "X509v3.CertificatePolicies"; } - - bool should_encode() const { return (oids.size() > 0); } - MemoryVector encode_inner() const; - void decode_inner(const MemoryRegion&); - void contents_to(Data_Store&, Data_Store&) const; - - std::vector oids; - }; - -/** -* CRL Number Extension -*/ -class BOTAN_DLL CRL_Number : public Certificate_Extension - { - public: - CRL_Number* copy() const; - - CRL_Number() : has_value(false), crl_number(0) {} - CRL_Number(size_t n) : has_value(true), crl_number(n) {} - - size_t get_crl_number() const; - private: - std::string config_id() const { return "crl_number"; } - std::string oid_name() const { return "X509v3.CRLNumber"; } - - bool should_encode() const { return has_value; } - MemoryVector encode_inner() const; - void decode_inner(const MemoryRegion&); - void contents_to(Data_Store&, Data_Store&) const; - - bool has_value; - size_t crl_number; - }; - -/** -* CRL Entry Reason Code Extension -*/ -class BOTAN_DLL CRL_ReasonCode : public Certificate_Extension - { - public: - CRL_ReasonCode* copy() const { return new CRL_ReasonCode(reason); } - - CRL_ReasonCode(CRL_Code r = UNSPECIFIED) : reason(r) {} - - CRL_Code get_reason() const { return reason; } - private: - std::string config_id() const { return "crl_reason"; } - std::string oid_name() const { return "X509v3.ReasonCode"; } - - bool should_encode() const { return (reason != UNSPECIFIED); } - MemoryVector encode_inner() const; - void decode_inner(const MemoryRegion&); - void contents_to(Data_Store&, Data_Store&) const; - - CRL_Code reason; - }; - -} - -} - - -namespace Botan { - -/** -* DSA Public Key -*/ -class BOTAN_DLL DSA_PublicKey : public virtual DL_Scheme_PublicKey - { - public: - std::string algo_name() const { return "DSA"; } - - DL_Group::Format group_format() const { return DL_Group::ANSI_X9_57; } - size_t message_parts() const { return 2; } - size_t message_part_size() const { return group_q().bytes(); } - size_t max_input_bits() const { return group_q().bits(); } - - DSA_PublicKey(const AlgorithmIdentifier& alg_id, - const MemoryRegion& key_bits) : - DL_Scheme_PublicKey(alg_id, key_bits, DL_Group::ANSI_X9_57) - { - } - - DSA_PublicKey(const DL_Group& group, const BigInt& y); - protected: - DSA_PublicKey() {} - }; - -/** -* DSA Private Key -*/ -class BOTAN_DLL DSA_PrivateKey : public DSA_PublicKey, - public virtual DL_Scheme_PrivateKey - { - public: - DSA_PrivateKey(const AlgorithmIdentifier& alg_id, - const MemoryRegion& key_bits, - RandomNumberGenerator& rng); - - DSA_PrivateKey(RandomNumberGenerator& rng, - const DL_Group& group, - const BigInt& private_key = 0); - - bool check_key(RandomNumberGenerator& rng, bool strong) const; - }; - -/** -* Object that can create a DSA signature -*/ -class BOTAN_DLL DSA_Signature_Operation : public PK_Ops::Signature - { - public: - DSA_Signature_Operation(const DSA_PrivateKey& dsa); - - size_t message_parts() const { return 2; } - size_t message_part_size() const { return q.bytes(); } - size_t max_input_bits() const { return q.bits(); } - - SecureVector sign(const byte msg[], size_t msg_len, - RandomNumberGenerator& rng); - private: - const BigInt& q; - const BigInt& x; - Fixed_Base_Power_Mod powermod_g_p; - Modular_Reducer mod_q; - }; - -/** -* Object that can verify a DSA signature -*/ -class BOTAN_DLL DSA_Verification_Operation : public PK_Ops::Verification - { - public: - DSA_Verification_Operation(const DSA_PublicKey& dsa); - - size_t message_parts() const { return 2; } - size_t message_part_size() const { return q.bytes(); } - size_t max_input_bits() const { return q.bits(); } - - bool with_recovery() const { return false; } - - bool verify(const byte msg[], size_t msg_len, - const byte sig[], size_t sig_len); - private: - const BigInt& q; - const BigInt& y; - - Fixed_Base_Power_Mod powermod_g_p, powermod_y_p; - Modular_Reducer mod_p, mod_q; - }; - -} - - -namespace Botan { - -/** -* PRF from ANSI X9.42 -*/ -class BOTAN_DLL X942_PRF : public KDF - { - public: - SecureVector derive(size_t, const byte[], size_t, - const byte[], size_t) const; - - std::string name() const { return "X942_PRF(" + key_wrap_oid + ")"; } - KDF* clone() const { return new X942_PRF(key_wrap_oid); } - - X942_PRF(const std::string& oid); - private: - std::string key_wrap_oid; - }; - -} - - -namespace Botan { - -/** -* TEA -*/ -class BOTAN_DLL TEA : public Block_Cipher_Fixed_Params<8, 16> - { - public: - void encrypt_n(const byte in[], byte out[], size_t blocks) const; - void decrypt_n(const byte in[], byte out[], size_t blocks) const; - - void clear() { zeroise(K); } - std::string name() const { return "TEA"; } - BlockCipher* clone() const { return new TEA; } - - TEA() : K(4) {} - private: - void key_schedule(const byte[], size_t); - SecureVector K; - }; - -} - - -namespace Botan { - -/** -* Nyberg-Rueppel Public Key -*/ -class BOTAN_DLL NR_PublicKey : public virtual DL_Scheme_PublicKey - { - public: - std::string algo_name() const { return "NR"; } - - DL_Group::Format group_format() const { return DL_Group::ANSI_X9_57; } - - size_t message_parts() const { return 2; } - size_t message_part_size() const { return group_q().bytes(); } - size_t max_input_bits() const { return (group_q().bits() - 1); } - - NR_PublicKey(const AlgorithmIdentifier& alg_id, - const MemoryRegion& key_bits); - - NR_PublicKey(const DL_Group& group, const BigInt& pub_key); - protected: - NR_PublicKey() {} - }; - -/** -* Nyberg-Rueppel Private Key -*/ -class BOTAN_DLL NR_PrivateKey : public NR_PublicKey, - public virtual DL_Scheme_PrivateKey - { - public: - bool check_key(RandomNumberGenerator& rng, bool strong) const; - - NR_PrivateKey(const AlgorithmIdentifier& alg_id, - const MemoryRegion& key_bits, - RandomNumberGenerator& rng); - - NR_PrivateKey(RandomNumberGenerator& rng, - const DL_Group& group, - const BigInt& x = 0); - }; - -/** -* Nyberg-Rueppel signature operation -*/ -class BOTAN_DLL NR_Signature_Operation : public PK_Ops::Signature - { - public: - NR_Signature_Operation(const NR_PrivateKey& nr); - - size_t message_parts() const { return 2; } - size_t message_part_size() const { return q.bytes(); } - size_t max_input_bits() const { return (q.bits() - 1); } - - SecureVector sign(const byte msg[], size_t msg_len, - RandomNumberGenerator& rng); - private: - const BigInt& q; - const BigInt& x; - Fixed_Base_Power_Mod powermod_g_p; - Modular_Reducer mod_q; - }; - -/** -* Nyberg-Rueppel verification operation -*/ -class BOTAN_DLL NR_Verification_Operation : public PK_Ops::Verification - { - public: - NR_Verification_Operation(const NR_PublicKey& nr); - - size_t message_parts() const { return 2; } - size_t message_part_size() const { return q.bytes(); } - size_t max_input_bits() const { return (q.bits() - 1); } - - bool with_recovery() const { return true; } - - SecureVector verify_mr(const byte msg[], size_t msg_len); - private: - const BigInt& q; - const BigInt& y; - - Fixed_Base_Power_Mod powermod_g_p, powermod_y_p; - Modular_Reducer mod_p, mod_q; - }; - -} - - -namespace Botan { - -/** -* Alleged RC4 -*/ -class BOTAN_DLL ARC4 : public StreamCipher - { - public: - void cipher(const byte in[], byte out[], size_t length); - - void clear(); - std::string name() const; - - StreamCipher* clone() const { return new ARC4(SKIP); } - - Key_Length_Specification key_spec() const - { - return Key_Length_Specification(1, 256); - } - - /** - * @param skip skip this many initial bytes in the keystream - */ - ARC4(size_t skip = 0); - - ~ARC4() { clear(); } - private: - void key_schedule(const byte[], size_t); - void generate(); - - const size_t SKIP; - - byte X, Y; - SecureVector state; - - SecureVector buffer; - size_t position; - }; - -} - - -namespace Botan { - -/** -* Rabin-Williams Public Key -*/ -class BOTAN_DLL RW_PublicKey : public virtual IF_Scheme_PublicKey - { - public: - std::string algo_name() const { return "RW"; } - - RW_PublicKey(const AlgorithmIdentifier& alg_id, - const MemoryRegion& key_bits) : - IF_Scheme_PublicKey(alg_id, key_bits) - {} - - RW_PublicKey(const BigInt& mod, const BigInt& exponent) : - IF_Scheme_PublicKey(mod, exponent) - {} - - protected: - RW_PublicKey() {} - }; - -/** -* Rabin-Williams Private Key -*/ -class BOTAN_DLL RW_PrivateKey : public RW_PublicKey, - public IF_Scheme_PrivateKey - { - public: - RW_PrivateKey(const AlgorithmIdentifier& alg_id, - const MemoryRegion& key_bits, - RandomNumberGenerator& rng) : - IF_Scheme_PrivateKey(rng, alg_id, key_bits) {} - - RW_PrivateKey(RandomNumberGenerator& rng, - const BigInt& p, const BigInt& q, - const BigInt& e, const BigInt& d = 0, - const BigInt& n = 0) : - IF_Scheme_PrivateKey(rng, p, q, e, d, n) {} - - RW_PrivateKey(RandomNumberGenerator& rng, size_t bits, size_t = 2); - - bool check_key(RandomNumberGenerator& rng, bool) const; - }; - -/** -* Rabin-Williams Signature Operation -*/ -class BOTAN_DLL RW_Signature_Operation : public PK_Ops::Signature - { - public: - RW_Signature_Operation(const RW_PrivateKey& rw); - - size_t max_input_bits() const { return (n.bits() - 1); } - - SecureVector sign(const byte msg[], size_t msg_len, - RandomNumberGenerator& rng); - private: - const BigInt& n; - const BigInt& e; - const BigInt& q; - const BigInt& c; - - Fixed_Exponent_Power_Mod powermod_d1_p, powermod_d2_q; - Modular_Reducer mod_p; - Blinder blinder; - }; - -/** -* Rabin-Williams Verification Operation -*/ -class BOTAN_DLL RW_Verification_Operation : public PK_Ops::Verification - { - public: - RW_Verification_Operation(const RW_PublicKey& rw) : - n(rw.get_n()), powermod_e_n(rw.get_e(), rw.get_n()) - {} - - size_t max_input_bits() const { return (n.bits() - 1); } - bool with_recovery() const { return true; } - - SecureVector verify_mr(const byte msg[], size_t msg_len); - - private: - const BigInt& n; - Fixed_Exponent_Power_Mod powermod_e_n; - }; - -} - - -#if BOTAN_TARGET_UNALIGNED_MEMORY_ACCESS_OK - -#if defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN) - -#define BOTAN_ENDIAN_N2B(x) (x) -#define BOTAN_ENDIAN_B2N(x) (x) - -#define BOTAN_ENDIAN_N2L(x) reverse_bytes(x) -#define BOTAN_ENDIAN_L2N(x) reverse_bytes(x) - -#elif defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN) - -#define BOTAN_ENDIAN_N2L(x) (x) -#define BOTAN_ENDIAN_L2N(x) (x) - -#define BOTAN_ENDIAN_N2B(x) reverse_bytes(x) -#define BOTAN_ENDIAN_B2N(x) reverse_bytes(x) - -#endif - -#endif - -namespace Botan { - -/** -* Make a u16bit from two bytes -* @param i0 the first byte -* @param i1 the second byte -* @return i0 || i1 -*/ -inline u16bit make_u16bit(byte i0, byte i1) - { - return ((static_cast(i0) << 8) | i1); - } - -/** -* Make a u32bit from four bytes -* @param i0 the first byte -* @param i1 the second byte -* @param i2 the third byte -* @param i3 the fourth byte -* @return i0 || i1 || i2 || i3 -*/ -inline u32bit make_u32bit(byte i0, byte i1, byte i2, byte i3) - { - return ((static_cast(i0) << 24) | - (static_cast(i1) << 16) | - (static_cast(i2) << 8) | - (static_cast(i3))); - } - -/** -* Make a u32bit from eight bytes -* @param i0 the first byte -* @param i1 the second byte -* @param i2 the third byte -* @param i3 the fourth byte -* @param i4 the fifth byte -* @param i5 the sixth byte -* @param i6 the seventh byte -* @param i7 the eighth byte -* @return i0 || i1 || i2 || i3 || i4 || i5 || i6 || i7 -*/ -inline u64bit make_u64bit(byte i0, byte i1, byte i2, byte i3, - byte i4, byte i5, byte i6, byte i7) - { - return ((static_cast(i0) << 56) | - (static_cast(i1) << 48) | - (static_cast(i2) << 40) | - (static_cast(i3) << 32) | - (static_cast(i4) << 24) | - (static_cast(i5) << 16) | - (static_cast(i6) << 8) | - (static_cast(i7))); - } - -/** -* Load a big-endian word -* @param in a pointer to some bytes -* @param off an offset into the array -* @return off'th T of in, as a big-endian value -*/ -template -inline T load_be(const byte in[], size_t off) - { - in += off * sizeof(T); - T out = 0; - for(size_t i = 0; i != sizeof(T); ++i) - out = (out << 8) | in[i]; - return out; - } - -/** -* Load a little-endian word -* @param in a pointer to some bytes -* @param off an offset into the array -* @return off'th T of in, as a litte-endian value -*/ -template -inline T load_le(const byte in[], size_t off) - { - in += off * sizeof(T); - T out = 0; - for(size_t i = 0; i != sizeof(T); ++i) - out = (out << 8) | in[sizeof(T)-1-i]; - return out; - } - -/** -* Load a big-endian u16bit -* @param in a pointer to some bytes -* @param off an offset into the array -* @return off'th u16bit of in, as a big-endian value -*/ -template<> -inline u16bit load_be(const byte in[], size_t off) - { -#if BOTAN_TARGET_UNALIGNED_MEMORY_ACCESS_OK - return BOTAN_ENDIAN_N2B(*(reinterpret_cast(in) + off)); -#else - in += off * sizeof(u16bit); - return make_u16bit(in[0], in[1]); -#endif - } - -/** -* Load a little-endian u16bit -* @param in a pointer to some bytes -* @param off an offset into the array -* @return off'th u16bit of in, as a little-endian value -*/ -template<> -inline u16bit load_le(const byte in[], size_t off) - { -#if BOTAN_TARGET_UNALIGNED_MEMORY_ACCESS_OK - return BOTAN_ENDIAN_N2L(*(reinterpret_cast(in) + off)); -#else - in += off * sizeof(u16bit); - return make_u16bit(in[1], in[0]); -#endif - } - -/** -* Load a big-endian u32bit -* @param in a pointer to some bytes -* @param off an offset into the array -* @return off'th u32bit of in, as a big-endian value -*/ -template<> -inline u32bit load_be(const byte in[], size_t off) - { -#if BOTAN_TARGET_UNALIGNED_MEMORY_ACCESS_OK - return BOTAN_ENDIAN_N2B(*(reinterpret_cast(in) + off)); -#else - in += off * sizeof(u32bit); - return make_u32bit(in[0], in[1], in[2], in[3]); -#endif - } - -/** -* Load a little-endian u32bit -* @param in a pointer to some bytes -* @param off an offset into the array -* @return off'th u32bit of in, as a little-endian value -*/ -template<> -inline u32bit load_le(const byte in[], size_t off) - { -#if BOTAN_TARGET_UNALIGNED_MEMORY_ACCESS_OK - return BOTAN_ENDIAN_N2L(*(reinterpret_cast(in) + off)); -#else - in += off * sizeof(u32bit); - return make_u32bit(in[3], in[2], in[1], in[0]); -#endif - } - -/** -* Load a big-endian u64bit -* @param in a pointer to some bytes -* @param off an offset into the array -* @return off'th u64bit of in, as a big-endian value -*/ -template<> -inline u64bit load_be(const byte in[], size_t off) - { -#if BOTAN_TARGET_UNALIGNED_MEMORY_ACCESS_OK - return BOTAN_ENDIAN_N2B(*(reinterpret_cast(in) + off)); -#else - in += off * sizeof(u64bit); - return make_u64bit(in[0], in[1], in[2], in[3], - in[4], in[5], in[6], in[7]); -#endif - } - -/** -* Load a little-endian u64bit -* @param in a pointer to some bytes -* @param off an offset into the array -* @return off'th u64bit of in, as a little-endian value -*/ -template<> -inline u64bit load_le(const byte in[], size_t off) - { -#if BOTAN_TARGET_UNALIGNED_MEMORY_ACCESS_OK - return BOTAN_ENDIAN_N2L(*(reinterpret_cast(in) + off)); -#else - in += off * sizeof(u64bit); - return make_u64bit(in[7], in[6], in[5], in[4], - in[3], in[2], in[1], in[0]); -#endif - } - -/** -* Load two little-endian words -* @param in a pointer to some bytes -* @param x0 where the first word will be written -* @param x1 where the second word will be written -*/ -template -inline void load_le(const byte in[], T& x0, T& x1) - { - x0 = load_le(in, 0); - x1 = load_le(in, 1); - } - -/** -* Load four little-endian words -* @param in a pointer to some bytes -* @param x0 where the first word will be written -* @param x1 where the second word will be written -* @param x2 where the third word will be written -* @param x3 where the fourth word will be written -*/ -template -inline void load_le(const byte in[], - T& x0, T& x1, T& x2, T& x3) - { - x0 = load_le(in, 0); - x1 = load_le(in, 1); - x2 = load_le(in, 2); - x3 = load_le(in, 3); - } - -/** -* Load eight little-endian words -* @param in a pointer to some bytes -* @param x0 where the first word will be written -* @param x1 where the second word will be written -* @param x2 where the third word will be written -* @param x3 where the fourth word will be written -* @param x4 where the fifth word will be written -* @param x5 where the sixth word will be written -* @param x6 where the seventh word will be written -* @param x7 where the eighth word will be written -*/ -template -inline void load_le(const byte in[], - T& x0, T& x1, T& x2, T& x3, - T& x4, T& x5, T& x6, T& x7) - { - x0 = load_le(in, 0); - x1 = load_le(in, 1); - x2 = load_le(in, 2); - x3 = load_le(in, 3); - x4 = load_le(in, 4); - x5 = load_le(in, 5); - x6 = load_le(in, 6); - x7 = load_le(in, 7); - } - -/** -* Load a variable number of little-endian words -* @param out the output array of words -* @param in the input array of bytes -* @param count how many words are in in -*/ -template -inline void load_le(T out[], - const byte in[], - size_t count) - { -#if defined(BOTAN_TARGET_CPU_HAS_KNOWN_ENDIANNESS) - std::memcpy(out, in, sizeof(T)*count); - -#if defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN) - const size_t blocks = count - (count % 4); - const size_t left = count - blocks; - - for(size_t i = 0; i != blocks; i += 4) - bswap_4(out + i); - - for(size_t i = 0; i != left; ++i) - out[blocks+i] = reverse_bytes(out[blocks+i]); -#endif - -#else - for(size_t i = 0; i != count; ++i) - out[i] = load_le(in, i); -#endif - } - -/** -* Load two big-endian words -* @param in a pointer to some bytes -* @param x0 where the first word will be written -* @param x1 where the second word will be written -*/ -template -inline void load_be(const byte in[], T& x0, T& x1) - { - x0 = load_be(in, 0); - x1 = load_be(in, 1); - } - -/** -* Load four big-endian words -* @param in a pointer to some bytes -* @param x0 where the first word will be written -* @param x1 where the second word will be written -* @param x2 where the third word will be written -* @param x3 where the fourth word will be written -*/ -template -inline void load_be(const byte in[], - T& x0, T& x1, T& x2, T& x3) - { - x0 = load_be(in, 0); - x1 = load_be(in, 1); - x2 = load_be(in, 2); - x3 = load_be(in, 3); - } - -/** -* Load eight big-endian words -* @param in a pointer to some bytes -* @param x0 where the first word will be written -* @param x1 where the second word will be written -* @param x2 where the third word will be written -* @param x3 where the fourth word will be written -* @param x4 where the fifth word will be written -* @param x5 where the sixth word will be written -* @param x6 where the seventh word will be written -* @param x7 where the eighth word will be written -*/ -template -inline void load_be(const byte in[], - T& x0, T& x1, T& x2, T& x3, - T& x4, T& x5, T& x6, T& x7) - { - x0 = load_be(in, 0); - x1 = load_be(in, 1); - x2 = load_be(in, 2); - x3 = load_be(in, 3); - x4 = load_be(in, 4); - x5 = load_be(in, 5); - x6 = load_be(in, 6); - x7 = load_be(in, 7); - } - -/** -* Load a variable number of big-endian words -* @param out the output array of words -* @param in the input array of bytes -* @param count how many words are in in -*/ -template -inline void load_be(T out[], - const byte in[], - size_t count) - { -#if defined(BOTAN_TARGET_CPU_HAS_KNOWN_ENDIANNESS) - std::memcpy(out, in, sizeof(T)*count); - -#if defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN) - const size_t blocks = count - (count % 4); - const size_t left = count - blocks; - - for(size_t i = 0; i != blocks; i += 4) - bswap_4(out + i); - - for(size_t i = 0; i != left; ++i) - out[blocks+i] = reverse_bytes(out[blocks+i]); -#endif - -#else - for(size_t i = 0; i != count; ++i) - out[i] = load_be(in, i); -#endif - } - -/** -* Store a big-endian u16bit -* @param in the input u16bit -* @param out the byte array to write to -*/ -inline void store_be(u16bit in, byte out[2]) - { -#if BOTAN_TARGET_UNALIGNED_MEMORY_ACCESS_OK - *reinterpret_cast(out) = BOTAN_ENDIAN_B2N(in); -#else - out[0] = get_byte(0, in); - out[1] = get_byte(1, in); -#endif - } - -/** -* Store a little-endian u16bit -* @param in the input u16bit -* @param out the byte array to write to -*/ -inline void store_le(u16bit in, byte out[2]) - { -#if BOTAN_TARGET_UNALIGNED_MEMORY_ACCESS_OK - *reinterpret_cast(out) = BOTAN_ENDIAN_L2N(in); -#else - out[0] = get_byte(1, in); - out[1] = get_byte(0, in); -#endif - } - -/** -* Store a big-endian u32bit -* @param in the input u32bit -* @param out the byte array to write to -*/ -inline void store_be(u32bit in, byte out[4]) - { -#if BOTAN_TARGET_UNALIGNED_MEMORY_ACCESS_OK - *reinterpret_cast(out) = BOTAN_ENDIAN_B2N(in); -#else - out[0] = get_byte(0, in); - out[1] = get_byte(1, in); - out[2] = get_byte(2, in); - out[3] = get_byte(3, in); -#endif - } - -/** -* Store a little-endian u32bit -* @param in the input u32bit -* @param out the byte array to write to -*/ -inline void store_le(u32bit in, byte out[4]) - { -#if BOTAN_TARGET_UNALIGNED_MEMORY_ACCESS_OK - *reinterpret_cast(out) = BOTAN_ENDIAN_L2N(in); -#else - out[0] = get_byte(3, in); - out[1] = get_byte(2, in); - out[2] = get_byte(1, in); - out[3] = get_byte(0, in); -#endif - } - -/** -* Store a big-endian u64bit -* @param in the input u64bit -* @param out the byte array to write to -*/ -inline void store_be(u64bit in, byte out[8]) - { -#if BOTAN_TARGET_UNALIGNED_MEMORY_ACCESS_OK - *reinterpret_cast(out) = BOTAN_ENDIAN_B2N(in); -#else - out[0] = get_byte(0, in); - out[1] = get_byte(1, in); - out[2] = get_byte(2, in); - out[3] = get_byte(3, in); - out[4] = get_byte(4, in); - out[5] = get_byte(5, in); - out[6] = get_byte(6, in); - out[7] = get_byte(7, in); -#endif - } - -/** -* Store a little-endian u64bit -* @param in the input u64bit -* @param out the byte array to write to -*/ -inline void store_le(u64bit in, byte out[8]) - { -#if BOTAN_TARGET_UNALIGNED_MEMORY_ACCESS_OK - *reinterpret_cast(out) = BOTAN_ENDIAN_L2N(in); -#else - out[0] = get_byte(7, in); - out[1] = get_byte(6, in); - out[2] = get_byte(5, in); - out[3] = get_byte(4, in); - out[4] = get_byte(3, in); - out[5] = get_byte(2, in); - out[6] = get_byte(1, in); - out[7] = get_byte(0, in); -#endif - } - -/** -* Store two little-endian words -* @param out the output byte array -* @param x0 the first word -* @param x1 the second word -*/ -template -inline void store_le(byte out[], T x0, T x1) - { - store_le(x0, out + (0 * sizeof(T))); - store_le(x1, out + (1 * sizeof(T))); - } - -/** -* Store two big-endian words -* @param out the output byte array -* @param x0 the first word -* @param x1 the second word -*/ -template -inline void store_be(byte out[], T x0, T x1) - { - store_be(x0, out + (0 * sizeof(T))); - store_be(x1, out + (1 * sizeof(T))); - } - -/** -* Store four little-endian words -* @param out the output byte array -* @param x0 the first word -* @param x1 the second word -* @param x2 the third word -* @param x3 the fourth word -*/ -template -inline void store_le(byte out[], T x0, T x1, T x2, T x3) - { - store_le(x0, out + (0 * sizeof(T))); - store_le(x1, out + (1 * sizeof(T))); - store_le(x2, out + (2 * sizeof(T))); - store_le(x3, out + (3 * sizeof(T))); - } - -/** -* Store four big-endian words -* @param out the output byte array -* @param x0 the first word -* @param x1 the second word -* @param x2 the third word -* @param x3 the fourth word -*/ -template -inline void store_be(byte out[], T x0, T x1, T x2, T x3) - { - store_be(x0, out + (0 * sizeof(T))); - store_be(x1, out + (1 * sizeof(T))); - store_be(x2, out + (2 * sizeof(T))); - store_be(x3, out + (3 * sizeof(T))); - } - -/** -* Store eight little-endian words -* @param out the output byte array -* @param x0 the first word -* @param x1 the second word -* @param x2 the third word -* @param x3 the fourth word -* @param x4 the fifth word -* @param x5 the sixth word -* @param x6 the seventh word -* @param x7 the eighth word -*/ -template -inline void store_le(byte out[], T x0, T x1, T x2, T x3, - T x4, T x5, T x6, T x7) - { - store_le(x0, out + (0 * sizeof(T))); - store_le(x1, out + (1 * sizeof(T))); - store_le(x2, out + (2 * sizeof(T))); - store_le(x3, out + (3 * sizeof(T))); - store_le(x4, out + (4 * sizeof(T))); - store_le(x5, out + (5 * sizeof(T))); - store_le(x6, out + (6 * sizeof(T))); - store_le(x7, out + (7 * sizeof(T))); - } - -/** -* Store eight big-endian words -* @param out the output byte array -* @param x0 the first word -* @param x1 the second word -* @param x2 the third word -* @param x3 the fourth word -* @param x4 the fifth word -* @param x5 the sixth word -* @param x6 the seventh word -* @param x7 the eighth word -*/ -template -inline void store_be(byte out[], T x0, T x1, T x2, T x3, - T x4, T x5, T x6, T x7) - { - store_be(x0, out + (0 * sizeof(T))); - store_be(x1, out + (1 * sizeof(T))); - store_be(x2, out + (2 * sizeof(T))); - store_be(x3, out + (3 * sizeof(T))); - store_be(x4, out + (4 * sizeof(T))); - store_be(x5, out + (5 * sizeof(T))); - store_be(x6, out + (6 * sizeof(T))); - store_be(x7, out + (7 * sizeof(T))); - } - -} - - -namespace Botan { - -/** -* CBC Encryption -*/ -class BOTAN_DLL CBC_Encryption : public Keyed_Filter, - private Buffered_Filter - { - public: - std::string name() const; - - void set_iv(const InitializationVector& iv); - - void set_key(const SymmetricKey& key) { cipher->set_key(key); } - - bool valid_keylength(size_t key_len) const - { return cipher->valid_keylength(key_len); } - - bool valid_iv_length(size_t iv_len) const - { return (iv_len == cipher->block_size()); } - - CBC_Encryption(BlockCipher* cipher, - BlockCipherModePaddingMethod* padding); - - CBC_Encryption(BlockCipher* cipher, - BlockCipherModePaddingMethod* padding, - const SymmetricKey& key, - const InitializationVector& iv); - - ~CBC_Encryption() { delete cipher; delete padder; } - private: - void buffered_block(const byte input[], size_t input_length); - void buffered_final(const byte input[], size_t input_length); - - void write(const byte input[], size_t input_length); - void end_msg(); - - BlockCipher* cipher; - const BlockCipherModePaddingMethod* padder; - SecureVector state; - }; - -/** -* CBC Decryption -*/ -class BOTAN_DLL CBC_Decryption : public Keyed_Filter, - private Buffered_Filter - { - public: - std::string name() const; - - void set_iv(const InitializationVector& iv); - - void set_key(const SymmetricKey& key) { cipher->set_key(key); } - - bool valid_keylength(size_t key_len) const - { return cipher->valid_keylength(key_len); } - - bool valid_iv_length(size_t iv_len) const - { return (iv_len == cipher->block_size()); } - - CBC_Decryption(BlockCipher* cipher, - BlockCipherModePaddingMethod* padding); - - CBC_Decryption(BlockCipher* cipher, - BlockCipherModePaddingMethod* padding, - const SymmetricKey& key, - const InitializationVector& iv); - - ~CBC_Decryption() { delete cipher; delete padder; } - private: - void buffered_block(const byte input[], size_t input_length); - void buffered_final(const byte input[], size_t input_length); - - void write(const byte[], size_t); - void end_msg(); - - BlockCipher* cipher; - const BlockCipherModePaddingMethod* padder; - SecureVector state, temp; - }; - -} - - -namespace Botan { - -/** -* A class handling runtime CPU feature detection -*/ -class BOTAN_DLL CPUID - { - public: - /** - * Probe the CPU and see what extensions are supported - */ - static void initialize(); - - /** - * Return a best guess of the cache line size - */ - static size_t cache_line_size() { return cache_line; } - - /** - * Check if the processor supports RDTSC - */ - static bool has_rdtsc() - { return x86_processor_flags_has(CPUID_RDTSC_BIT); } - - /** - * Check if the processor supports SSE2 - */ - static bool has_sse2() - { return x86_processor_flags_has(CPUID_SSE2_BIT); } - - /** - * Check if the processor supports SSSE3 - */ - static bool has_ssse3() - { return x86_processor_flags_has(CPUID_SSSE3_BIT); } - - /** - * Check if the processor supports SSE4.1 - */ - static bool has_sse41() - { return x86_processor_flags_has(CPUID_SSE41_BIT); } - - /** - * Check if the processor supports SSE4.2 - */ - static bool has_sse42() - { return x86_processor_flags_has(CPUID_SSE42_BIT); } - - /** - * Check if the processor supports extended AVX vector instructions - */ - static bool has_avx() - { return x86_processor_flags_has(CPUID_AVX_BIT); } - - /** - * Check if the processor supports AES-NI - */ - static bool has_aes_ni() - { return x86_processor_flags_has(CPUID_AESNI_BIT); } - - /** - * Check if the processor supports PCMULUDQ - */ - static bool has_pcmuludq() - { return x86_processor_flags_has(CPUID_PCMUL_BIT); } - - /** - * Check if the processor supports MOVBE - */ - static bool has_movbe() - { return x86_processor_flags_has(CPUID_MOVBE_BIT); } - - /** - * Check if the processor supports RDRAND - */ - static bool has_rdrand() - { return x86_processor_flags_has(CPUID_RDRAND_BIT); } - - /** - * Check if the processor supports AltiVec/VMX - */ - static bool has_altivec() { return altivec_capable; } - private: - enum CPUID_bits { - CPUID_RDTSC_BIT = 4, - CPUID_SSE2_BIT = 26, - CPUID_PCMUL_BIT = 33, - CPUID_SSSE3_BIT = 41, - CPUID_SSE41_BIT = 51, - CPUID_SSE42_BIT = 52, - CPUID_MOVBE_BIT = 54, - CPUID_AESNI_BIT = 57, - CPUID_AVX_BIT = 60, - CPUID_RDRAND_BIT = 62 - }; - - static bool x86_processor_flags_has(u64bit bit) - { - return ((x86_processor_flags >> bit) & 1); - } - - static u64bit x86_processor_flags; - static size_t cache_line; - static bool altivec_capable; - }; - -} - - -namespace Botan { - -/** -* Serpent implementation using SIMD -*/ -class BOTAN_DLL Serpent_SIMD : public Serpent - { - public: - size_t parallelism() const { return 4; } - - void encrypt_n(const byte in[], byte out[], size_t blocks) const; - void decrypt_n(const byte in[], byte out[], size_t blocks) const; - - BlockCipher* clone() const { return new Serpent_SIMD; } - }; - -} - - -namespace Botan { - -/** -* PK_Encryptor Filter -*/ -class BOTAN_DLL PK_Encryptor_Filter : public Filter - { - public: - void write(const byte[], size_t); - void end_msg(); - PK_Encryptor_Filter(PK_Encryptor* c, - RandomNumberGenerator& rng_ref) : - cipher(c), rng(rng_ref) {} - ~PK_Encryptor_Filter() { delete cipher; } - private: - PK_Encryptor* cipher; - RandomNumberGenerator& rng; - SecureVector buffer; - }; - -/** -* PK_Decryptor Filter -*/ -class BOTAN_DLL PK_Decryptor_Filter : public Filter - { - public: - void write(const byte[], size_t); - void end_msg(); - PK_Decryptor_Filter(PK_Decryptor* c) : cipher(c) {} - ~PK_Decryptor_Filter() { delete cipher; } - private: - PK_Decryptor* cipher; - SecureVector buffer; - }; - -/** -* PK_Signer Filter -*/ -class BOTAN_DLL PK_Signer_Filter : public Filter - { - public: - void write(const byte[], size_t); - void end_msg(); - - PK_Signer_Filter(PK_Signer* s, - RandomNumberGenerator& rng_ref) : - signer(s), rng(rng_ref) {} - - ~PK_Signer_Filter() { delete signer; } - private: - PK_Signer* signer; - RandomNumberGenerator& rng; - }; - -/** -* PK_Verifier Filter -*/ -class BOTAN_DLL PK_Verifier_Filter : public Filter - { - public: - void write(const byte[], size_t); - void end_msg(); - - void set_signature(const byte[], size_t); - void set_signature(const MemoryRegion&); - - PK_Verifier_Filter(PK_Verifier* v) : verifier(v) {} - PK_Verifier_Filter(PK_Verifier*, const byte[], size_t); - PK_Verifier_Filter(PK_Verifier*, const MemoryRegion&); - ~PK_Verifier_Filter() { delete verifier; } - private: - PK_Verifier* verifier; - SecureVector signature; - }; - -} - - -namespace Botan { - -/** -* XTEA implemented using SIMD operations -*/ -class BOTAN_DLL XTEA_SIMD : public XTEA - { - public: - size_t parallelism() const { return 8; } - - void encrypt_n(const byte in[], byte out[], size_t blocks) const; - void decrypt_n(const byte in[], byte out[], size_t blocks) const; - BlockCipher* clone() const { return new XTEA_SIMD; } - }; - -} - - -namespace Botan { - -/** -* A queue that knows how to zeroize itself -*/ -class BOTAN_DLL SecureQueue : public Fanout_Filter, public DataSource - { - public: - std::string name() const { return "Queue"; } - - void write(const byte[], size_t); - - size_t read(byte[], size_t); - size_t peek(byte[], size_t, size_t = 0) const; - - bool end_of_data() const; - - /** - * @return number of bytes available in the queue - */ - size_t size() const; - - bool attachable() { return false; } - - /** - * SecureQueue assignment - * @param other the queue to copy - */ - SecureQueue& operator=(const SecureQueue& other); - - /** - * SecureQueue default constructor (creates empty queue) - */ - SecureQueue(); - - /** - * SecureQueue copy constructor - * @param other the queue to copy - */ - SecureQueue(const SecureQueue& other); - - ~SecureQueue() { destroy(); } - private: - void destroy(); - class SecureQueueNode* head; - class SecureQueueNode* tail; - }; - -} - - -namespace Botan { - -/** -* HMAC -*/ -class BOTAN_DLL HMAC : public MessageAuthenticationCode - { - public: - void clear(); - std::string name() const; - MessageAuthenticationCode* clone() const; - - size_t output_length() const { return hash->output_length(); } - - Key_Length_Specification key_spec() const - { - return Key_Length_Specification(0, 2*hash->hash_block_size()); - } - - /** - * @param hash the hash to use for HMACing - */ - HMAC(HashFunction* hash); - ~HMAC() { delete hash; } - private: - void add_data(const byte[], size_t); - void final_result(byte[]); - void key_schedule(const byte[], size_t); - - HashFunction* hash; - SecureVector i_key, o_key; - }; - -} - - -namespace Botan { - -/** -* OpenPGP's S2K -*/ -class BOTAN_DLL OpenPGP_S2K : public PBKDF - { - public: - /** - * @param hash_in the hash function to use - */ - OpenPGP_S2K(HashFunction* hash_in) : hash(hash_in) {} - - ~OpenPGP_S2K() { delete hash; } - - std::string name() const - { - return "OpenPGP-S2K(" + hash->name() + ")"; - } - - PBKDF* clone() const - { - return new OpenPGP_S2K(hash->clone()); - } - - OctetString derive_key(size_t output_len, - const std::string& passphrase, - const byte salt[], size_t salt_len, - size_t iterations) const; - private: - HashFunction* hash; - }; - -} - - -namespace Botan { - -/** -* Lion is a block cipher construction designed by Ross Anderson and -* Eli Biham, described in "Two Practical and Provably Secure Block -* Ciphers: BEAR and LION". It has a variable block size and is -* designed to encrypt very large blocks (up to a megabyte) - -* http://www.cl.cam.ac.uk/~rja14/Papers/bear-lion.pdf -*/ -class BOTAN_DLL Lion : public BlockCipher - { - public: - void encrypt_n(const byte in[], byte out[], size_t blocks) const; - void decrypt_n(const byte in[], byte out[], size_t blocks) const; - - size_t block_size() const { return BLOCK_SIZE; } - - Key_Length_Specification key_spec() const - { - return Key_Length_Specification(2, 2*hash->output_length(), 2); - } - - void clear(); - std::string name() const; - BlockCipher* clone() const; - - /** - * @param hash the hash to use internally - * @param cipher the stream cipher to use internally - * @param block_size the size of the block to use - */ - Lion(HashFunction* hash, - StreamCipher* cipher, - size_t block_size); - - ~Lion() { delete hash; delete cipher; } - private: - void key_schedule(const byte[], size_t); - - const size_t BLOCK_SIZE, LEFT_SIZE, RIGHT_SIZE; - - HashFunction* hash; - StreamCipher* cipher; - SecureVector key1, key2; - }; - -} - - -namespace Botan { - -/** -* Skipjack, a NSA designed cipher used in Fortezza -*/ -class BOTAN_DLL Skipjack : public Block_Cipher_Fixed_Params<8, 10> - { - public: - void encrypt_n(const byte in[], byte out[], size_t blocks) const; - void decrypt_n(const byte in[], byte out[], size_t blocks) const; - - void clear(); - std::string name() const { return "Skipjack"; } - BlockCipher* clone() const { return new Skipjack; } - - Skipjack() : FTAB(2560) {} - private: - void key_schedule(const byte[], size_t); - - SecureVector FTAB; - }; - -} - - -namespace Botan { - -namespace FPE { - -/** -* Encrypt X from and onto the group Z_n using key and tweak -* @param n the modulus -* @param X the plaintext as a BigInt -* @param key a random key -* @param tweak will modify the ciphertext (think of as an IV) -*/ -BigInt BOTAN_DLL fe1_encrypt(const BigInt& n, const BigInt& X, - const SymmetricKey& key, - const MemoryRegion& tweak); - -/** -* Decrypt X from and onto the group Z_n using key and tweak -* @param n the modulus -* @param X the ciphertext as a BigInt -* @param key is the key used for encryption -* @param tweak the same tweak used for encryption -*/ -BigInt BOTAN_DLL fe1_decrypt(const BigInt& n, const BigInt& X, - const SymmetricKey& key, - const MemoryRegion& tweak); - -} - -} - - -namespace Botan { - -/** -* This class represents ECDH Public Keys. -*/ -class BOTAN_DLL ECDH_PublicKey : public virtual EC_PublicKey - { - public: - - ECDH_PublicKey(const AlgorithmIdentifier& alg_id, - const MemoryRegion& key_bits) : - EC_PublicKey(alg_id, key_bits) {} - - /** - * Construct a public key from a given public point. - * @param dom_par the domain parameters associated with this key - * @param public_point the public point defining this key - */ - ECDH_PublicKey(const EC_Group& dom_par, - const PointGFp& public_point) : - EC_PublicKey(dom_par, public_point) {} - - /** - * Get this keys algorithm name. - * @return this keys algorithm name - */ - std::string algo_name() const { return "ECDH"; } - - /** - * Get the maximum number of bits allowed to be fed to this key. - * This is the bitlength of the order of the base point. - - * @return maximum number of input bits - */ - size_t max_input_bits() const { return domain().get_order().bits(); } - - /** - * @return public point value - */ - MemoryVector public_value() const - { return EC2OSP(public_point(), PointGFp::UNCOMPRESSED); } - - protected: - ECDH_PublicKey() {} - }; - -/** -* This class represents ECDH Private Keys. -*/ -class BOTAN_DLL ECDH_PrivateKey : public ECDH_PublicKey, - public EC_PrivateKey, - public PK_Key_Agreement_Key - { - public: - - ECDH_PrivateKey(const AlgorithmIdentifier& alg_id, - const MemoryRegion& key_bits) : - EC_PrivateKey(alg_id, key_bits) {} - - /** - * Generate a new private key - * @param rng a random number generator - * @param domain parameters to used for this key - * @param x the private key; if zero, a new random key is generated - */ - ECDH_PrivateKey(RandomNumberGenerator& rng, - const EC_Group& domain, - const BigInt& x = 0) : - EC_PrivateKey(rng, domain, x) {} - - MemoryVector public_value() const - { return ECDH_PublicKey::public_value(); } - }; - -/** -* ECDH operation -*/ -class BOTAN_DLL ECDH_KA_Operation : public PK_Ops::Key_Agreement - { - public: - ECDH_KA_Operation(const ECDH_PrivateKey& key); - - SecureVector agree(const byte w[], size_t w_len); - private: - const CurveGFp& curve; - const BigInt& cofactor; - BigInt l_times_priv; - }; - -} - - -namespace Botan { - -/** -* AES-128 -*/ -class BOTAN_DLL AES_128 : public Block_Cipher_Fixed_Params<16, 16> - { - public: - AES_128() : EK(40), DK(40), ME(16), MD(16) {} - - void encrypt_n(const byte in[], byte out[], size_t blocks) const; - void decrypt_n(const byte in[], byte out[], size_t blocks) const; - - void clear(); - - std::string name() const { return "AES-128"; } - BlockCipher* clone() const { return new AES_128; } - private: - void key_schedule(const byte key[], size_t length); - - SecureVector EK, DK; - SecureVector ME, MD; - }; - -/** -* AES-192 -*/ -class BOTAN_DLL AES_192 : public Block_Cipher_Fixed_Params<16, 24> - { - public: - AES_192() : EK(48), DK(48), ME(16), MD(16) {} - - void encrypt_n(const byte in[], byte out[], size_t blocks) const; - void decrypt_n(const byte in[], byte out[], size_t blocks) const; - - void clear(); - - std::string name() const { return "AES-192"; } - BlockCipher* clone() const { return new AES_192; } - private: - void key_schedule(const byte key[], size_t length); - - SecureVector EK, DK; - SecureVector ME, MD; - }; - -/** -* AES-256 -*/ -class BOTAN_DLL AES_256 : public Block_Cipher_Fixed_Params<16, 32> - { - public: - AES_256() : EK(56), DK(56), ME(16), MD(16) {} - - void encrypt_n(const byte in[], byte out[], size_t blocks) const; - void decrypt_n(const byte in[], byte out[], size_t blocks) const; - - void clear(); - - std::string name() const { return "AES-256"; } - BlockCipher* clone() const { return new AES_256; } - private: - void key_schedule(const byte key[], size_t length); - - SecureVector EK, DK; - SecureVector ME, MD; - }; - -} - - -namespace Botan { - -/** -* Rivest's Package Tranform -* @param rng the random number generator to use -* @param cipher the block cipher to use -* @param input the input data buffer -* @param input_len the length of the input data in bytes -* @param output the output data buffer (must be at least -* input_len + cipher->BLOCK_SIZE bytes long) -*/ -void BOTAN_DLL aont_package(RandomNumberGenerator& rng, - BlockCipher* cipher, - const byte input[], size_t input_len, - byte output[]); - -/** -* Rivest's Package Tranform (Inversion) -* @param cipher the block cipher to use -* @param input the input data buffer -* @param input_len the length of the input data in bytes -* @param output the output data buffer (must be at least -* input_len - cipher->BLOCK_SIZE bytes long) -*/ -void BOTAN_DLL aont_unpackage(BlockCipher* cipher, - const byte input[], size_t input_len, - byte output[]); - -} - - -namespace Botan { - -/** -* Combines two hash functions using a Feistel scheme. Described in -* "On the Security of Hash Function Combiners", Anja Lehmann -*/ -class BOTAN_DLL Comb4P : public HashFunction - { - public: - /** - * @param h1 the first hash - * @param h2 the second hash - */ - Comb4P(HashFunction* h1, HashFunction* h2); - - ~Comb4P() { delete hash1; delete hash2; } - - size_t hash_block_size() const; - - size_t output_length() const - { - return hash1->output_length() + hash2->output_length(); - } - - HashFunction* clone() const - { - return new Comb4P(hash1->clone(), hash2->clone()); - } - - std::string name() const - { - return "Comb4P(" + hash1->name() + "," + hash2->name() + ")"; - } - - void clear(); - private: - void add_data(const byte input[], size_t length); - void final_result(byte out[]); - - HashFunction* hash1; - HashFunction* hash2; - }; - -} - - -namespace Botan { - -/** -* A split secret, using the format from draft-mcgrew-tss-03 -*/ -class BOTAN_DLL RTSS_Share - { - public: - /** - * @param M the number of shares needed to reconstruct - * @param N the number of shares generated - * @param secret the secret to split - * @param secret_len the length of the secret - * @param identifier the 16 byte share identifier - * @param rng the random number generator to use - */ - static std::vector - split(byte M, byte N, - const byte secret[], u16bit secret_len, - const byte identifier[16], - RandomNumberGenerator& rng); - - /** - * @param shares the list of shares - */ - static SecureVector - reconstruct(const std::vector& shares); - - RTSS_Share() {} - - /** - * @param hex_input the share encoded in hexadecimal - */ - RTSS_Share(const std::string& hex_input); - - /** - * @return hex representation - */ - std::string to_string() const; - - /** - * @return share identifier - */ - byte share_id() const; - - /** - * @return size of this share in bytes - */ - size_t size() const { return contents.size(); } - - /** - * @return if this TSS share was initialized or not - */ - bool initialized() const { return (contents.size() > 0); } - private: - SecureVector contents; - }; - -} - - -namespace Botan { - -/** -* RC2 -*/ -class BOTAN_DLL RC2 : public Block_Cipher_Fixed_Params<8, 1, 32> - { - public: - void encrypt_n(const byte in[], byte out[], size_t blocks) const; - void decrypt_n(const byte in[], byte out[], size_t blocks) const; - - /** - * Return the code of the effective key bits - * @param bits key length - * @return EKB code - */ - static byte EKB_code(size_t bits); - - void clear() { zeroise(K); } - std::string name() const { return "RC2"; } - BlockCipher* clone() const { return new RC2; } - - RC2() : K(64) {} - private: - void key_schedule(const byte[], size_t); - - SecureVector K; - }; - -} - - -namespace Botan { - -/** -* DJB's Salsa20 (and XSalsa20) -*/ -class BOTAN_DLL Salsa20 : public StreamCipher - { - public: - void cipher(const byte in[], byte out[], size_t length); - - void set_iv(const byte iv[], size_t iv_len); - - bool valid_iv_length(size_t iv_len) const - { return (iv_len == 8 || iv_len == 24); } - - Key_Length_Specification key_spec() const - { - return Key_Length_Specification(16, 32, 16); - } - - void clear(); - std::string name() const; - StreamCipher* clone() const { return new Salsa20; } - - Salsa20() : state(16), buffer(64), position(0) {} - private: - void key_schedule(const byte key[], size_t key_len); - - SecureVector state; - SecureVector buffer; - size_t position; - }; - -} - - -namespace Botan { - -/** -* RIPEMD-128 -*/ -class BOTAN_DLL RIPEMD_128 : public MDx_HashFunction - { - public: - std::string name() const { return "RIPEMD-128"; } - size_t output_length() const { return 16; } - HashFunction* clone() const { return new RIPEMD_128; } - - void clear(); - - RIPEMD_128() : MDx_HashFunction(64, false, true), M(16), digest(4) - { clear(); } - private: - void compress_n(const byte[], size_t blocks); - void copy_out(byte[]); - - SecureVector M, digest; - }; - -} - - -namespace Botan { - -/** -* 24-bit cyclic redundancy check -*/ -class BOTAN_DLL CRC24 : public HashFunction - { - public: - std::string name() const { return "CRC24"; } - size_t output_length() const { return 3; } - HashFunction* clone() const { return new CRC24; } - - void clear() { crc = 0xB704CE; } - - CRC24() { clear(); } - ~CRC24() { clear(); } - private: - void add_data(const byte[], size_t); - void final_result(byte[]); - u32bit crc; - }; - -} - - -namespace Botan { - -/** -* PKCS #5 v1 PBKDF, aka PBKDF1 -* Can only generate a key up to the size of the hash output. -* Unless needed for backwards compatability, use PKCS5_PBKDF2 -*/ -class BOTAN_DLL PKCS5_PBKDF1 : public PBKDF - { - public: - /** - * Create a PKCS #5 instance using the specified hash function. - * @param hash_in pointer to a hash function object to use - */ - PKCS5_PBKDF1(HashFunction* hash_in) : hash(hash_in) {} - - /** - * Copy constructor - * @param other the object to copy - */ - PKCS5_PBKDF1(const PKCS5_PBKDF1& other) : - PBKDF(), hash(other.hash->clone()) {} - - ~PKCS5_PBKDF1() { delete hash; } - - std::string name() const - { - return "PBKDF1(" + hash->name() + ")"; - } - - PBKDF* clone() const - { - return new PKCS5_PBKDF1(hash->clone()); - } - - OctetString derive_key(size_t output_len, - const std::string& passphrase, - const byte salt[], size_t salt_len, - size_t iterations) const; - private: - HashFunction* hash; - }; - -} - - -namespace Botan { - -/** -* This class represents X.509 Certificate Authorities (CAs). -*/ -class BOTAN_DLL X509_CA - { - public: - - /** - * Sign a PKCS#10 Request. - * @param req the request to sign - * @param rng the rng to use - * @param not_before the starting time for the certificate - * @param not_after the expiration time for the certificate - * @return resulting certificate - */ - X509_Certificate sign_request(const PKCS10_Request& req, - RandomNumberGenerator& rng, - const X509_Time& not_before, - const X509_Time& not_after); - - /** - * Get the certificate of this CA. - * @return CA certificate - */ - X509_Certificate ca_certificate() const; - - /** - * Create a new and empty CRL for this CA. - * @param rng the random number generator to use - * @param next_update the time to set in next update in seconds - * as the offset from the current time - * @return new CRL - */ - X509_CRL new_crl(RandomNumberGenerator& rng, - u32bit next_update = 0) const; - - /** - * Create a new CRL by with additional entries. - * @param last_crl the last CRL of this CA to add the new entries to - * @param new_entries contains the new CRL entries to be added to the CRL - * @param rng the random number generator to use - * @param next_update the time to set in next update in seconds - * as the offset from the current time - */ - X509_CRL update_crl(const X509_CRL& last_crl, - const std::vector& new_entries, - RandomNumberGenerator& rng, - u32bit next_update = 0) const; - - /** - * Interface for creating new certificates - * @param signer a signing object - * @param rng a random number generator - * @param sig_algo the signature algorithm identifier - * @param pub_key the serialized public key - * @param not_before the start time of the certificate - * @param not_after the end time of the certificate - * @param issuer_dn the DN of the issuer - * @param subject_dn the DN of the subject - * @param extensions an optional list of certificate extensions - * @returns newly minted certificate - */ - static X509_Certificate make_cert(PK_Signer* signer, - RandomNumberGenerator& rng, - const AlgorithmIdentifier& sig_algo, - const MemoryRegion& pub_key, - const X509_Time& not_before, - const X509_Time& not_after, - const X509_DN& issuer_dn, - const X509_DN& subject_dn, - const Extensions& extensions); - - /** - * Create a new CA object. - * @param ca_certificate the certificate of the CA - * @param key the private key of the CA - * @param hash_fn name of a hash function to use for signing - */ - X509_CA(const X509_Certificate& ca_certificate, - const Private_Key& key, - const std::string& hash_fn); - - ~X509_CA(); - private: - X509_CA(const X509_CA&) {} - X509_CA& operator=(const X509_CA&) { return (*this); } - - X509_CRL make_crl(const std::vector& entries, - u32bit crl_number, u32bit next_update, - RandomNumberGenerator& rng) const; - - AlgorithmIdentifier ca_sig_algo; - X509_Certificate cert; - PK_Signer* signer; - }; - -/** -* Choose the default signature format for a certain public key signature -* scheme. -* @param key will be the key to choose a padding scheme for -* @param hash_fn is the desired hash function -* @param alg_id will be set to the chosen scheme -* @return A PK_Signer object for generating signatures -*/ -BOTAN_DLL PK_Signer* choose_sig_format(const Private_Key& key, - const std::string& hash_fn, - AlgorithmIdentifier& alg_id); - -} - - -namespace Botan { - -namespace OIDS { - -/** -* Register an OID to string mapping. -* @param oid the oid to register -* @param name the name to be associated with the oid -*/ -BOTAN_DLL void add_oid(const OID& oid, const std::string& name); - -/** -* See if an OID exists in the internal table. -* @param oid the oid to check for -* @return true if the oid is registered -*/ -BOTAN_DLL bool have_oid(const std::string& oid); - -/** -* Resolve an OID -* @param oid the OID to look up -* @return name associated with this OID -*/ -BOTAN_DLL std::string lookup(const OID& oid); - -/** -* Find the OID to a name. The lookup will be performed in the -* general OID section of the configuration. -* @param name the name to resolve -* @return OID associated with the specified name -*/ -BOTAN_DLL OID lookup(const std::string& name); - -/** -* Tests whether the specified OID stands for the specified name. -* @param oid the OID to check -* @param name the name to check -* @return true if the specified OID stands for the specified name -*/ -BOTAN_DLL bool name_of(const OID& oid, const std::string& name); - -} - -} - - -namespace Botan { - -/** -* EAX Base Class -*/ -class BOTAN_DLL EAX_Base : public Keyed_Filter - { - public: - void set_key(const SymmetricKey& key); - void set_iv(const InitializationVector& iv); - - /** - * Set some additional data that is not included in the - * ciphertext but that will be authenticated. - * @param header the header contents - * @param header_len length of header in bytes - */ - void set_header(const byte header[], size_t header_len); - - /** - * @return name of this mode - */ - std::string name() const; - - bool valid_keylength(size_t key_len) const; - - /** - * EAX supports arbitrary IV lengths - */ - bool valid_iv_length(size_t) const { return true; } - - ~EAX_Base() { delete ctr; delete cmac; } - protected: - /** - * @param cipher the cipher to use - * @param tag_size is how big the auth tag will be - */ - EAX_Base(BlockCipher* cipher, size_t tag_size); - void start_msg(); - - /** - * The block size of the underlying cipher - */ - const size_t BLOCK_SIZE; - - /** - * The requested tag name - */ - const size_t TAG_SIZE; - - /** - * The name of the cipher - */ - std::string cipher_name; - - /** - * The stream cipher (CTR mode) - */ - StreamCipher* ctr; - - /** - * The MAC (CMAC) - */ - MessageAuthenticationCode* cmac; - - /** - * The MAC of the nonce - */ - SecureVector nonce_mac; - - /** - * The MAC of the header - */ - SecureVector header_mac; - - /** - * A buffer for CTR mode encryption - */ - SecureVector ctr_buf; - }; - -/** -* EAX Encryption -*/ -class BOTAN_DLL EAX_Encryption : public EAX_Base - { - public: - /** - * @param ciph the cipher to use - * @param tag_size is how big the auth tag will be - */ - EAX_Encryption(BlockCipher* ciph, size_t tag_size = 0) : - EAX_Base(ciph, tag_size) {} - - /** - * @param ciph the cipher to use - * @param key the key to use - * @param iv the initially set IV - * @param tag_size is how big the auth tag will be - */ - EAX_Encryption(BlockCipher* ciph, const SymmetricKey& key, - const InitializationVector& iv, - size_t tag_size) : EAX_Base(ciph, tag_size) - { - set_key(key); - set_iv(iv); - } - private: - void write(const byte[], size_t); - void end_msg(); - }; - -/** -* EAX Decryption -*/ -class BOTAN_DLL EAX_Decryption : public EAX_Base - { - public: - /** - * @param ciph the cipher to use - * @param tag_size is how big the auth tag will be - */ - EAX_Decryption(BlockCipher* ciph, size_t tag_size = 0); - - /** - * @param ciph the cipher to use - * @param key the key to use - * @param iv the initially set IV - * @param tag_size is how big the auth tag will be - */ - EAX_Decryption(BlockCipher* ciph, const SymmetricKey& key, - const InitializationVector& iv, - size_t tag_size = 0); - private: - void write(const byte[], size_t); - void do_write(const byte[], size_t); - void end_msg(); - - SecureVector queue; - size_t queue_start, queue_end; - }; - -} - - -namespace Botan { - -/** -* CMAC, also known as OMAC1 -*/ -class BOTAN_DLL CMAC : public MessageAuthenticationCode - { - public: - std::string name() const; - size_t output_length() const { return e->block_size(); } - MessageAuthenticationCode* clone() const; - - void clear(); - - Key_Length_Specification key_spec() const - { - return e->key_spec(); - } - - /** - * CMAC's polynomial doubling operation - * @param in the input - * @param polynomial the byte value of the polynomial - */ - static SecureVector poly_double(const MemoryRegion& in, - byte polynomial); - - /** - * @param cipher the underlying block cipher to use - */ - CMAC(BlockCipher* cipher); - ~CMAC(); - private: - void add_data(const byte[], size_t); - void final_result(byte[]); - void key_schedule(const byte[], size_t); - - BlockCipher* e; - SecureVector buffer, state, B, P; - size_t position; - byte polynomial; - }; - -} - - -namespace Botan { - -/** -* Skein-512, a SHA-3 candidate -*/ -class BOTAN_DLL Skein_512 : public HashFunction - { - public: - /** - * @param output_bits the output size of Skein in bits - * @param personalization is a string that will paramaterize the - * hash output - */ - Skein_512(size_t output_bits = 512, - const std::string& personalization = ""); - - size_t hash_block_size() const { return 64; } - size_t output_length() const { return output_bits / 8; } - - HashFunction* clone() const; - std::string name() const; - void clear(); - private: - void add_data(const byte input[], size_t length); - void final_result(byte out[]); - - std::string personalization; - size_t output_bits; - - SecureVector H; - SecureVector T; - SecureVector buffer; - size_t buf_pos; - }; - -} - - -namespace Botan { - -/** -* CBC encryption with ciphertext stealing -*/ -class BOTAN_DLL CTS_Encryption : public Keyed_Filter - { - public: - std::string name() const { return cipher->name() + "/CTS"; } - - void set_iv(const InitializationVector&); - - void set_key(const SymmetricKey& key) { cipher->set_key(key); } - - bool valid_keylength(size_t key_len) const - { return cipher->valid_keylength(key_len); } - - bool valid_iv_length(size_t iv_len) const - { return (iv_len == cipher->block_size()); } - - CTS_Encryption(BlockCipher* cipher); - - CTS_Encryption(BlockCipher* cipher, - const SymmetricKey& key, - const InitializationVector& iv); - - ~CTS_Encryption() { delete cipher; } - private: - void write(const byte[], size_t); - void end_msg(); - void encrypt(const byte[]); - - BlockCipher* cipher; - SecureVector buffer, state; - size_t position; - }; - -/** -* CBC decryption with ciphertext stealing -*/ -class BOTAN_DLL CTS_Decryption : public Keyed_Filter - { - public: - std::string name() const { return cipher->name() + "/CTS"; } - - void set_iv(const InitializationVector&); - - void set_key(const SymmetricKey& key) { cipher->set_key(key); } - - bool valid_keylength(size_t key_len) const - { return cipher->valid_keylength(key_len); } - - bool valid_iv_length(size_t iv_len) const - { return (iv_len == cipher->block_size()); } - - CTS_Decryption(BlockCipher* cipher); - - CTS_Decryption(BlockCipher* cipher, - const SymmetricKey& key, - const InitializationVector& iv); - - ~CTS_Decryption() { delete cipher; } - private: - void write(const byte[], size_t); - void end_msg(); - void decrypt(const byte[]); - - BlockCipher* cipher; - SecureVector buffer, state, temp; - size_t position; - }; - -} - - -namespace Botan { - -/** -* Factory function for PBEs. -* @param algo_spec the name of the PBE algorithm to retrieve -* @return pointer to a PBE with randomly created parameters -*/ -BOTAN_DLL PBE* get_pbe(const std::string& algo_spec); - -/** -* Factory function for PBEs. -* @param pbe_oid the oid of the desired PBE -* @param params a DataSource providing the DER encoded parameters to use -* @return pointer to the PBE with the specified parameters -*/ -BOTAN_DLL PBE* get_pbe(const OID& pbe_oid, - DataSource& params); - -} - - -namespace Botan { - -/** -* Public key encryptor factory method. -* @deprecated Instantiate object from pubkey.h directly -* -* @param key the key that will work inside the encryptor -* @param eme determines the algorithm and encoding -* @return public key encryptor object -*/ -BOTAN_DEPRECATED("Instantiate object directly") -inline PK_Encryptor* get_pk_encryptor(const Public_Key& key, - const std::string& eme) - { - return new PK_Encryptor_EME(key, eme); - } - -/** -* Public key decryptor factory method. -* @deprecated Instantiate object from pubkey.h directly -* -* @param key the key that will work inside the decryptor -* @param eme determines the algorithm and encoding -* @return public key decryptor object -*/ -BOTAN_DEPRECATED("Instantiate object directly") -inline PK_Decryptor* get_pk_decryptor(const Private_Key& key, - const std::string& eme) - { - return new PK_Decryptor_EME(key, eme); - } - -/** -* Public key signer factory method. -* @deprecated Instantiate object from pubkey.h directly -* -* @param key the key that will work inside the signer -* @param emsa determines the algorithm, encoding and hash algorithm -* @param sig_format the signature format to be used -* @return public key signer object -*/ -BOTAN_DEPRECATED("Instantiate object directly") -inline PK_Signer* get_pk_signer(const Private_Key& key, - const std::string& emsa, - Signature_Format sig_format = IEEE_1363) - { - return new PK_Signer(key, emsa, sig_format); - } - -/** -* Public key verifier factory method. -* @deprecated Instantiate object from pubkey.h directly -* -* @param key the key that will work inside the verifier -* @param emsa determines the algorithm, encoding and hash algorithm -* @param sig_format the signature format to be used -* @return public key verifier object -*/ -BOTAN_DEPRECATED("Instantiate object directly") -inline PK_Verifier* get_pk_verifier(const Public_Key& key, - const std::string& emsa, - Signature_Format sig_format = IEEE_1363) - { - return new PK_Verifier(key, emsa, sig_format); - } - -/** -* Public key key agreement factory method. -* @deprecated Instantiate object from pubkey.h directly -* -* @param key the key that will work inside the key agreement -* @param kdf the kdf algorithm to use -* @return key agreement algorithm -*/ -BOTAN_DEPRECATED("Instantiate object directly") -inline PK_Key_Agreement* get_pk_kas(const PK_Key_Agreement_Key& key, - const std::string& kdf) - { - return new PK_Key_Agreement(key, kdf); - } - -} - - -namespace Botan { - -/** -* IDEA -*/ -class BOTAN_DLL IDEA : public Block_Cipher_Fixed_Params<8, 16> - { - public: - void encrypt_n(const byte in[], byte out[], size_t blocks) const; - void decrypt_n(const byte in[], byte out[], size_t blocks) const; - - void clear() { zeroise(EK); zeroise(DK); } - std::string name() const { return "IDEA"; } - BlockCipher* clone() const { return new IDEA; } - - IDEA() : EK(52), DK(52) {} - protected: - /** - * @return const reference to encryption subkeys - */ - const SecureVector& get_EK() const { return EK; } - - /** - * @return const reference to decryption subkeys - */ - const SecureVector& get_DK() const { return DK; } - - private: - void key_schedule(const byte[], size_t); - SecureVector EK, DK; - }; - -} - - -namespace Botan { - -/** -* Return the PKCS #1 hash identifier -* @see RFC 3447 section 9.2 -* @param hash_name the name of the hash function -* @return byte sequence identifying the hash -* @throw Invalid_Argument if the hash has no known PKCS #1 hash id -*/ -BOTAN_DLL MemoryVector pkcs_hash_id(const std::string& hash_name); - -/** -* Return the IEEE 1363 hash identifier -* @param hash_name the name of the hash function -* @return byte code identifying the hash, or 0 if not known -*/ -BOTAN_DLL byte ieee1363_hash_id(const std::string& hash_name); - -} - - -namespace Botan { - -/** -* MGF1 from PKCS #1 v2.0 -*/ -class BOTAN_DLL MGF1 : public MGF - { - public: - void mask(const byte[], size_t, byte[], size_t) const; - - /** - MGF1 constructor: takes ownership of hash - */ - MGF1(HashFunction* hash); - - ~MGF1(); - private: - HashFunction* hash; - }; - -} - - -namespace Botan { - -/** -* IEEE P1619 XTS Encryption -*/ -class BOTAN_DLL XTS_Encryption : public Keyed_Filter, - private Buffered_Filter - { - public: - void set_key(const SymmetricKey& key); - void set_iv(const InitializationVector& iv); - - bool valid_keylength(size_t key_len) const - { return cipher->valid_keylength(key_len); } - - bool valid_iv_length(size_t iv_len) const - { return (iv_len == cipher->block_size()); } - - std::string name() const; - - XTS_Encryption(BlockCipher* ciph); - - XTS_Encryption(BlockCipher* ciph, - const SymmetricKey& key, - const InitializationVector& iv); - - ~XTS_Encryption() { delete cipher; delete cipher2; } - private: - void write(const byte[], size_t); - void end_msg(); - - void buffered_block(const byte input[], size_t input_length); - void buffered_final(const byte input[], size_t input_length); - - BlockCipher* cipher; - BlockCipher* cipher2; - SecureVector tweak; - }; - -/** -* IEEE P1619 XTS Encryption -*/ -class BOTAN_DLL XTS_Decryption : public Keyed_Filter, - private Buffered_Filter - { - public: - void set_key(const SymmetricKey& key); - void set_iv(const InitializationVector& iv); - - bool valid_keylength(size_t key_len) const - { return cipher->valid_keylength(key_len); } - - bool valid_iv_length(size_t iv_len) const - { return (iv_len == cipher->block_size()); } - - std::string name() const; - - XTS_Decryption(BlockCipher* ciph); - - XTS_Decryption(BlockCipher* ciph, - const SymmetricKey& key, - const InitializationVector& iv); - - ~XTS_Decryption() { delete cipher; delete cipher2; } - private: - void write(const byte[], size_t); - void end_msg(); - - void buffered_block(const byte input[], size_t input_length); - void buffered_final(const byte input[], size_t input_length); - - BlockCipher* cipher; - BlockCipher* cipher2; - SecureVector tweak; - }; - -} - - -namespace Botan { - -/** -* Struct representing a particular date and time -*/ -struct BOTAN_DLL calendar_point - { - /** The year */ - u32bit year; - - /** The month, 1 through 12 for Jan to Dec */ - byte month; - - /** The day of the month, 1 through 31 (or 28 or 30 based on month */ - byte day; - - /** Hour in 24-hour form, 0 to 23 */ - byte hour; - - /** Minutes in the hour, 0 to 60 */ - byte minutes; - - /** Seconds in the minute, 0 to 60, but might be slightly - larger to deal with leap seconds on some systems - */ - byte seconds; - - /** - * Initialize a calendar_point - * @param y the year - * @param mon the month - * @param d the day - * @param h the hour - * @param min the minute - * @param sec the second - */ - calendar_point(u32bit y, byte mon, byte d, byte h, byte min, byte sec) : - year(y), month(mon), day(d), hour(h), minutes(min), seconds(sec) {} - }; - -/** -* @param time_point a time point from the system clock -* @return calendar_point object representing this time point -*/ -BOTAN_DLL calendar_point calendar_value(u64bit time_point); - -/** -* @return seconds resolution timestamp, unknown epoch -*/ -BOTAN_DLL u64bit system_time(); - -/** -* @return nanoseconds resolution timestamp, unknown epoch -*/ -BOTAN_DLL u64bit get_nanoseconds_clock(); - -} - - -namespace Botan { - -/** -* EMSA-Raw - sign inputs directly -* Don't use this unless you know what you are doing. -*/ -class BOTAN_DLL EMSA_Raw : public EMSA - { - private: - void update(const byte[], size_t); - SecureVector raw_data(); - - SecureVector encoding_of(const MemoryRegion&, size_t, - RandomNumberGenerator&); - bool verify(const MemoryRegion&, const MemoryRegion&, - size_t); - - SecureVector message; - }; - -} - - -namespace Botan { - -/** -* Perform base64 encoding -* @param output an array of at least input_length*4/3 bytes -* @param input is some binary data -* @param input_length length of input in bytes -* @param input_consumed is an output parameter which says how many -* bytes of input were actually consumed. If less than -* input_length, then the range input[consumed:length] -* should be passed in later along with more input. -* @param final_inputs true iff this is the last input, in which case - padding chars will be applied if needed -* @return number of bytes written to output -*/ -size_t BOTAN_DLL base64_encode(char output[], - const byte input[], - size_t input_length, - size_t& input_consumed, - bool final_inputs); - -/** -* Perform base64 encoding -* @param input some input -* @param input_length length of input in bytes -* @return base64adecimal representation of input -*/ -std::string BOTAN_DLL base64_encode(const byte input[], - size_t input_length); - -/** -* Perform base64 encoding -* @param input some input -* @return base64adecimal representation of input -*/ -std::string BOTAN_DLL base64_encode(const MemoryRegion& input); - -/** -* Perform base64 decoding -* @param output an array of at least input_length*3/4 bytes -* @param input some base64 input -* @param input_length length of input in bytes -* @param input_consumed is an output parameter which says how many -* bytes of input were actually consumed. If less than -* input_length, then the range input[consumed:length] -* should be passed in later along with more input. -* @param final_inputs true iff this is the last input, in which case - padding is allowed -* @param ignore_ws ignore whitespace on input; if false, throw an - exception if whitespace is encountered -* @return number of bytes written to output -*/ -size_t BOTAN_DLL base64_decode(byte output[], - const char input[], - size_t input_length, - size_t& input_consumed, - bool final_inputs, - bool ignore_ws = true); - -/** -* Perform base64 decoding -* @param output an array of at least input_length*3/4 bytes -* @param input some base64 input -* @param input_length length of input in bytes -* @param ignore_ws ignore whitespace on input; if false, throw an - exception if whitespace is encountered -* @return number of bytes written to output -*/ -size_t BOTAN_DLL base64_decode(byte output[], - const char input[], - size_t input_length, - bool ignore_ws = true); - -/** -* Perform base64 decoding -* @param output an array of at least input_length/3*4 bytes -* @param input some base64 input -* @param ignore_ws ignore whitespace on input; if false, throw an - exception if whitespace is encountered -* @return number of bytes written to output -*/ -size_t BOTAN_DLL base64_decode(byte output[], - const std::string& input, - bool ignore_ws = true); - -/** -* Perform base64 decoding -* @param input some base64 input -* @param input_length the length of input in bytes -* @param ignore_ws ignore whitespace on input; if false, throw an - exception if whitespace is encountered -* @return decoded base64 output -*/ -SecureVector BOTAN_DLL base64_decode(const char input[], - size_t input_length, - bool ignore_ws = true); - -/** -* Perform base64 decoding -* @param input some base64 input -* @param ignore_ws ignore whitespace on input; if false, throw an - exception if whitespace is encountered -* @return decoded base64 output -*/ -SecureVector BOTAN_DLL base64_decode(const std::string& input, - bool ignore_ws = true); - -} - - -namespace Botan { - -/** -* PRF used in TLS 1.0/1.1 -*/ -class BOTAN_DLL TLS_PRF : public KDF - { - public: - SecureVector derive(size_t key_len, - const byte secret[], size_t secret_len, - const byte seed[], size_t seed_len) const; - - std::string name() const { return "TLS-PRF"; } - KDF* clone() const { return new TLS_PRF; } - - TLS_PRF(); - ~TLS_PRF(); - private: - MessageAuthenticationCode* hmac_md5; - MessageAuthenticationCode* hmac_sha1; - }; - -/** -* PRF used in TLS 1.2 -*/ -class BOTAN_DLL TLS_12_PRF : public KDF - { - public: - SecureVector derive(size_t key_len, - const byte secret[], size_t secret_len, - const byte seed[], size_t seed_len) const; - - std::string name() const { return "TLSv12-PRF(" + hmac->name() + ")"; } - KDF* clone() const { return new TLS_12_PRF(hmac->clone()); } - - TLS_12_PRF(MessageAuthenticationCode* hmac); - ~TLS_12_PRF(); - private: - MessageAuthenticationCode* hmac; - }; - -} - - -namespace Botan { - -/** -* EMSA4 aka PSS-R -*/ -class BOTAN_DLL EMSA4 : public EMSA - { - public: - /** - * @param hash the hash object to use - */ - EMSA4(HashFunction* hash); - - /** - * @param hash the hash object to use - * @param salt_size the size of the salt to use in bytes - */ - EMSA4(HashFunction* hash, size_t salt_size); - - ~EMSA4() { delete hash; delete mgf; } - private: - void update(const byte[], size_t); - SecureVector raw_data(); - - SecureVector encoding_of(const MemoryRegion&, size_t, - RandomNumberGenerator& rng); - bool verify(const MemoryRegion&, const MemoryRegion&, - size_t); - - size_t SALT_SIZE; - HashFunction* hash; - const MGF* mgf; - }; - -} - - -namespace Botan { - -/** -* Camellia-128 -*/ -class BOTAN_DLL Camellia_128 : public Block_Cipher_Fixed_Params<16, 16> - { - public: - void encrypt_n(const byte in[], byte out[], size_t blocks) const; - void decrypt_n(const byte in[], byte out[], size_t blocks) const; - - void clear() { SK.clear(); } - std::string name() const { return "Camellia-128"; } - BlockCipher* clone() const { return new Camellia_128; } - private: - void key_schedule(const byte key[], size_t length); - - SecureVector SK; - }; - -/** -* Camellia-192 -*/ -class BOTAN_DLL Camellia_192 : public Block_Cipher_Fixed_Params<16, 24> - { - public: - void encrypt_n(const byte in[], byte out[], size_t blocks) const; - void decrypt_n(const byte in[], byte out[], size_t blocks) const; - - void clear() { SK.clear(); } - std::string name() const { return "Camellia-192"; } - BlockCipher* clone() const { return new Camellia_192; } - private: - void key_schedule(const byte key[], size_t length); - - SecureVector SK; - }; - -/** -* Camellia-256 -*/ -class BOTAN_DLL Camellia_256 : public Block_Cipher_Fixed_Params<16, 32> - { - public: - void encrypt_n(const byte in[], byte out[], size_t blocks) const; - void decrypt_n(const byte in[], byte out[], size_t blocks) const; - - void clear() { SK.clear(); } - std::string name() const { return "Camellia-256"; } - BlockCipher* clone() const { return new Camellia_256; } - private: - void key_schedule(const byte key[], size_t length); - - SecureVector SK; - }; - -} - - -namespace Botan { - -/** -* MD4 -*/ -class BOTAN_DLL MD4 : public MDx_HashFunction - { - public: - std::string name() const { return "MD4"; } - size_t output_length() const { return 16; } - HashFunction* clone() const { return new MD4; } - - void clear(); - - MD4() : MDx_HashFunction(64, false, true), M(16), digest(4) - { clear(); } - protected: - void compress_n(const byte input[], size_t blocks); - void copy_out(byte[]); - - /** - * The message buffer, exposed for use by subclasses (x86 asm) - */ - SecureVector M; - - /** - * The digest value, exposed for use by subclasses (x86 asm) - */ - SecureVector digest; - }; - -} - - -namespace Botan { - -/** -* Turing -*/ -class BOTAN_DLL Turing : public StreamCipher - { - public: - void cipher(const byte in[], byte out[], size_t length); - void set_iv(const byte iv[], size_t iv_length); - - bool valid_iv_length(size_t iv_len) const - { return (iv_len % 4 == 0 && iv_len <= 16); } - - Key_Length_Specification key_spec() const - { - return Key_Length_Specification(4, 32, 4); - } - - void clear(); - std::string name() const { return "Turing"; } - StreamCipher* clone() const { return new Turing; } - - Turing() : S0(256), S1(256), S2(256), S3(256), - R(17), buffer(340), position(0) {} - - private: - void key_schedule(const byte[], size_t); - void generate(); - - static u32bit fixedS(u32bit); - - static const u32bit Q_BOX[256]; - static const byte SBOX[256]; - - SecureVector S0, S1, S2, S3; - SecureVector R; - SecureVector K; - SecureVector buffer; - size_t position; - }; - -} - - -namespace Botan { - -/** -* SRP6a Client side -* @param username the username we are attempting login for -* @param password the password we are attempting to use -* @param group_id specifies the shared SRP group -* @param hash_id specifies a secure hash function -* @param salt is the salt value sent by the server -* @param B is the server's public value -* @param rng is a random number generator -* -* @return (A,K) the client public key and the shared secret key -*/ -std::pair -BOTAN_DLL srp6_client_agree(const std::string& username, - const std::string& password, - const std::string& group_id, - const std::string& hash_id, - const MemoryRegion& salt, - const BigInt& B, - RandomNumberGenerator& rng); - -/** -* Generate a new SRP-6 verifier -* @param identifier a username or other client identifier -* @param password the secret used to authenticate user -* @param salt a randomly chosen value, at least 128 bits long -*/ -BigInt BOTAN_DLL generate_srp6_verifier(const std::string& identifier, - const std::string& password, - const MemoryRegion& salt, - const std::string& group_id, - const std::string& hash_id); - -/** -* Return the group id for this SRP param set, or else thrown an -* exception -*/ -std::string BOTAN_DLL srp6_group_identifier(const BigInt& N, const BigInt& g); - -/** -* Represents a SRP-6a server session -*/ -class BOTAN_DLL SRP6_Server_Session - { - public: - /** - * Server side step 1 - * @param v the verification value saved from client registration - */ - BigInt step1(const BigInt& v, - const std::string& group_id, - const std::string& hash_id, - RandomNumberGenerator& rng); - - SymmetricKey step2(const BigInt& A); - - private: - std::string hash_id; - BigInt B, b, v, S, p; - size_t p_bytes; - }; - -} - - -namespace Botan { - -/** -* SAFER-SK -*/ -class BOTAN_DLL SAFER_SK : public Block_Cipher_Fixed_Params<8, 16> - { - public: - void encrypt_n(const byte in[], byte out[], size_t blocks) const; - void decrypt_n(const byte in[], byte out[], size_t blocks) const; - - void clear() { zeroise(EK); } - std::string name() const; - BlockCipher* clone() const; - - /** - * @param rounds the number of rounds to use - must be between 1 - * and 13 - */ - SAFER_SK(size_t rounds); - private: - size_t get_rounds() const { return (EK.size() - 8) / 16; } - void key_schedule(const byte[], size_t); - - SecureVector EK; - }; - -} - - -namespace Botan { - -/** -* CAST-128 -*/ -class BOTAN_DLL CAST_128 : public Block_Cipher_Fixed_Params<8, 11, 16> - { - public: - void encrypt_n(const byte in[], byte out[], size_t blocks) const; - void decrypt_n(const byte in[], byte out[], size_t blocks) const; - - void clear() { zeroise(MK); zeroise(RK); } - std::string name() const { return "CAST-128"; } - BlockCipher* clone() const { return new CAST_128; } - - CAST_128() : MK(16), RK(16) {} - private: - void key_schedule(const byte[], size_t); - - static void cast_ks(MemoryRegion& ks, - MemoryRegion& user_key); - - static const u32bit S5[256]; - static const u32bit S6[256]; - static const u32bit S7[256]; - static const u32bit S8[256]; - - SecureVector MK, RK; - }; - -extern const u32bit CAST_SBOX1[256]; -extern const u32bit CAST_SBOX2[256]; -extern const u32bit CAST_SBOX3[256]; -extern const u32bit CAST_SBOX4[256]; - -} - - -namespace Botan { - -/** -* PKCS #5 v2.0 PBE -*/ -class BOTAN_DLL PBE_PKCS5v20 : public PBE - { - public: - /** - * @param cipher names a block cipher - * @return true iff PKCS #5 knows how to use this cipher - */ - static bool known_cipher(const std::string& cipher); - - std::string name() const; - - void write(const byte[], size_t); - void start_msg(); - void end_msg(); - - /** - * Load a PKCS #5 v2.0 encrypted stream - * @param input is the input source - */ - PBE_PKCS5v20(DataSource& input); - - /** - * @param cipher the block cipher to use - * @param hash the hash function to use - */ - PBE_PKCS5v20(BlockCipher* cipher, HashFunction* hash); - - ~PBE_PKCS5v20(); - private: - void set_key(const std::string&); - void new_params(RandomNumberGenerator& rng); - MemoryVector encode_params() const; - void decode_params(DataSource&); - OID get_oid() const; - - void flush_pipe(bool); - - Cipher_Dir direction; - BlockCipher* block_cipher; - HashFunction* hash_function; - SecureVector salt, key, iv; - size_t iterations, key_length; - Pipe pipe; - }; - -} - - -namespace Botan { - -/** -* Algorithm benchmark -* @param name the name of the algorithm to test (cipher, hash, or MAC) -* @param af the algorithm factory used to create objects -* @param rng the rng to use to generate random inputs -* @param milliseconds total time for the benchmark to run -* @param buf_size size of buffer to benchmark against, in KiB -* @return results a map from provider to speed in mebibytes per second -*/ -std::map -BOTAN_DLL algorithm_benchmark(const std::string& name, - Algorithm_Factory& af, - RandomNumberGenerator& rng, - u32bit milliseconds, - size_t buf_size); - -} - - -namespace Botan { - -/** -* CBC-MAC -*/ -class BOTAN_DLL CBC_MAC : public MessageAuthenticationCode - { - public: - std::string name() const; - MessageAuthenticationCode* clone() const; - size_t output_length() const { return e->block_size(); } - void clear(); - - Key_Length_Specification key_spec() const - { - return e->key_spec(); - } - - /** - * @param cipher the underlying block cipher to use - */ - CBC_MAC(BlockCipher* cipher); - ~CBC_MAC(); - private: - void add_data(const byte[], size_t); - void final_result(byte[]); - void key_schedule(const byte[], size_t); - - BlockCipher* e; - SecureVector state; - size_t position; - }; - -} - - -namespace Botan { - -/** -* MARS, IBM's candidate for AES -*/ -class BOTAN_DLL MARS : public Block_Cipher_Fixed_Params<16, 16, 32, 4> - { - public: - void encrypt_n(const byte in[], byte out[], size_t blocks) const; - void decrypt_n(const byte in[], byte out[], size_t blocks) const; - - void clear() { zeroise(EK); } - std::string name() const { return "MARS"; } - BlockCipher* clone() const { return new MARS; } - - MARS() : EK(40) {} - private: - void key_schedule(const byte[], size_t); - - SecureVector EK; - }; - -} - - -namespace Botan { - -/** -* PKCS #5 PBKDF2 -*/ -class BOTAN_DLL PKCS5_PBKDF2 : public PBKDF - { - public: - std::string name() const - { - return "PBKDF2(" + mac->name() + ")"; - } - - PBKDF* clone() const - { - return new PKCS5_PBKDF2(mac->clone()); - } - - OctetString derive_key(size_t output_len, - const std::string& passphrase, - const byte salt[], size_t salt_len, - size_t iterations) const; - - /** - * Create a PKCS #5 instance using the specified message auth code - * @param mac_fn the MAC to use - */ - PKCS5_PBKDF2(MessageAuthenticationCode* mac_fn) : mac(mac_fn) {} - - /** - * Destructor - */ - ~PKCS5_PBKDF2() { delete mac; } - private: - MessageAuthenticationCode* mac; - }; - -} - - -namespace Botan { - -class Algorithm_Factory; - -/** -* Encrypt a key under a key encryption key using the algorithm -* described in RFC 3394 -* -* @param key the plaintext key to encrypt -* @param kek the key encryption key -* @param af an algorithm factory -* @return key encrypted under kek -*/ -SecureVector BOTAN_DLL rfc3394_keywrap(const MemoryRegion& key, - const SymmetricKey& kek, - Algorithm_Factory& af); - -/** -* Decrypt a key under a key encryption key using the algorithm -* described in RFC 3394 -* -* @param key the encrypted key to decrypt -* @param kek the key encryption key -* @param af an algorithm factory -* @return key decrypted under kek -*/ -SecureVector BOTAN_DLL rfc3394_keyunwrap(const MemoryRegion& key, - const SymmetricKey& kek, - Algorithm_Factory& af); - -} - - -namespace Botan { - -/** -* DLIES Encryption -*/ -class BOTAN_DLL DLIES_Encryptor : public PK_Encryptor - { - public: - DLIES_Encryptor(const PK_Key_Agreement_Key&, - KDF* kdf, - MessageAuthenticationCode* mac, - size_t mac_key_len = 20); - - ~DLIES_Encryptor(); - - void set_other_key(const MemoryRegion&); - private: - SecureVector enc(const byte[], size_t, - RandomNumberGenerator&) const; - size_t maximum_input_size() const; - - SecureVector other_key, my_key; - - PK_Key_Agreement ka; - KDF* kdf; - MessageAuthenticationCode* mac; - size_t mac_keylen; - }; - -/** -* DLIES Decryption -*/ -class BOTAN_DLL DLIES_Decryptor : public PK_Decryptor - { - public: - DLIES_Decryptor(const PK_Key_Agreement_Key&, - KDF* kdf, - MessageAuthenticationCode* mac, - size_t mac_key_len = 20); - - ~DLIES_Decryptor(); - - private: - SecureVector dec(const byte[], size_t) const; - - SecureVector my_key; - - PK_Key_Agreement ka; - KDF* kdf; - MessageAuthenticationCode* mac; - size_t mac_keylen; - }; - -} - - -namespace Botan { - -/** -* Output Feedback Mode -*/ -class BOTAN_DLL OFB : public StreamCipher - { - public: - void cipher(const byte in[], byte out[], size_t length); - - void set_iv(const byte iv[], size_t iv_len); - - bool valid_iv_length(size_t iv_len) const - { return (iv_len <= permutation->block_size()); } - - Key_Length_Specification key_spec() const - { - return permutation->key_spec(); - } - - std::string name() const; - - OFB* clone() const - { return new OFB(permutation->clone()); } - - void clear(); - - /** - * @param cipher the underlying block cipher to use - */ - OFB(BlockCipher* cipher); - ~OFB(); - private: - void key_schedule(const byte key[], size_t key_len); - - BlockCipher* permutation; - SecureVector buffer; - size_t position; - }; - -} - - -namespace Botan { - -/** -* Blowfish -*/ -class BOTAN_DLL Blowfish : public Block_Cipher_Fixed_Params<8, 1, 56> - { - public: - void encrypt_n(const byte in[], byte out[], size_t blocks) const; - void decrypt_n(const byte in[], byte out[], size_t blocks) const; - - /** - * Modified EKSBlowfish key schedule, used for bcrypt password hashing - */ - void eks_key_schedule(const byte key[], size_t key_length, - const byte salt[16], size_t workfactor); - - void clear(); - std::string name() const { return "Blowfish"; } - BlockCipher* clone() const { return new Blowfish; } - - Blowfish() : S(1024), P(18) {} - private: - void key_schedule(const byte key[], size_t length); - - void key_expansion(const byte key[], - size_t key_length, - const byte salt[16]); - - void generate_sbox(MemoryRegion& box, - u32bit& L, u32bit& R, - const byte salt[16], - size_t salt_off) const; - - static const u32bit P_INIT[18]; - static const u32bit S_INIT[1024]; - - SecureVector S; - SecureVector P; - }; - -} - - -namespace Botan { - -/** -* The Adler32 checksum, used in zlib -*/ -class BOTAN_DLL Adler32 : public HashFunction - { - public: - std::string name() const { return "Adler32"; } - size_t output_length() const { return 4; } - HashFunction* clone() const { return new Adler32; } - - void clear() { S1 = 1; S2 = 0; } - - Adler32() { clear(); } - ~Adler32() { clear(); } - private: - void add_data(const byte[], size_t); - void final_result(byte[]); - u16bit S1, S2; - }; - -} - - -namespace Botan { - -/** -* Parallel Hashes -*/ -class BOTAN_DLL Parallel : public HashFunction - { - public: - void clear(); - std::string name() const; - HashFunction* clone() const; - - size_t output_length() const; - - /** - * @param hashes a set of hashes to compute in parallel - */ - Parallel(const std::vector& hashes); - ~Parallel(); - private: - void add_data(const byte[], size_t); - void final_result(byte[]); - std::vector hashes; - }; - -} - - -namespace Botan { - -/** -* RC5 -*/ -class BOTAN_DLL RC5 : public Block_Cipher_Fixed_Params<8, 1, 32> - { - public: - void encrypt_n(const byte in[], byte out[], size_t blocks) const; - void decrypt_n(const byte in[], byte out[], size_t blocks) const; - - void clear() { zeroise(S); } - std::string name() const; - BlockCipher* clone() const { return new RC5(get_rounds()); } - - /** - * @param rounds the number of RC5 rounds to run. Must be between - * 8 and 32 and a multiple of 4. - */ - RC5(size_t rounds); - private: - size_t get_rounds() const { return (S.size() - 2) / 2; } - - void key_schedule(const byte[], size_t); - - SecureVector S; - }; - -} - - -namespace Botan { - -/** -* Run a set of self tests on some basic algorithms like AES and SHA-1 -* @param af an algorithm factory -* @throws Self_Test_Error if a failure occured -*/ -BOTAN_DLL void confirm_startup_self_tests(Algorithm_Factory& af); - -/** -* Run a set of self tests on some basic algorithms like AES and SHA-1 -* @param af an algorithm factory -* @returns false if a failure occured, otherwise true -*/ -BOTAN_DLL bool passes_self_tests(Algorithm_Factory& af); - -/** -* Run a set of algorithm KATs (known answer tests) -* @param algo_name the algorithm we are testing -* @param vars a set of input variables for this test, all - hex encoded. Keys used: "input", "output", "key", and "iv" -* @param af an algorithm factory -* @returns map from provider name to test result for that provider -*/ -BOTAN_DLL std::map -algorithm_kat(const SCAN_Name& algo_name, - const std::map& vars, - Algorithm_Factory& af); - -} - - -namespace Botan { - -/** -* Noekeon implementation using SIMD operations -*/ -class BOTAN_DLL Noekeon_SIMD : public Noekeon - { - public: - size_t parallelism() const { return 4; } - - void encrypt_n(const byte in[], byte out[], size_t blocks) const; - void decrypt_n(const byte in[], byte out[], size_t blocks) const; - - BlockCipher* clone() const { return new Noekeon_SIMD; } - }; - -} - - -namespace Botan { - -/** -* PKCS #5 v1.5 PBE -*/ -class BOTAN_DLL PBE_PKCS5v15 : public PBE - { - public: - std::string name() const; - - void write(const byte[], size_t); - void start_msg(); - void end_msg(); - - /** - * @param cipher the block cipher to use (DES or RC2) - * @param hash the hash function to use - * @param direction are we encrypting or decrypting - */ - PBE_PKCS5v15(BlockCipher* cipher, - HashFunction* hash, - Cipher_Dir direction); - - ~PBE_PKCS5v15(); - private: - void set_key(const std::string&); - void new_params(RandomNumberGenerator& rng); - MemoryVector encode_params() const; - void decode_params(DataSource&); - OID get_oid() const; - - void flush_pipe(bool); - - Cipher_Dir direction; - BlockCipher* block_cipher; - HashFunction* hash_function; - - SecureVector salt, key, iv; - size_t iterations; - Pipe pipe; - }; - -} - - -namespace Botan { - -/** -* CTR-BE (Counter mode, big-endian) -*/ -class BOTAN_DLL CTR_BE : public StreamCipher - { - public: - void cipher(const byte in[], byte out[], size_t length); - - void set_iv(const byte iv[], size_t iv_len); - - bool valid_iv_length(size_t iv_len) const - { return (iv_len <= permutation->block_size()); } - - Key_Length_Specification key_spec() const - { - return permutation->key_spec(); - } - - std::string name() const; - - CTR_BE* clone() const - { return new CTR_BE(permutation->clone()); } - - void clear(); - - /** - * @param cipher the underlying block cipher to use - */ - CTR_BE(BlockCipher* cipher); - ~CTR_BE(); - private: - void key_schedule(const byte key[], size_t key_len); - void increment_counter(); - - BlockCipher* permutation; - SecureVector counter, buffer; - size_t position; - }; - -} - - -namespace Botan { - -/** -* Randpool -*/ -class BOTAN_DLL Randpool : public RandomNumberGenerator - { - public: - void randomize(byte[], size_t); - bool is_seeded() const { return seeded; } - void clear(); - std::string name() const; - - void reseed(size_t bits_to_collect); - void add_entropy_source(EntropySource* es); - void add_entropy(const byte input[], size_t length); - - /** - * @param cipher a block cipher to use - * @param mac a message authentication code to use - * @param pool_blocks how many cipher blocks to use for the pool - * @param iterations_before_reseed how many times we'll use the - * internal state to generate output before reseeding - */ - Randpool(BlockCipher* cipher, - MessageAuthenticationCode* mac, - size_t pool_blocks = 32, - size_t iterations_before_reseed = 128); - - ~Randpool(); - private: - void update_buffer(); - void mix_pool(); - - size_t ITERATIONS_BEFORE_RESEED, POOL_BLOCKS; - BlockCipher* cipher; - MessageAuthenticationCode* mac; - - std::vector entropy_sources; - SecureVector pool, buffer, counter; - bool seeded; - }; - -} - - -namespace Botan { - -/** -* PRF used in SSLv3 -*/ -class BOTAN_DLL SSL3_PRF : public KDF - { - public: - SecureVector derive(size_t, const byte[], size_t, - const byte[], size_t) const; - - std::string name() const { return "SSL3-PRF"; } - KDF* clone() const { return new SSL3_PRF; } - }; - -} - - -namespace Botan { - -/** -* DES/3DES-based MAC from ANSI X9.19 -*/ -class BOTAN_DLL ANSI_X919_MAC : public MessageAuthenticationCode - { - public: - void clear(); - std::string name() const; - size_t output_length() const { return e->block_size(); } - MessageAuthenticationCode* clone() const; - - Key_Length_Specification key_spec() const - { - return Key_Length_Specification(8, 16, 8); - } - - /** - * @param cipher the underlying block cipher to use - */ - ANSI_X919_MAC(BlockCipher* cipher); - ~ANSI_X919_MAC(); - private: - void add_data(const byte[], size_t); - void final_result(byte[]); - void key_schedule(const byte[], size_t); - - BlockCipher* e; - BlockCipher* d; - SecureVector state; - size_t position; - }; - -} - -#endif // USE_SYSTEM_BOTAN -#endif // BOTAN_AMALGAMATION_H__ diff --git a/src/libs/3rdparty/botan/botan.pri b/src/libs/3rdparty/botan/botan.pri deleted file mode 100644 index abf66bfba7..0000000000 --- a/src/libs/3rdparty/botan/botan.pri +++ /dev/null @@ -1,56 +0,0 @@ -INCLUDEPATH *= $$PWD/.. -HEADERS += $$PWD/botan.h - -equals(USE_SYSTEM_BOTAN, 1) { - DEFINES += USE_SYSTEM_BOTAN - CONFIG += link_pkgconfig - PKGCONFIG += botan-1.10 -} else { - -SOURCES += $$PWD/botan.cpp - -CONFIG += exceptions - -DEPENDPATH += . - -DEFINES += BOTAN_DLL= -unix:DEFINES += BOTAN_TARGET_OS_HAS_GETTIMEOFDAY BOTAN_HAS_ALLOC_MMAP \ - BOTAN_HAS_ENTROPY_SRC_DEV_RANDOM BOTAN_HAS_ENTROPY_SRC_EGD BOTAN_HAS_ENTROPY_SRC_FTW \ - BOTAN_HAS_ENTROPY_SRC_UNIX BOTAN_HAS_MUTEX_PTHREAD BOTAN_HAS_PIPE_UNIXFD_IO -*linux*:DEFINES += BOTAN_TARGET_OS_IS_LINUX BOTAN_TARGET_OS_HAS_CLOCK_GETTIME \ - BOTAN_TARGET_OS_HAS_DLOPEN BOTAN_TARGET_OS_HAS_GMTIME_R BOTAN_TARGET_OS_HAS_POSIX_MLOCK \ - BOTAN_HAS_DYNAMICALLY_LOADED_ENGINE BOTAN_HAS_DYNAMIC_LOADER -macx:DEFINES += BOTAN_TARGET_OS_IS_DARWIN -*g++*:DEFINES += BOTAN_BUILD_COMPILER_IS_GCC -*clang*:DEFINES += BOTAN_BUILD_COMPILER_IS_CLANG -*icc*:DEFINES += BOTAN_BUILD_COMPILER_IS_INTEL - -CONFIG(x86_64):DEFINES += BOTAN_TARGET_ARCH_IS_X86_64 - -win32 { - DEFINES += BOTAN_TARGET_OS_IS_WINDOWS \ - BOTAN_TARGET_OS_HAS_LOADLIBRARY BOTAN_TARGET_OS_HAS_WIN32_GET_SYSTEMTIME \ - BOTAN_TARGET_OS_HAS_WIN32_VIRTUAL_LOCK BOTAN_HAS_DYNAMICALLY_LOADED_ENGINE \ - BOTAN_HAS_DYNAMIC_LOADER BOTAN_HAS_ENTROPY_SRC_CAPI BOTAN_HAS_ENTROPY_SRC_WIN32 \ - BOTAN_HAS_MUTEX_WIN32 - - msvc { - QMAKE_CXXFLAGS_EXCEPTIONS_ON = -EHs - QMAKE_CXXFLAGS += -wd4251 -wd4290 -wd4250 -wd4297 -wd4267 -wd4334 - DEFINES += BOTAN_BUILD_COMPILER_IS_MSVC BOTAN_TARGET_OS_HAS_GMTIME_S _SCL_SECURE_NO_WARNINGS - } else { - QMAKE_CFLAGS += -fpermissive -finline-functions -Wno-long-long - QMAKE_CXXFLAGS += -fpermissive -finline-functions -Wno-long-long - } - LIBS += -ladvapi32 -luser32 -} - -unix:*-g++* { - QMAKE_CFLAGS += -fPIC -fpermissive -finline-functions -Wno-long-long - QMAKE_CXXFLAGS += -fPIC -fpermissive -finline-functions -Wno-long-long -} - -linux*|freebsd* { - LIBS += -lrt $$QMAKE_LIBS_DYNLOAD -} -} diff --git a/src/libs/3rdparty/botan/configure.py b/src/libs/3rdparty/botan/configure.py old mode 100644 new mode 100755 index 71d2a3d39d..b09f07bb5e --- a/src/libs/3rdparty/botan/configure.py +++ b/src/libs/3rdparty/botan/configure.py @@ -1,22 +1,27 @@ #!/usr/bin/env python """ -Configuration program for botan (http://botan.randombit.net/) - (C) 2009-2011 Jack Lloyd - Distributed under the terms of the Botan license +Configuration program for botan -Tested with CPython 2.6, 2.7, 3.1 and PyPy 1.5 +(C) 2009,2010,2011,2012,2013,2014,2015,2016,2017,2018 Jack Lloyd +(C) 2015,2016,2017 Simon Warta (Kullo GmbH) -Python 2.5 works if you change the exception catching syntax: - perl -pi -e 's/except (.*) as (.*):/except $1, $2:/g' configure.py +Botan is released under the Simplified BSD License (see license.txt) -Jython - Target detection does not work (use --os and --cpu) +This script is regularly tested with CPython 2.7 and 3.5, and +occasionally tested with CPython 2.6 and PyPy 4. -CPython 2.4 and earlier are not supported +Support for CPython 2.6 will be dropped eventually, but is kept up for as +long as reasonably convenient. -Has not been tested with IronPython +CPython 2.5 and earlier are not supported. + +On Jython target detection does not work (use --os and --cpu). """ +import collections +import copy +import json import sys import os import os.path @@ -24,322 +29,485 @@ import platform import re import shlex import shutil -import string import subprocess +import traceback import logging -import getpass import time import errno -import optparse +import optparse # pylint: disable=deprecated-module + +# An error caused by and to be fixed by the user, e.g. invalid command line argument +class UserError(Exception): + pass -# Avoid useless botan_version.pyc (Python 2.6 or higher) -if 'dont_write_bytecode' in sys.__dict__: - sys.dont_write_bytecode = True -import botan_version +# An error caused by bugs in this script or when reading/parsing build data files +# Those are not expected to be fixed by the user of this script +class InternalError(Exception): + pass + def flatten(l): return sum(l, []) -def get_vc_revision(): - try: - mtn = subprocess.Popen(['mtn', 'automate', 'heads'], - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - universal_newlines=True) +def normalize_source_path(source): + """ + cmake needs this, and nothing else minds + """ + return os.path.normpath(source).replace('\\', '/') - (stdout, stderr) = mtn.communicate() +def parse_version_file(version_path): + version_file = open(version_path) + key_and_val = re.compile(r"([a-z_]+) = ([a-zA-Z0-9:\-\']+)") - if mtn.returncode != 0: - logging.debug('Error getting rev from monotone - %d (%s)' - % (mtn.returncode, stderr)) - return 'unknown' + results = {} + for line in version_file.readlines(): + if not line or line[0] == '#': + continue + match = key_and_val.match(line) + if match: + key = match.group(1) + val = match.group(2) + + if val == 'None': + val = None + elif val.startswith("'") and val.endswith("'"): + val = val[1:len(val)-1] + else: + val = int(val) - rev = str(stdout).strip() - logging.debug('Monotone reported revision %s' % (rev)) + results[key] = val + return results - return 'mtn:' + rev - except OSError as e: - logging.debug('Error getting rev from monotone - %s' % (e[1])) - return 'unknown' - except Exception as e: - logging.debug('Error getting rev from monotone - %s' % (e)) - return 'unknown' +class Version(object): + """ + Version information are all static members + """ + data = {} + + @staticmethod + def get_data(): + if not Version.data: + root_dir = os.path.dirname(os.path.realpath(__file__)) + Version.data = parse_version_file(os.path.join(root_dir, 'src/build-data/version.txt')) + return Version.data + + @staticmethod + def major(): + return Version.get_data()["release_major"] + + @staticmethod + def minor(): + return Version.get_data()["release_minor"] + + @staticmethod + def patch(): + return Version.get_data()["release_patch"] + + @staticmethod + def packed(): + # Used on Darwin for dylib versioning + return Version.major() * 1000 + Version.minor() + + @staticmethod + def so_rev(): + return Version.get_data()["release_so_abi_rev"] + + @staticmethod + def release_type(): + return Version.get_data()["release_type"] + + @staticmethod + def datestamp(): + return Version.get_data()["release_datestamp"] + + @staticmethod + def as_string(): + return '%d.%d.%d' % (Version.major(), Version.minor(), Version.patch()) + + @staticmethod + def vc_rev(): + # Lazy load to ensure _local_repo_vc_revision() does not run before logger is set up + if Version.get_data()["release_vc_rev"] is None: + Version.data["release_vc_rev"] = Version._local_repo_vc_revision() + return Version.get_data()["release_vc_rev"] + + @staticmethod + def _local_repo_vc_revision(): + vc_command = ['git', 'rev-parse', 'HEAD'] + cmdname = vc_command[0] + + try: + vc = subprocess.Popen( + vc_command, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + universal_newlines=True) + (stdout, stderr) = vc.communicate() + + if vc.returncode != 0: + logging.debug('Error getting rev from %s - %d (%s)' + % (cmdname, vc.returncode, stderr)) + return 'unknown' + + rev = str(stdout).strip() + logging.debug('%s reported revision %s' % (cmdname, rev)) + + return '%s:%s' % (cmdname, rev) + except OSError as e: + logging.debug('Error getting rev from %s - %s' % (cmdname, e.strerror)) + return 'unknown' -class BuildConfigurationInformation(object): +class SourcePaths(object): """ - Version information + A collection of paths defined by the project structure and + independent of user configurations. + All paths are relative to the base_dir, which may be relative as well (e.g. ".") """ - version_major = botan_version.release_major - version_minor = botan_version.release_minor - version_patch = botan_version.release_patch - version_so_rev = botan_version.release_so_abi_rev - version_datestamp = botan_version.release_datestamp + def __init__(self, base_dir): + self.base_dir = base_dir + self.doc_dir = os.path.join(self.base_dir, 'doc') + self.src_dir = os.path.join(self.base_dir, 'src') - version_vc_rev = botan_version.release_vc_rev - version_string = '%d.%d.%d' % (version_major, version_minor, version_patch) + # dirs in src/ + self.build_data_dir = os.path.join(self.src_dir, 'build-data') + self.configs_dir = os.path.join(self.src_dir, 'configs') + self.lib_dir = os.path.join(self.src_dir, 'lib') + self.python_dir = os.path.join(self.src_dir, 'python') + self.scripts_dir = os.path.join(self.src_dir, 'scripts') + # subdirs of src/ + self.sphinx_config_dir = os.path.join(self.configs_dir, 'sphinx') + + +class BuildPaths(object): # pylint: disable=too-many-instance-attributes """ Constructor """ - def __init__(self, options, modules): - - if self.version_vc_rev is None: - self.version_vc_rev = get_vc_revision() - + def __init__(self, source_paths, options, modules): self.build_dir = os.path.join(options.with_build_dir, 'build') - self.checkobj_dir = os.path.join(self.build_dir, 'checks') - self.libobj_dir = os.path.join(self.build_dir, 'lib') - - self.python_dir = os.path.join(options.src_dir, 'wrap', 'python') - - self.boost_python = options.boost_python + self.libobj_dir = os.path.join(self.build_dir, 'obj', 'lib') + self.cliobj_dir = os.path.join(self.build_dir, 'obj', 'cli') + self.testobj_dir = os.path.join(self.build_dir, 'obj', 'test') self.doc_output_dir = os.path.join(self.build_dir, 'docs') - - self.pyobject_dir = os.path.join(self.build_dir, 'python') + self.doc_output_dir_manual = os.path.join(self.doc_output_dir, 'manual') + self.doc_output_dir_doxygen = os.path.join(self.doc_output_dir, 'doxygen') if options.with_doxygen else None self.include_dir = os.path.join(self.build_dir, 'include') self.botan_include_dir = os.path.join(self.include_dir, 'botan') self.internal_include_dir = os.path.join(self.botan_include_dir, 'internal') + self.external_include_dir = os.path.join(self.include_dir, 'external') - self.sources = sorted(flatten([mod.sources() for mod in modules])) self.internal_headers = sorted(flatten([m.internal_headers() for m in modules])) + self.external_headers = sorted(flatten([m.external_headers() for m in modules])) - if options.via_amalgamation: - self.build_sources = ['botan_all.cpp'] - self.build_internal_headers = [] + if options.amalgamation: + self.lib_sources = ['botan_all.cpp'] else: - self.build_sources = self.sources - self.build_internal_headers = self.internal_headers + self.lib_sources = [normalize_source_path(s) for s in sorted(flatten([mod.sources() for mod in modules]))] self.public_headers = sorted(flatten([m.public_headers() for m in modules])) - checks_dir = os.path.join(options.base_dir, 'checks') - - self.check_sources = sorted( - [os.path.join(checks_dir, file) for file in os.listdir(checks_dir) - if file.endswith('.cpp')]) - - self.python_sources = sorted( - [os.path.join(self.python_dir, file) - for file in os.listdir(self.python_dir) - if file.endswith('.cpp')]) - - self.manual_dir = os.path.join(self. doc_output_dir, 'manual') + def find_sources_in(basedir, srcdir): + for (dirpath, _, filenames) in os.walk(os.path.join(basedir, srcdir)): + for filename in filenames: + if filename.endswith('.cpp') and not filename.startswith('.'): + yield os.path.join(dirpath, filename) + + def find_headers_in(basedir, srcdir): + for (dirpath, _, filenames) in os.walk(os.path.join(basedir, srcdir)): + for filename in filenames: + if filename.endswith('.h') and not filename.startswith('.'): + yield os.path.join(dirpath, filename) + + self.cli_sources = [normalize_source_path(s) for s in find_sources_in(source_paths.src_dir, 'cli')] + self.cli_headers = [normalize_source_path(s) for s in find_headers_in(source_paths.src_dir, 'cli')] + self.test_sources = [normalize_source_path(s) for s in find_sources_in(source_paths.src_dir, 'tests')] + + if options.build_fuzzers: + self.fuzzer_sources = list(find_sources_in(source_paths.src_dir, 'fuzzer')) + self.fuzzer_output_dir = os.path.join(self.build_dir, 'fuzzer') + self.fuzzobj_dir = os.path.join(self.build_dir, 'obj', 'fuzzer') + else: + self.fuzzer_sources = None + self.fuzzer_output_dir = None + self.fuzzobj_dir = None + + def build_dirs(self): + out = [ + self.libobj_dir, + self.cliobj_dir, + self.testobj_dir, + self.botan_include_dir, + self.internal_include_dir, + self.external_include_dir, + self.doc_output_dir_manual, + ] + if self.doc_output_dir_doxygen: + out += [self.doc_output_dir_doxygen] + if self.fuzzer_output_dir: + out += [self.fuzzobj_dir] + out += [self.fuzzer_output_dir] + return out + + def format_include_paths(self, cc, external_include): + dash_i = cc.add_include_dir_option + output = dash_i + self.include_dir + if self.external_headers: + output += ' ' + dash_i + self.external_include_dir + if external_include: + output += ' ' + dash_i + external_include + return output + + def src_info(self, typ): + if typ == 'lib': + return (self.lib_sources, self.libobj_dir) + elif typ == 'cli': + return (self.cli_sources, self.cliobj_dir) + elif typ == 'test': + return (self.test_sources, self.testobj_dir) + elif typ == 'fuzzer': + return (self.fuzzer_sources, self.fuzzobj_dir) + else: + raise InternalError("Unknown src info type '%s'" % (typ)) - def build_doc_commands(): - yield '$(COPY) readme.txt %s' % (self.doc_output_dir) +def process_command_line(args): # pylint: disable=too-many-locals + """ + Handle command line options + Do not use logging in this method as command line options need to be + available before logging is setup. + """ - if options.with_sphinx: - yield 'sphinx-build $(SPHINX_OPTS) -b html doc %s' % ( - self.manual_dir) - else: - yield '$(COPY) doc/*.txt %s' % (self.manual_dir) + parser = optparse.OptionParser( + formatter=optparse.IndentedHelpFormatter(max_help_position=50), + version=Version.as_string()) - if options.with_doxygen: - yield 'doxygen %s/botan.doxy' % (self.build_dir) + parser.add_option('--verbose', action='store_true', default=False, + help='Show debug messages') + parser.add_option('--quiet', action='store_true', default=False, + help='Show only warnings and errors') - self.build_doc_commands = '\n'.join(['\t' + s for s in build_doc_commands()]) + target_group = optparse.OptionGroup(parser, 'Target options') - def build_dirs(): - yield self.checkobj_dir - yield self.libobj_dir - yield self.botan_include_dir - yield self.internal_include_dir - yield os.path.join(self.doc_output_dir, 'manual') - if options.with_doxygen: - yield os.path.join(self.doc_output_dir, 'doxygen') + target_group.add_option('--cpu', help='set the target CPU architecture') - if self.boost_python: - yield self.pyobject_dir + target_group.add_option('--os', help='set the target operating system') - self.build_dirs = list(build_dirs()) + target_group.add_option('--cc', dest='compiler', help='set the desired build compiler') - def pkg_config_file(self): - return 'botan-%d.%d.pc' % (self.version_major, - self.version_minor) + target_group.add_option('--cc-min-version', dest='cc_min_version', default=None, + metavar='MAJOR.MINOR', + help='Set the minimal version of the target compiler. ' \ + 'Use --cc-min-version=0.0 to support all compiler versions. ' \ + 'Default is auto detection.') - def config_shell_script(self): - return 'botan-config-%d.%d' % (self.version_major, - self.version_minor) + target_group.add_option('--cc-bin', dest='compiler_binary', metavar='BINARY', + help='set path to compiler binary') - def username(self): - return getpass.getuser() + target_group.add_option('--cc-abi-flags', metavar='FLAG', default='', + help='set compiler ABI flags') - def hostname(self): - return platform.node() + target_group.add_option('--cxxflags', metavar='FLAG', default=None, + help='set compiler flags') - def timestamp(self): - return time.ctime() + target_group.add_option('--ldflags', metavar='FLAG', + help='set linker flags', default=None) -""" -Handle command line options -""" -def process_command_line(args): + target_group.add_option('--ar-command', dest='ar_command', metavar='AR', default=None, + help='set path to static archive creator') - parser = optparse.OptionParser( - formatter = optparse.IndentedHelpFormatter(max_help_position = 50), - version = BuildConfigurationInformation.version_string) + target_group.add_option('--msvc-runtime', metavar='RT', default=None, + help='specify MSVC runtime (MT, MD, MTd, MDd)') - parser.add_option('--verbose', action='store_true', default=False, - help='Show debug messages') - parser.add_option('--quiet', action='store_true', default=False, - help='Show only warnings and errors') + target_group.add_option('--with-endian', metavar='ORDER', default=None, + help='override byte order guess') - target_group = optparse.OptionGroup(parser, 'Target options') + target_group.add_option('--with-os-features', action='append', metavar='FEAT', + help='specify OS features to use') + target_group.add_option('--without-os-features', action='append', metavar='FEAT', + help='specify OS features to disable') - target_group.add_option('--cpu', - help='set the target processor type/model') + isa_extensions = [ + 'SSE2', 'SSSE3', 'SSE4.1', 'SSE4.2', 'AVX2', + 'AES-NI', 'SHA', + 'AltiVec', 'NEON', 'ARMv8Crypto'] - target_group.add_option('--os', - help='set the target operating system') + for isa_extn_name in isa_extensions: + isa_extn = isa_extn_name.lower() - target_group.add_option('--cc', dest='compiler', - help='set the desired build compiler') + target_group.add_option('--disable-%s' % (isa_extn), + help='disable %s intrinsics' % (isa_extn_name), + action='append_const', + const=isa_extn.replace('-', '').replace('.', ''), + dest='disable_intrinsics') - target_group.add_option('--cc-bin', dest='compiler_binary', - metavar='BINARY', - help='set the name of the compiler binary') + build_group = optparse.OptionGroup(parser, 'Build options') - target_group.add_option('--with-endian', metavar='ORDER', default=None, - help='override guess of CPU byte order') + build_group.add_option('--with-debug-info', action='store_true', default=False, dest='with_debug_info', + help='include debug symbols') - target_group.add_option('--with-unaligned-mem', - dest='unaligned_mem', action='store_true', - default=None, - help='enable unaligned memory accesses') + build_group.add_option('--with-sanitizers', action='store_true', default=False, dest='with_sanitizers', + help='enable ASan/UBSan checks') - target_group.add_option('--without-unaligned-mem', - dest='unaligned_mem', action='store_false', - help=optparse.SUPPRESS_HELP) + build_group.add_option('--enable-sanitizers', metavar='SAN', default='', + help='enable specific sanitizers') - for isa_extn_name in ['SSE2', 'SSSE3', 'AltiVec', 'AES-NI', 'movbe']: - isa_extn = isa_extn_name.lower() + build_group.add_option('--with-stack-protector', dest='with_stack_protector', + action='store_false', default=None, help=optparse.SUPPRESS_HELP) - target_group.add_option('--enable-%s' % (isa_extn), - help='enable use of %s' % (isa_extn_name), - action='append_const', - const=isa_extn, - dest='enable_isa_extns') + build_group.add_option('--without-stack-protector', dest='with_stack_protector', + action='store_false', help='disable stack smashing protections') - target_group.add_option('--disable-%s' % (isa_extn), - help=optparse.SUPPRESS_HELP, - action='append_const', - const=isa_extn, - dest='disable_isa_extns') + build_group.add_option('--with-coverage', action='store_true', default=False, dest='with_coverage', + help='add coverage info and disable opts') - build_group = optparse.OptionGroup(parser, 'Build options') + build_group.add_option('--with-coverage-info', action='store_true', default=False, dest='with_coverage_info', + help='add coverage info') - build_group.add_option('--enable-shared', dest='build_shared_lib', - action='store_true', default=True, - help=optparse.SUPPRESS_HELP) - build_group.add_option('--disable-shared', dest='build_shared_lib', + build_group.add_option('--enable-shared-library', dest='build_shared_lib', + action='store_true', default=None, + help=optparse.SUPPRESS_HELP) + build_group.add_option('--disable-shared-library', dest='build_shared_lib', action='store_false', - help='disable building a shared library') + help='disable building shared library') - build_group.add_option('--enable-asm', dest='asm_ok', - action='store_true', default=True, + build_group.add_option('--enable-static-library', dest='build_static_lib', + action='store_true', default=None, help=optparse.SUPPRESS_HELP) - build_group.add_option('--disable-asm', dest='asm_ok', + build_group.add_option('--disable-static-library', dest='build_static_lib', action='store_false', - help='disallow use of assembler') + help='disable building static library') - build_group.add_option('--enable-debug', dest='debug_build', + build_group.add_option('--optimize-for-size', dest='optimize_for_size', action='store_true', default=False, - help='enable debug build') - build_group.add_option('--disable-debug', dest='debug_build', - action='store_false', help=optparse.SUPPRESS_HELP) + help='optimize for code size') build_group.add_option('--no-optimizations', dest='no_optimizations', action='store_true', default=False, - help=optparse.SUPPRESS_HELP) + help='disable all optimizations (for debugging)') - build_group.add_option('--gen-amalgamation', dest='gen_amalgamation', - default=False, action='store_true', - help='generate amalgamation files') + build_group.add_option('--debug-mode', action='store_true', default=False, dest='debug_mode', + help='enable debug info, disable optimizations') - build_group.add_option('--via-amalgamation', dest='via_amalgamation', + build_group.add_option('--amalgamation', dest='amalgamation', default=False, action='store_true', - help='build via amalgamation') + help='use amalgamation to build') - build_group.add_option('--with-tr1-implementation', metavar='WHICH', - dest='with_tr1', default=None, - help='enable TR1 (choices: none, system, boost)') + build_group.add_option('--single-amalgamation-file', + default=False, action='store_true', + help='build single file instead of splitting on ABI') - build_group.add_option('--with-build-dir', - metavar='DIR', default='', + build_group.add_option('--with-build-dir', metavar='DIR', default='', help='setup the build in DIR') - build_group.add_option('--makefile-style', metavar='STYLE', default=None, - help='choose a makefile style (unix or nmake)') + build_group.add_option('--with-external-includedir', metavar='DIR', default='', + help='use DIR for external includes') + + build_group.add_option('--with-external-libdir', metavar='DIR', default='', + help='use DIR for external libs') + + build_group.add_option('--with-sysroot-dir', metavar='DIR', default='', + help='use DIR for system root while cross-compiling') + + build_group.add_option('--with-openmp', default=False, action='store_true', + help='enable use of OpenMP') + + link_methods = ['symlink', 'hardlink', 'copy'] + build_group.add_option('--link-method', default=None, metavar='METHOD', + choices=link_methods, + help='choose how links to include headers are created (%s)' % ', '.join(link_methods)) build_group.add_option('--with-local-config', dest='local_config', metavar='FILE', help='include the contents of FILE into build.h') build_group.add_option('--distribution-info', metavar='STRING', - help='set distribution specific versioning', + help='distribution specific version', default='unspecified') - build_group.add_option('--with-sphinx', action='store_true', - default=None, - help='Use Sphinx to generate HTML manual') + build_group.add_option('--maintainer-mode', dest='maintainer_mode', + action='store_true', default=False, + help="Enable extra warnings") - build_group.add_option('--without-sphinx', action='store_false', - dest='with_sphinx', help=optparse.SUPPRESS_HELP) + build_group.add_option('--with-python-versions', dest='python_version', + metavar='N.M', + default='%d.%d' % (sys.version_info[0], sys.version_info[1]), + help='where to install botan2.py (def %default)') - build_group.add_option('--with-visibility', action='store_true', - default=None, help=optparse.SUPPRESS_HELP) + build_group.add_option('--disable-cc-tests', dest='enable_cc_tests', + default=True, action='store_false', + help=optparse.SUPPRESS_HELP) - build_group.add_option('--without-visibility', action='store_false', - dest='with_visibility', help=optparse.SUPPRESS_HELP) + build_group.add_option('--with-valgrind', help='use valgrind API', + dest='with_valgrind', action='store_true', default=False) - build_group.add_option('--with-doxygen', action='store_true', - default=False, - help='Use Doxygen to generate HTML API docs') + # Cmake and bakefile options are hidden as they should not be used by end users + build_group.add_option('--with-cmake', action='store_true', + default=False, help=optparse.SUPPRESS_HELP) - build_group.add_option('--without-doxygen', action='store_false', - dest='with_doxygen', help=optparse.SUPPRESS_HELP) + build_group.add_option('--with-bakefile', action='store_true', + default=False, help=optparse.SUPPRESS_HELP) - build_group.add_option('--dumb-gcc', dest='dumb_gcc', - action='store_true', default=False, - help=optparse.SUPPRESS_HELP) + build_group.add_option('--unsafe-fuzzer-mode', action='store_true', default=False, + help='Disable essential checks for testing') - build_group.add_option('--maintainer-mode', dest='maintainer_mode', - action='store_true', default=False, - help=optparse.SUPPRESS_HELP) + build_group.add_option('--build-fuzzers', dest='build_fuzzers', + metavar='TYPE', default=None, + help='Build fuzzers (afl, libfuzzer, klee, test)') + + build_group.add_option('--with-fuzzer-lib', metavar='LIB', default=None, dest='fuzzer_lib', + help='additionally link in LIB') - build_group.add_option('--dirty-tree', dest='clean_build_tree', - action='store_false', default=True, + build_group.add_option('--test-mode', action='store_true', default=False, help=optparse.SUPPRESS_HELP) - build_group.add_option('--link-method', - default=None, + build_group.add_option('--with-debug-asserts', action='store_true', default=False, help=optparse.SUPPRESS_HELP) - wrapper_group = optparse.OptionGroup(parser, 'Wrapper options') + docs_group = optparse.OptionGroup(parser, 'Documentation Options') + + docs_group.add_option('--with-documentation', action='store_true', + help=optparse.SUPPRESS_HELP) + + docs_group.add_option('--without-documentation', action='store_false', + default=True, dest='with_documentation', + help='Skip building/installing documentation') + + docs_group.add_option('--with-sphinx', action='store_true', + default=None, help='Use Sphinx') + + docs_group.add_option('--without-sphinx', action='store_false', + dest='with_sphinx', help=optparse.SUPPRESS_HELP) + + docs_group.add_option('--with-pdf', action='store_true', + default=False, help='Use Sphinx to generate PDF doc') + + docs_group.add_option('--without-pdf', action='store_false', + dest='with_pdf', help=optparse.SUPPRESS_HELP) - wrapper_group.add_option('--with-boost-python', dest='boost_python', - default=False, action='store_true', - help='enable Boost.Python wrapper') + docs_group.add_option('--with-rst2man', action='store_true', + default=None, help='Use rst2man to generate man page') - wrapper_group.add_option('--without-boost-python', - dest='boost_python', - action='store_false', - help=optparse.SUPPRESS_HELP) + docs_group.add_option('--without-rst2man', action='store_false', + dest='with_rst2man', help=optparse.SUPPRESS_HELP) - wrapper_group.add_option('--with-python-version', dest='python_version', - metavar='N.M', - default='.'.join(map(str, sys.version_info[0:2])), - help='specify Python to build against (eg %default)') + docs_group.add_option('--with-doxygen', action='store_true', + default=False, help='Use Doxygen') + + docs_group.add_option('--without-doxygen', action='store_false', + dest='with_doxygen', help=optparse.SUPPRESS_HELP) mods_group = optparse.OptionGroup(parser, 'Module selection') + mods_group.add_option('--module-policy', dest='module_policy', + help="module policy file (see src/build-data/policy)", + metavar='POL', default=None) + mods_group.add_option('--enable-modules', dest='enabled_modules', metavar='MODS', action='append', help='enable specific modules') @@ -347,14 +515,16 @@ def process_command_line(args): metavar='MODS', action='append', help='disable specific modules') mods_group.add_option('--no-autoload', action='store_true', default=False, - help='disable automatic loading') + help=optparse.SUPPRESS_HELP) + mods_group.add_option('--minimized-build', action='store_true', dest='no_autoload', + help='minimize build') - for lib in ['OpenSSL', 'GNU MP', 'Bzip2', 'Zlib']: - - mod = lib.lower().replace(' ', '') + # Should be derived from info.txt but this runs too early + third_party = ['bearssl', 'boost', 'bzip2', 'lzma', 'openssl', 'sqlite3', 'zlib', 'tpm'] + for mod in third_party: mods_group.add_option('--with-%s' % (mod), - help='add support for using %s' % (lib), + help=('use %s' % (mod)) if mod in third_party else optparse.SUPPRESS_HELP, action='append_const', const=mod, dest='enabled_modules') @@ -365,26 +535,48 @@ def process_command_line(args): const=mod, dest='disabled_modules') + mods_group.add_option('--with-everything', help=optparse.SUPPRESS_HELP, + action='store_true', default=False) + install_group = optparse.OptionGroup(parser, 'Installation options') + install_group.add_option('--program-suffix', metavar='SUFFIX', + help='append string to program names') + install_group.add_option('--library-suffix', metavar='SUFFIX', default='', + help='append string to library names') + install_group.add_option('--prefix', metavar='DIR', - help='set the base install directory') + help='set the install prefix') install_group.add_option('--docdir', metavar='DIR', - help='set the documentation install directory') + help='set the doc install dir') + install_group.add_option('--bindir', metavar='DIR', + help='set the binary install dir') install_group.add_option('--libdir', metavar='DIR', - help='set the library install directory') + help='set the library install dir') + install_group.add_option('--mandir', metavar='DIR', + help='set the install dir for man pages') install_group.add_option('--includedir', metavar='DIR', - help='set the include file install directory') + help='set the include file install dir') + + info_group = optparse.OptionGroup(parser, 'Informational') + + info_group.add_option('--list-modules', dest='list_modules', + action='store_true', + help='list available modules and exit') + + info_group.add_option('--list-os-features', dest='list_os_features', + action='store_true', + help='list available OS features and exit') parser.add_option_group(target_group) parser.add_option_group(build_group) + parser.add_option_group(docs_group) parser.add_option_group(mods_group) - parser.add_option_group(wrapper_group) parser.add_option_group(install_group) + parser.add_option_group(info_group) - # These exist only for autoconf compatability (requested by zw for mtn) + # These exist only for autoconf compatibility (requested by zw for mtn) compat_with_autoconf_options = [ - 'bindir', 'datadir', 'datarootdir', 'dvidir', @@ -394,7 +586,6 @@ def process_command_line(args): 'libexecdir', 'localedir', 'localstatedir', - 'mandir', 'oldincludedir', 'pdfdir', 'psdir', @@ -409,11 +600,18 @@ def process_command_line(args): (options, args) = parser.parse_args(args) if args != []: - raise Exception('Unhandled option(s): ' + ' '.join(args)) - if options.with_endian != None and \ - options.with_endian not in ['little', 'big']: - raise Exception('Bad value to --with-endian "%s"' % ( - options.with_endian)) + raise UserError('Unhandled option(s): ' + ' '.join(args)) + + if options.with_endian not in [None, 'little', 'big']: + raise UserError('Bad value to --with-endian "%s"' % (options.with_endian)) + + if options.debug_mode: + options.no_optimizations = True + options.with_debug_info = True + + if options.with_coverage: + options.with_coverage_info = True + options.no_optimizations = True def parse_multiple_enable(modules): if modules is None: @@ -423,78 +621,78 @@ def process_command_line(args): options.enabled_modules = parse_multiple_enable(options.enabled_modules) options.disabled_modules = parse_multiple_enable(options.disabled_modules) - options.enable_isa_extns = parse_multiple_enable(options.enable_isa_extns) - options.disable_isa_extns = parse_multiple_enable(options.disable_isa_extns) - - def enabled_or_disabled_isa(isa): - if isa in options.enable_isa_extns: - return True - if isa in options.disable_isa_extns: - return True - return False + options.with_os_features = parse_multiple_enable(options.with_os_features) + options.without_os_features = parse_multiple_enable(options.without_os_features) - isa_deps = { - 'ssse3': 'sse2', - 'aes-ni': 'sse2' - } + options.disable_intrinsics = parse_multiple_enable(options.disable_intrinsics) - if 'sse2' in options.disable_isa_extns: - for isa in [k for (k,v) in isa_deps.items() if v == 'sse2']: - # If explicitly enabled, allow it even if a dependency - # violation; trust the user to know what they want - if not enabled_or_disabled_isa(isa): - options.disable_isa_extns.append(isa) + # Take some values from environment, if not set on command line - for isa in options.enable_isa_extns: - if isa in isa_deps: - for dep in isa_deps.get(isa, '').split(','): - if not enabled_or_disabled_isa(dep): - options.enable_isa_extns.append(dep) + if options.ar_command is None: + options.ar_command = os.getenv('AR') + if options.compiler_binary is None: + options.compiler_binary = os.getenv('CXX') + if options.cxxflags is None: + options.cxxflags = os.getenv('CXXFLAGS') + if options.ldflags is None: + options.ldflags = os.getenv('LDFLAGS') return options -""" -Generic lexer function for info.txt and src/build-data files -""" -def lex_me_harder(infofile, to_obj, allowed_groups, name_val_pairs): - # Format as a nameable Python variable - def py_var(group): - return group.replace(':', '_') +class LexResult(object): + pass - class LexerError(Exception): - def __init__(self, msg, line): - self.msg = msg - self.line = line - def __str__(self): - return '%s at %s:%d' % (self.msg, infofile, self.line) +class LexerError(InternalError): + def __init__(self, msg, lexfile, line): + super(LexerError, self).__init__(msg) + self.msg = msg + self.lexfile = lexfile + self.line = line - (dirname, basename) = os.path.split(infofile) + def __str__(self): + return '%s at %s:%d' % (self.msg, self.lexfile, self.line) - to_obj.lives_in = dirname - if basename == 'info.txt': - (obj_dir,to_obj.basename) = os.path.split(dirname) - if os.access(os.path.join(obj_dir, 'info.txt'), os.R_OK): - to_obj.parent_module = os.path.basename(obj_dir) - else: - to_obj.parent_module = None - else: - to_obj.basename = basename.replace('.txt', '') + +def parse_lex_dict(as_list): + if len(as_list) % 3 != 0: + raise InternalError("Lex dictionary has invalid format (input not divisible by 3): %s" % as_list) + + result = {} + for key, sep, value in [as_list[3*i:3*i+3] for i in range(0, len(as_list)//3)]: + if sep != '->': + raise InternalError("Lex dictionary has invalid format") + result[key] = value + return result + + +def lex_me_harder(infofile, allowed_groups, allowed_maps, name_val_pairs): + """ + Generic lexer function for info.txt and src/build-data files + """ + out = LexResult() + + # Format as a nameable Python variable + def py_var(group): + return group.replace(':', '_') lexer = shlex.shlex(open(infofile), infofile, posix=True) - lexer.wordchars += '|:.<>/,-!+' # handle various funky chars in info.txt + lexer.wordchars += ':.<>/,-!?+*' # handle various funky chars in info.txt - for group in allowed_groups: - to_obj.__dict__[py_var(group)] = [] - for (key,val) in name_val_pairs.items(): - to_obj.__dict__[key] = val + groups = allowed_groups + allowed_maps + for group in groups: + out.__dict__[py_var(group)] = [] + for (key, val) in name_val_pairs.items(): + out.__dict__[key] = val - def lexed_tokens(): # Convert to an interator - token = lexer.get_token() - while token != None: - yield token + def lexed_tokens(): # Convert to an iterator + while True: token = lexer.get_token() + if token != lexer.eof: + yield token + else: + return for token in lexed_tokens(): match = re.match('<(.*)>', token) @@ -503,106 +701,175 @@ def lex_me_harder(infofile, to_obj, allowed_groups, name_val_pairs): if match is not None: group = match.group(1) - if group not in allowed_groups: + if group not in groups: raise LexerError('Unknown group "%s"' % (group), - lexer.lineno) + infofile, lexer.lineno) end_marker = '' token = lexer.get_token() while token != end_marker: - to_obj.__dict__[py_var(group)].append(token) + out.__dict__[py_var(group)].append(token) token = lexer.get_token() if token is None: raise LexerError('Group "%s" not terminated' % (group), - lexer.lineno) + infofile, lexer.lineno) elif token in name_val_pairs.keys(): - next_val = lexer.get_token() - - if type(to_obj.__dict__[token]) is list: - to_obj.__dict__[token].append(next_val) + if isinstance(out.__dict__[token], list): + out.__dict__[token].append(lexer.get_token()) else: - to_obj.__dict__[token] = next_val + out.__dict__[token] = lexer.get_token() else: # No match -> error - raise LexerError('Bad token "%s"' % (token), lexer.lineno) + raise LexerError('Bad token "%s"' % (token), infofile, lexer.lineno) -""" -Convert a lex'ed map (from build-data files) from a list to a dict -""" -def force_to_dict(l): - return dict(zip(l[::3],l[2::3])) + for group in allowed_maps: + out.__dict__[group] = parse_lex_dict(out.__dict__[group]) -""" -Represents the information about a particular module -""" -class ModuleInfo(object): + return out +class InfoObject(object): def __init__(self, infofile): + """ + Constructor sets members `infofile`, `lives_in`, `parent_module` and `basename` + """ + + self.infofile = infofile + (dirname, basename) = os.path.split(infofile) + self.lives_in = dirname + if basename == 'info.txt': + (obj_dir, self.basename) = os.path.split(dirname) + if os.access(os.path.join(obj_dir, 'info.txt'), os.R_OK): + self.parent_module = os.path.basename(obj_dir) + else: + self.parent_module = None + else: + self.basename = basename.replace('.txt', '') - lex_me_harder(infofile, self, - ['source', 'header:internal', 'header:public', - 'requires', 'os', 'arch', 'cc', 'libs', - 'comment'], - { - 'load_on': 'auto', - 'define': [], - 'uses_tr1': 'false', - 'need_isa': None, - 'mp_bits': 0 }) - - def extract_files_matching(basedir, suffixes): - for (dirpath, dirnames, filenames) in os.walk(basedir): - if dirpath == basedir: - for filename in filenames: - if filename.startswith('.'): - continue - - for suffix in suffixes: - if filename.endswith(suffix): - yield filename - if self.source == []: - self.source = list(extract_files_matching(self.lives_in, ['.cpp', '.S'])) +class ModuleInfo(InfoObject): + """ + Represents the information about a particular module + """ - if self.header_internal == [] and self.header_public == []: - self.header_public = list(extract_files_matching(self.lives_in, ['.h'])) + def __init__(self, infofile): + super(ModuleInfo, self).__init__(infofile) + lex = lex_me_harder( + infofile, + ['header:internal', 'header:public', 'header:external', 'requires', + 'os_features', 'arch', 'cc', 'libs', 'frameworks', 'comment', 'warning' + ], + ['defines'], + { + 'load_on': 'auto', + 'need_isa': '' + }) + + def check_header_duplicates(header_list_public, header_list_internal): + pub_header = set(header_list_public) + int_header = set(header_list_internal) + if not pub_header.isdisjoint(int_header): + logging.error("Module %s header contains same header in public and internal sections" % self.infofile) + + check_header_duplicates(lex.header_public, lex.header_internal) + + all_source_files = [] + all_header_files = [] + + for fspath in os.listdir(self.lives_in): + if fspath.endswith('.cpp'): + all_source_files.append(fspath) + elif fspath.endswith('.h'): + all_header_files.append(fspath) + + self.source = all_source_files + + # If not entry for the headers, all are assumed public + if lex.header_internal == [] and lex.header_public == []: + self.header_public = list(all_header_files) + self.header_internal = [] + else: + self.header_public = lex.header_public + self.header_internal = lex.header_internal + self.header_external = lex.header_external # Coerce to more useful types def convert_lib_list(l): + if len(l) % 3 != 0: + raise InternalError("Bad in module %s" % (self.basename)) result = {} + + for sep in l[1::3]: + if sep != '->': + raise InternalError("Bad in module %s" % (self.basename)) + for (targetlist, vallist) in zip(l[::3], l[2::3]): vals = vallist.split(',') for target in targetlist.split(','): result[target] = result.setdefault(target, []) + vals return result - self.libs = convert_lib_list(self.libs) - - def add_dir_name(filename): - if filename.count(':') == 0: - return os.path.join(self.lives_in, filename) - - # modules can request to add files of the form - # MODULE_NAME:FILE_NAME to add a file from another module - # For these, assume other module is always in a - # neighboring directory; this is true for all current uses - return os.path.join(os.path.split(self.lives_in)[0], - *filename.split(':')) - - self.source = [add_dir_name(s) for s in self.source] - self.header_internal = [add_dir_name(s) for s in self.header_internal] - self.header_public = [add_dir_name(s) for s in self.header_public] - - self.mp_bits = int(self.mp_bits) - - self.uses_tr1 = (True if self.uses_tr1 == 'yes' else False) - - if self.comment != []: - self.comment = ' '.join(self.comment) - else: - self.comment = None + # Convert remaining lex result to members + self.arch = lex.arch + self.cc = lex.cc + self.comment = ' '.join(lex.comment) if lex.comment else None + self._defines = lex.defines + self._validate_defines_content(self._defines) + self.frameworks = convert_lib_list(lex.frameworks) + self.libs = convert_lib_list(lex.libs) + self.load_on = lex.load_on + self.need_isa = lex.need_isa.split(',') if lex.need_isa else [] + self.os_features = lex.os_features + self.requires = lex.requires + self.warning = ' '.join(lex.warning) if lex.warning else None + + # Modify members + self.source = [normalize_source_path(os.path.join(self.lives_in, s)) for s in self.source] + self.header_internal = [os.path.join(self.lives_in, s) for s in self.header_internal] + self.header_public = [os.path.join(self.lives_in, s) for s in self.header_public] + self.header_external = [os.path.join(self.lives_in, s) for s in self.header_external] + + # Filesystem read access check + for src in self.source + self.header_internal + self.header_public + self.header_external: + if not os.access(src, os.R_OK): + logging.error("Missing file %s in %s" % (src, infofile)) + + # Check for duplicates + def intersect_check(type_a, list_a, type_b, list_b): + intersection = set.intersection(set(list_a), set(list_b)) + if intersection: + logging.error('Headers %s marked both %s and %s' % (' '.join(intersection), type_a, type_b)) + + intersect_check('public', self.header_public, 'internal', self.header_internal) + intersect_check('public', self.header_public, 'external', self.header_external) + intersect_check('external', self.header_external, 'internal', self.header_internal) + + @staticmethod + def _validate_defines_content(defines): + 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): + raise InternalError('Module defines value has invalid format: "%s"' % value) + + def cross_check(self, arch_info, cc_info, all_os_features): + + for feat in set(flatten([o.split(',') for o in self.os_features])): + if feat not in all_os_features: + logging.error("Module %s uses an OS feature (%s) which no OS supports", self.infofile, feat) + + for supp_cc in self.cc: + if supp_cc not in cc_info: + colon_idx = supp_cc.find(':') + # a versioned compiler dependency + if colon_idx > 0 and supp_cc[0:colon_idx] in cc_info: + pass + else: + raise InternalError('Module %s mentions unknown compiler %s' % (self.infofile, supp_cc)) + for supp_arch in self.arch: + if supp_arch not in arch_info: + raise InternalError('Module %s mentions unknown arch %s' % (self.infofile, supp_arch)) def sources(self): return self.source @@ -613,321 +880,556 @@ class ModuleInfo(object): def internal_headers(self): return self.header_internal + def external_headers(self): + return self.header_external + def defines(self): - return ['HAS_' + d for d in self.define] + return [(key + ' ' + value) for key, value in self._defines.items()] def compatible_cpu(self, archinfo, options): - arch_name = archinfo.basename cpu_name = options.cpu + for isa in self.need_isa: + if isa in options.disable_intrinsics: + return False # explicitly disabled + + if isa not in archinfo.isa_extensions: + return False + if self.arch != []: if arch_name not in self.arch and cpu_name not in self.arch: return False - if self.need_isa != None: - if self.need_isa in options.disable_isa_extns: - return False # explicitly disabled + return True - if self.need_isa in options.enable_isa_extns: - return True # explicitly enabled + def compatible_os(self, os_data, options): + if not self.os_features: + return True - # Default to whatever the CPU is supposed to support - return self.need_isa in archinfo.isa_extensions_in(cpu_name) + def has_all(needed, provided): + for n in needed: + if n not in provided: + return False + return True - return True + provided_features = os_data.enabled_features(options) - def compatible_os(self, os): - return self.os == [] or os in self.os + for feature_set in self.os_features: + if has_all(feature_set.split(','), provided_features): + return True - def compatible_compiler(self, cc): - return self.cc == [] or cc in self.cc + return False - def tr1_ok(self, with_tr1): - if self.uses_tr1: - return with_tr1 in ['boost', 'system'] - else: + def compatible_compiler(self, ccinfo, cc_min_version, arch): + # Check if this compiler supports the flags we need + def supported_isa_flags(ccinfo, arch): + for isa in self.need_isa: + if ccinfo.isa_flags_for(isa, arch) is None: + return False return True - def dependencies(self): - # utils is an implicit dep (contains types, etc) - deps = self.requires + ['utils'] + # Check if module gives explicit compiler dependencies + def supported_compiler(ccinfo, cc_min_version): + if self.cc == []: + # no compiler restriction + return True + + if ccinfo.basename in self.cc: + # compiler is supported, independent of version + return True + + # Maybe a versioned compiler dep + for cc in self.cc: + try: + name, version = cc.split(":") + if name == ccinfo.basename: + min_cc_version = [int(v) for v in version.split('.')] + cur_cc_version = [int(v) for v in cc_min_version.split('.')] + # With lists of ints, this does what we want + return cur_cc_version >= min_cc_version + except ValueError: + # No version part specified + pass + + return False # compiler not listed + + return supported_isa_flags(ccinfo, arch) and supported_compiler(ccinfo, cc_min_version) + + def dependencies(self, osinfo): + # base is an implicit dep for all submodules + deps = ['base'] if self.parent_module != None: deps.append(self.parent_module) + + for req in self.requires: + if req.find('?') != -1: + (cond, dep) = req.split('?') + if osinfo is None or cond in osinfo.target_features: + deps.append(dep) + else: + deps.append(req) + return deps - """ - Ensure that all dependencies of this module actually exist, warning - about any that do not - """ def dependencies_exist(self, modules): - all_deps = [s.split('|') for s in self.dependencies()] + """ + Ensure that all dependencies of this module actually exist, warning + about any that do not + """ + + missing = [s for s in self.dependencies(None) if s not in modules] - for missing in [s for s in flatten(all_deps) if s not in modules]: - logging.warn("Module '%s', dep of '%s', does not exist" % ( + if missing: + logging.error("Module '%s', dep of '%s', does not exist" % ( missing, self.basename)) - def __cmp__(self, other): - if self.basename < other.basename: - return -1 - if self.basename == other.basename: - return 0 - return 1 -class ArchInfo(object): +class ModulePolicyInfo(InfoObject): + def __init__(self, infofile): + super(ModulePolicyInfo, self).__init__(infofile) + lex = lex_me_harder( + infofile, + ['required', 'if_available', 'prohibited'], + [], + {}) + + self.if_available = lex.if_available + self.required = lex.required + self.prohibited = lex.prohibited + + def cross_check(self, modules): + def check(tp, lst): + for mod in lst: + if mod not in modules: + logging.error("Module policy %s includes non-existent module %s in <%s>" % ( + self.infofile, mod, tp)) + + check('required', self.required) + check('if_available', self.if_available) + check('prohibited', self.prohibited) + + +class ArchInfo(InfoObject): + def __init__(self, infofile): + super(ArchInfo, self).__init__(infofile) + lex = lex_me_harder( + infofile, + ['aliases', 'isa_extensions'], + [], + { + 'endian': None, + 'family': None, + 'wordsize': 32 + }) + + self.aliases = lex.aliases + self.endian = lex.endian + self.family = lex.family + self.isa_extensions = lex.isa_extensions + self.wordsize = int(lex.wordsize) + + if self.wordsize not in [32, 64]: + logging.error('Unexpected wordsize %d for arch %s', self.wordsize, infofile) + + alphanumeric = re.compile('^[a-z0-9]+$') + for isa in self.isa_extensions: + if alphanumeric.match(isa) is None: + logging.error('Invalid name for ISA extension "%s"', isa) + + def supported_isa_extensions(self, cc, options): + isas = [] + + for isa in self.isa_extensions: + if isa not in options.disable_intrinsics: + if cc.isa_flags_for(isa, self.basename) is not None: + isas.append(isa) + + return sorted(isas) + + +class CompilerInfo(InfoObject): # pylint: disable=too-many-instance-attributes def __init__(self, infofile): - lex_me_harder(infofile, self, - ['aliases', 'submodels', 'submodel_aliases', 'isa_extn'], - { 'endian': None, - 'family': None, - 'unaligned': 'no' - }) + super(CompilerInfo, self).__init__(infofile) + lex = lex_me_harder( + infofile, + [], + ['cpu_flags', 'cpu_flags_no_debug', 'so_link_commands', 'binary_link_commands', + 'mach_abi_linking', 'isa_flags', 'sanitizers'], + { + 'binary_name': None, + 'linker_name': None, + 'macro_name': None, + 'output_to_object': '-o ', + 'output_to_exe': '-o ', + 'add_include_dir_option': '-I', + 'add_lib_dir_option': '-L', + 'add_sysroot_option': '', + 'add_lib_option': '-l', + 'add_framework_option': '-framework ', + 'preproc_flags': '-E', + 'compile_flags': '-c', + 'debug_info_flags': '-g', + 'optimization_flags': '', + 'size_optimization_flags': '', + 'sanitizer_optimization_flags': '', + 'coverage_flags': '', + 'stack_protector_flags': '', + 'shared_flags': '', + 'lang_flags': '', + 'warning_flags': '', + 'maintainer_warning_flags': '', + 'visibility_build_flags': '', + 'visibility_attribute': '', + 'ar_command': '', + 'ar_options': '', + 'ar_output_to': '', + }) + + self.add_framework_option = lex.add_framework_option + self.add_include_dir_option = lex.add_include_dir_option + self.add_lib_dir_option = lex.add_lib_dir_option + self.add_lib_option = lex.add_lib_option + self.add_sysroot_option = lex.add_sysroot_option + self.ar_command = lex.ar_command + self.ar_options = lex.ar_options + self.ar_output_to = lex.ar_output_to + self.binary_link_commands = lex.binary_link_commands + self.binary_name = lex.binary_name + self.cpu_flags = lex.cpu_flags + self.cpu_flags_no_debug = lex.cpu_flags_no_debug + self.compile_flags = lex.compile_flags + self.coverage_flags = lex.coverage_flags + self.debug_info_flags = lex.debug_info_flags + self.isa_flags = lex.isa_flags + self.lang_flags = lex.lang_flags + self.linker_name = lex.linker_name + self.mach_abi_linking = lex.mach_abi_linking + self.macro_name = lex.macro_name + self.maintainer_warning_flags = lex.maintainer_warning_flags + self.optimization_flags = lex.optimization_flags + self.output_to_exe = lex.output_to_exe + self.output_to_object = lex.output_to_object + self.preproc_flags = lex.preproc_flags + self.sanitizers = lex.sanitizers + self.sanitizer_types = [] + self.sanitizer_optimization_flags = lex.sanitizer_optimization_flags + self.shared_flags = lex.shared_flags + self.size_optimization_flags = lex.size_optimization_flags + self.so_link_commands = lex.so_link_commands + self.stack_protector_flags = lex.stack_protector_flags + self.visibility_attribute = lex.visibility_attribute + self.visibility_build_flags = lex.visibility_build_flags + self.warning_flags = lex.warning_flags + + def isa_flags_for(self, isa, arch): + if isa in self.isa_flags: + return self.isa_flags[isa] + arch_isa = '%s:%s' % (arch, isa) + if arch_isa in self.isa_flags: + return self.isa_flags[arch_isa] + return None + + def get_isa_specific_flags(self, isas, arch, options): + flags = set() + + def simd32_impl(): + for simd_isa in ['sse2', 'altivec', 'neon']: + if simd_isa in arch.isa_extensions and \ + simd_isa not in options.disable_intrinsics and \ + self.isa_flags_for(simd_isa, arch.basename): + return simd_isa + return None + + for isa in isas: + + if isa == 'simd': + isa = simd32_impl() + + if isa is None: + continue + + flagset = self.isa_flags_for(isa, arch.basename) + if flagset is None: + raise UserError('Compiler %s does not support %s' % (self.basename, isa)) + flags.add(flagset) + + return " ".join(sorted(flags)) - def convert_isa_list(input): - isa_info = {} - for line in self.isa_extn: - (isa,cpus) = line.split(':') - for cpu in cpus.split(','): - isa_info.setdefault(cpu, []).append(isa) - return isa_info + def gen_shared_flags(self, options): + """ + Return the shared library build flags, if any + """ - self.isa_extn = convert_isa_list(self.isa_extn) + def flag_builder(): + if options.build_shared_lib: + yield self.shared_flags + yield self.visibility_build_flags - self.submodel_aliases = force_to_dict(self.submodel_aliases) + return ' '.join(list(flag_builder())) - self.unaligned_ok = (1 if self.unaligned == 'ok' else 0) + def gen_visibility_attribute(self, options): + if options.build_shared_lib: + return self.visibility_attribute + return '' - """ - Return ISA extensions specific to this CPU - """ - def isa_extensions_in(self, cpu_type): - return sorted(self.isa_extn.get(cpu_type, []) + - self.isa_extn.get('all', [])) + def mach_abi_link_flags(self, options, with_debug_info=None): + #pylint: disable=too-many-branches - """ - Return a list of all submodels for this arch, ordered longest - to shortest - """ - def all_submodels(self): - return sorted([(k,k) for k in self.submodels] + - [k for k in self.submodel_aliases.items()], - key = lambda k: len(k[0]), reverse = True) + """ + Return the machine specific ABI flags + """ - """ - Return CPU-specific defines for build.h - """ - def defines(self, options): - def form_macro(cpu_name): - return cpu_name.upper().replace('.', '').replace('-', '_') + if with_debug_info is None: + with_debug_info = options.with_debug_info - macros = ['TARGET_ARCH_IS_%s' % - (form_macro(self.basename.upper()))] + def mach_abi_groups(): - if self.basename != options.cpu: - macros.append('TARGET_CPU_IS_%s' % (form_macro(options.cpu))) + yield 'all' - enabled_isas = set(self.isa_extensions_in(options.cpu) + - options.enable_isa_extns) - disabled_isas = set(options.disable_isa_extns) + if options.msvc_runtime is None: + if with_debug_info: + yield 'rt-debug' + else: + yield 'rt' - isa_extensions = sorted(enabled_isas - disabled_isas) + for all_except in [s for s in self.mach_abi_linking.keys() if s.startswith('all!')]: + exceptions = all_except[4:].split(',') + if options.os not in exceptions and options.arch not in exceptions: + yield all_except - for isa in isa_extensions: - macros.append('TARGET_CPU_HAS_%s' % (form_macro(isa))) + yield options.os + yield options.cpu - endian = options.with_endian or self.endian + abi_link = set() + 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: + abi_link.add(flag) - if endian != None: - macros.append('TARGET_CPU_IS_%s_ENDIAN' % (endian.upper())) - logging.info('Assuming CPU is %s endian' % (endian)) + if options.msvc_runtime: + abi_link.add("/" + options.msvc_runtime) - unaligned_ok = options.unaligned_mem - if unaligned_ok is None: - unaligned_ok = self.unaligned_ok - if unaligned_ok: - logging.info('Assuming unaligned memory access works') + if options.with_stack_protector and self.stack_protector_flags != '': + abi_link.add(self.stack_protector_flags) - if self.family is not None: - macros.append('TARGET_CPU_IS_%s_FAMILY' % (self.family.upper())) + if options.with_coverage_info: + if self.coverage_flags == '': + raise UserError('No coverage handling for %s' % (self.basename)) + abi_link.add(self.coverage_flags) - macros.append('TARGET_UNALIGNED_MEMORY_ACCESS_OK %d' % (unaligned_ok)) + if options.with_sanitizers or options.enable_sanitizers != '': + if not self.sanitizers: + raise UserError('No sanitizer handling for %s' % (self.basename)) - return macros + default_san = self.sanitizers['default'].split(',') -class CompilerInfo(object): - def __init__(self, infofile): - lex_me_harder(infofile, self, - ['so_link_flags', 'mach_opt', 'mach_abi_linking'], - { 'binary_name': None, - 'macro_name': None, - 'compile_option': '-c ', - 'output_to_option': '-o ', - 'add_include_dir_option': '-I', - 'add_lib_dir_option': '-L', - 'add_lib_option': '-l', - 'lib_opt_flags': '', - 'check_opt_flags': '', - 'debug_flags': '', - 'no_debug_flags': '', - 'shared_flags': '', - 'lang_flags': '', - 'warning_flags': '', - 'maintainer_warning_flags': '', - 'visibility_build_flags': '', - 'visibility_attribute': '', - 'ar_command': None, - 'makefile_style': '', - 'has_tr1': False, - }) - - self.so_link_flags = force_to_dict(self.so_link_flags) - self.mach_abi_linking = force_to_dict(self.mach_abi_linking) - - self.mach_opt_flags = {} - - while self.mach_opt != []: - proc = self.mach_opt.pop(0) - if self.mach_opt.pop(0) != '->': - raise Exception('Parsing err in %s mach_opt' % (self.basename)) - - flags = self.mach_opt.pop(0) - regex = '' - - if len(self.mach_opt) > 0 and \ - (len(self.mach_opt) == 1 or self.mach_opt[1] != '->'): - regex = self.mach_opt.pop(0) - - self.mach_opt_flags[proc] = (flags,regex) - - del self.mach_opt + if options.enable_sanitizers: + san = options.enable_sanitizers.split(',') + else: + san = default_san - """ - Return the shared library build flags, if any - """ - def gen_shared_flags(self, options): - def flag_builder(): - if options.build_shared_lib: - yield self.shared_flags - if options.with_visibility: - yield self.visibility_build_flags + for s in san: + if s not in self.sanitizers: + raise UserError('No flags defined for sanitizer %s in %s' % (s, self.basename)) - return ' '.join(list(flag_builder())) + if s == 'default': + abi_link.update([self.sanitizers[s] for s in default_san]) + else: + abi_link.add(self.sanitizers[s]) - def gen_visibility_attribute(self, options): - if options.build_shared_lib and options.with_visibility: - return self.visibility_attribute - return '' + self.sanitizer_types = san - """ - Return the machine specific ABI flags - """ - def mach_abi_link_flags(self, osname, arch, submodel, debug_p): + if options.with_openmp: + if 'openmp' not in self.mach_abi_linking: + raise UserError('No support for OpenMP for %s' % (self.basename)) + abi_link.add(self.mach_abi_linking['openmp']) - def all(): - if debug_p: - return 'all-debug' - return 'all' + abi_flags = ' '.join(sorted(abi_link)) - abi_link = set() - for what in [all(), osname, arch, submodel]: - if self.mach_abi_linking.get(what) != None: - abi_link.add(self.mach_abi_linking.get(what)) + if options.cc_abi_flags != '': + abi_flags += ' ' + options.cc_abi_flags - if len(abi_link) == 0: - return '' - return ' ' + ' '.join(abi_link) + return abi_flags - """ - Return the flags for MACH_OPT - """ - def mach_opts(self, arch, submodel): + def cc_warning_flags(self, options): + def gen_flags(): + yield self.warning_flags + if options.maintainer_mode: + yield self.maintainer_warning_flags - def submodel_fixup(tup): - return tup[0].replace('SUBMODEL', submodel.replace(tup[1], '')) + return (' '.join(gen_flags())).strip() - if submodel == arch: - return '' + def cc_lang_flags(self): + return self.lang_flags - if submodel in self.mach_opt_flags: - return submodel_fixup(self.mach_opt_flags[submodel]) - if arch in self.mach_opt_flags: - return submodel_fixup(self.mach_opt_flags[arch]) + def cc_compile_flags(self, options, with_debug_info=None, enable_optimizations=None): + def gen_flags(with_debug_info, enable_optimizations): - return '' + sanitizers_enabled = options.with_sanitizers or (len(options.enable_sanitizers) > 0) - """ - Return the flags for LIB_OPT - """ - def library_opt_flags(self, options): - def gen_flags(): - if options.debug_build: - yield self.debug_flags + if with_debug_info is None: + with_debug_info = options.with_debug_info + if enable_optimizations is None: + enable_optimizations = not options.no_optimizations + + if with_debug_info: + yield self.debug_info_flags - if not options.no_optimizations: - yield self.lib_opt_flags + if enable_optimizations: + if options.optimize_for_size: + if self.size_optimization_flags != '': + yield self.size_optimization_flags + else: + logging.warning("No size optimization flags set for current compiler") + yield self.optimization_flags + elif sanitizers_enabled and self.sanitizer_optimization_flags != '': + yield self.sanitizer_optimization_flags + else: + yield self.optimization_flags - if not options.debug_build: - yield self.no_debug_flags + if options.arch in self.cpu_flags: + yield self.cpu_flags[options.arch] - return (' '.join(gen_flags())).strip() + if options.arch in self.cpu_flags_no_debug: - """ - Return the command needed to link a shared object - """ - def so_link_command_for(self, osname): - if osname in self.so_link_flags: - return self.so_link_flags[osname] - if 'default' in self.so_link_flags: - return self.so_link_flags['default'] - return '' + # Only enable these if no debug/sanitizer options enabled - """ - Return defines for build.h - """ - def defines(self, with_tr1): - - def tr1_macro(): - if with_tr1: - if with_tr1 == 'boost': - return ['USE_BOOST_TR1'] - elif with_tr1 == 'system': - return ['USE_STD_TR1'] - elif self.has_tr1: - return ['USE_STD_TR1'] - return [] + if not (options.debug_mode or sanitizers_enabled): + yield self.cpu_flags_no_debug[options.arch] + + return (' '.join(gen_flags(with_debug_info, enable_optimizations))).strip() + + @staticmethod + def _so_link_search(osname, debug_info): + so_link_typ = [osname, 'default'] + if debug_info: + so_link_typ = [l + '-debug' for l in so_link_typ] + so_link_typ + return so_link_typ + + def so_link_command_for(self, osname, options): + """ + Return the command needed to link a shared object + """ + + for s in self._so_link_search(osname, options.with_debug_info): + if s in self.so_link_commands: + return self.so_link_commands[s] + + raise InternalError( + "No shared library link command found for target '%s' in compiler settings '%s'" % + (osname, self.infofile)) + + def binary_link_command_for(self, osname, options): + """ + Return the command needed to link an app/test object + """ + + for s in self._so_link_search(osname, options.with_debug_info): + if s in self.binary_link_commands: + return self.binary_link_commands[s] - return ['BUILD_COMPILER_IS_' + self.macro_name] + tr1_macro() + return '$(LINKER)' -class OsInfo(object): +class OsInfo(InfoObject): # pylint: disable=too-many-instance-attributes def __init__(self, infofile): - lex_me_harder(infofile, self, - ['aliases', 'target_features'], - { 'os_type': None, - 'obj_suffix': 'o', - 'so_suffix': 'so', - 'static_suffix': 'a', - 'ar_command': 'ar crs', - 'ar_needs_ranlib': False, - 'install_root': '/usr/local', - 'header_dir': 'include', - 'lib_dir': 'lib', - 'doc_dir': 'share/doc', - 'build_shared': 'yes', - 'install_cmd_data': 'install -m 644', - 'install_cmd_exec': 'install -m 755' - }) - - self.ar_needs_ranlib = bool(self.ar_needs_ranlib) - - self.build_shared = (True if self.build_shared == 'yes' else False) - - def ranlib_command(self): - return ('ranlib' if self.ar_needs_ranlib else 'true') + super(OsInfo, self).__init__(infofile) + lex = lex_me_harder( + infofile, + ['aliases', 'target_features'], + [], + { + 'program_suffix': '', + 'obj_suffix': 'o', + 'soname_suffix': '', + 'soname_pattern_patch': '', + 'soname_pattern_abi': '', + 'soname_pattern_base': '', + 'static_suffix': 'a', + 'ar_command': 'ar', + 'ar_options': '', + 'ar_output_to': '', + 'install_root': '/usr/local', + 'header_dir': 'include', + 'bin_dir': 'bin', + 'lib_dir': 'lib', + 'doc_dir': 'share/doc', + 'man_dir': 'share/man', + 'use_stack_protector': 'true', + 'so_post_link_command': '', + 'cli_exe_name': 'botan', + 'lib_prefix': 'lib', + 'library_name': 'botan{suffix}-{major}', + }) + + if lex.ar_command == 'ar' and lex.ar_options == '': + lex.ar_options = 'crs' + + if lex.soname_pattern_base: + self.soname_pattern_base = lex.soname_pattern_base + if lex.soname_pattern_patch == '' and lex.soname_pattern_abi == '': + self.soname_pattern_patch = lex.soname_pattern_base + self.soname_pattern_abi = lex.soname_pattern_base + elif lex.soname_pattern_abi != '' and lex.soname_pattern_abi != '': + self.soname_pattern_patch = lex.soname_pattern_patch + self.soname_pattern_abi = lex.soname_pattern_abi + else: + # base set, only one of patch/abi set + raise InternalError("Invalid soname_patterns in %s" % (self.infofile)) + else: + if lex.soname_suffix: + self.soname_pattern_base = "libbotan{lib_suffix}-{version_major}.%s" % (lex.soname_suffix) + self.soname_pattern_abi = self.soname_pattern_base + ".{abi_rev}" + self.soname_pattern_patch = self.soname_pattern_abi + ".{version_minor}.{version_patch}" + else: + # Could not calculate soname_pattern_* + # This happens for OSs without shared library support (e.g. nacl, mingw, includeos, cygwin) + self.soname_pattern_base = None + self.soname_pattern_abi = None + self.soname_pattern_patch = None + + self._aliases = lex.aliases + self.ar_command = lex.ar_command + self.ar_options = lex.ar_options + self.bin_dir = lex.bin_dir + self.cli_exe_name = lex.cli_exe_name + self.doc_dir = lex.doc_dir + self.header_dir = lex.header_dir + self.install_root = lex.install_root + self.lib_dir = lex.lib_dir + self.lib_prefix = lex.lib_prefix + self.library_name = lex.library_name + self.man_dir = lex.man_dir + self.obj_suffix = lex.obj_suffix + self.program_suffix = lex.program_suffix + self.so_post_link_command = lex.so_post_link_command + self.static_suffix = lex.static_suffix + self.target_features = lex.target_features + self.use_stack_protector = (lex.use_stack_protector == "true") + + def matches_name(self, nm): + if nm in self._aliases: + return True - def defines(self): - return ['TARGET_OS_IS_%s' % (self.basename.upper())] + \ - ['TARGET_OS_HAS_' + feat.upper() - for feat in sorted(self.target_features)] + for alias in self._aliases: + if re.match(alias, nm): + return True + return False + + def building_shared_supported(self): + return self.soname_pattern_base != None + + def enabled_features(self, options): + feats = [] + for feat in self.target_features: + if feat not in options.without_os_features: + feats.append(feat) + for feat in options.with_os_features: + if feat not in self.target_features: + feats.append(feat) + + return sorted(feats) def fixup_proc_name(proc): proc = proc.lower().replace(' ', '') @@ -941,711 +1443,1152 @@ def canon_processor(archinfo, proc): # First, try to search for an exact match for ainfo in archinfo.values(): if ainfo.basename == proc or proc in ainfo.aliases: - return (ainfo.basename, ainfo.basename) + return ainfo.basename - for (match,submodel) in ainfo.all_submodels(): - if proc == submodel or proc == match: - return (ainfo.basename, submodel) + return None - logging.debug('Could not find an exact match for CPU "%s"' % (proc)) - - # Now, try searching via regex match - for ainfo in archinfo.values(): - for (match,submodel) in ainfo.all_submodels(): - if re.search(match, proc) != None: - logging.debug('Possible match "%s" with "%s" (%s)' % ( - proc, match, submodel)) - return (ainfo.basename, submodel) +def system_cpu_info(): - logging.debug('Known CPU names: ' + ' '.join( - sorted(flatten([[ainfo.basename] + \ - ainfo.aliases + \ - [x for (x,_) in ainfo.all_submodels()] - for ainfo in archinfo.values()])))) + cpu_info = [] - raise Exception('Unknown or unidentifiable processor "%s"' % (proc)) + if platform.machine() != '': + cpu_info.append(platform.machine()) -def guess_processor(archinfo): - base_proc = platform.machine() + if platform.processor() != '': + cpu_info.append(platform.processor()) - if base_proc == '': - raise Exception('Could not determine target CPU; set with --cpu') + if 'uname' in os.__dict__: + cpu_info.append(os.uname()[4]) - full_proc = fixup_proc_name(platform.processor()) or base_proc + return cpu_info - for ainfo in archinfo.values(): - if ainfo.basename == base_proc or base_proc in ainfo.aliases: - for (match,submodel) in ainfo.all_submodels(): - if re.search(match, full_proc) != None: - return (ainfo.basename, submodel) +def guess_processor(archinfo): + for info_part in system_cpu_info(): + if info_part: + match = canon_processor(archinfo, info_part) + if match != None: + logging.debug("Matched '%s' to processor '%s'" % (info_part, match)) + return match, info_part + else: + logging.debug("Failed to deduce CPU from '%s'" % info_part) - return canon_processor(archinfo, ainfo.basename) + raise UserError('Could not determine target CPU; set with --cpu') - # No matches, so just use the base proc type - return canon_processor(archinfo, base_proc) -""" -Read a whole file into memory as a string -""" -def slurp_file(filename): - if filename is None: +def read_textfile(filepath): + """ + Read a whole file into memory as a string + """ + if filepath is None: return '' - return ''.join(open(filename).readlines()) -""" -Perform template substitution -""" -def process_template(template_file, variables): - class PercentSignTemplate(string.Template): - delimiter = '%' + with open(filepath) as f: + return ''.join(f.readlines()) - try: - template = PercentSignTemplate(slurp_file(template_file)) - return template.substitute(variables) - except KeyError as e: - raise Exception('Unbound var %s in template %s' % (e, template_file)) -""" -Create the template variables needed to process the makefile, build.h, etc -""" -def create_template_vars(build_config, options, modules, cc, arch, osinfo): - def make_cpp_macros(macros): - return '\n'.join(['#define BOTAN_' + macro for macro in macros]) +def process_template(template_file, variables): + # pylint: disable=too-many-branches,too-many-statements """ - Figure out what external libraries are needed based on selected modules + Perform template substitution + + The template language supports (un-nested) conditionals. """ - def link_to(): - libs = set() - for module in modules: - for (osname,link_to) in module.libs.items(): - if osname == 'all' or osname == osinfo.basename: - libs |= set(link_to) + class SimpleTemplate(object): + + def __init__(self, vals): + self.vals = vals + self.value_pattern = re.compile(r'%{([a-z][a-z_0-9\|]+)}') + self.cond_pattern = re.compile('%{(if|unless) ([a-z][a-z_0-9]+)}') + self.for_pattern = re.compile('(.*)%{for ([a-z][a-z_0-9]+)}') + self.join_pattern = re.compile('(.*)%{join ([a-z][a-z_0-9]+)}') + + def substitute(self, template): + # pylint: disable=too-many-locals + def insert_value(match): + v = match.group(1) + if v in self.vals: + return str(self.vals.get(v)) + if v.endswith('|upper'): + v = v.replace('|upper', '') + if v in self.vals: + return str(self.vals.get(v)).upper() + + raise KeyError(v) + + lines = template.splitlines() + + output = "" + idx = 0 + + while idx < len(lines): + cond_match = self.cond_pattern.match(lines[idx]) + join_match = self.join_pattern.match(lines[idx]) + for_match = self.for_pattern.match(lines[idx]) + + if cond_match: + cond_type = cond_match.group(1) + cond_var = cond_match.group(2) + + include_cond = False + + if cond_type == 'if' and cond_var in self.vals and self.vals.get(cond_var): + include_cond = True + elif cond_type == 'unless' and (cond_var not in self.vals or (not self.vals.get(cond_var))): + include_cond = True + + idx += 1 + while idx < len(lines): + if lines[idx] == '%{endif}': + break + if include_cond: + output += lines[idx] + "\n" + idx += 1 + elif join_match: + join_var = join_match.group(2) + join_str = ' ' + join_line = '%%{join %s}' % (join_var) + output += lines[idx].replace(join_line, join_str.join(self.vals[join_var])) + "\n" + elif for_match: + for_prefix = for_match.group(1) + output += for_prefix + for_var = for_match.group(2) + + if for_var not in self.vals: + raise InternalError("Unknown for loop iteration variable '%s'" % (for_var)) + + var = self.vals[for_var] + if not isinstance(var, list): + raise InternalError("For loop iteration variable '%s' is not a list" % (for_var)) + idx += 1 + + for_body = "" + while idx < len(lines): + if lines[idx] == '%{endfor}': + break + for_body += lines[idx] + "\n" + idx += 1 + + for v in var: + if isinstance(v, dict): + for_val = for_body + for ik, iv in v.items(): + for_val = for_val.replace('%{' + ik + '}', iv) + output += for_val + "\n" + else: + output += for_body.replace('%{i}', v).replace('%{i|upper}', v.upper()) + output += "\n" else: - match = re.match('^all!(.*)', osname) - if match is not None: - exceptions = match.group(1).split(',') - if osinfo.basename not in exceptions: - libs |= set(link_to) - return sorted(libs) + output += lines[idx] + "\n" + idx += 1 - def objectfile_list(sources, obj_dir): - for src in sources: - (dir,file) = os.path.split(os.path.normpath(src)) + return self.value_pattern.sub(insert_value, output) + '\n' - if dir.startswith('src'): - parts = dir.split(os.sep)[1:] - if file == parts[-1] + '.cpp': - name = '_'.join(dir.split(os.sep)[1:]) + '.cpp' - else: - name = '_'.join(dir.split(os.sep)[1:]) + '_' + file + try: + return SimpleTemplate(variables).substitute(read_textfile(template_file)) + except KeyError as e: + logging.error('Unbound var %s in template %s' % (e, template_file)) + except Exception as e: # pylint: disable=broad-except + logging.error('Exception %s during template processing file %s' % (e, template_file)) + +def yield_objectfile_list(sources, obj_dir, obj_suffix): + obj_suffix = '.' + obj_suffix + + for src in sources: + (directory, filename) = os.path.split(os.path.normpath(src)) + parts = directory.split(os.sep) + + if 'src' in parts: + parts = parts[parts.index('src')+2:] + elif filename.find('botan_all') != -1: + parts = [] + else: + raise InternalError("Unexpected file '%s/%s'" % (directory, filename)) + + if parts != []: + # Handle src/X/X.cpp -> X.o + if filename == parts[-1] + '.cpp': + name = '_'.join(parts) + '.cpp' else: - name = file + name = '_'.join(parts) + '_' + filename - for src_suffix in ['.cpp', '.S']: - name = name.replace(src_suffix, '.' + osinfo.obj_suffix) + def fixup_obj_name(name): + def remove_dups(parts): + last = None + for part in parts: + if last is None or part != last: + last = part + yield part - yield os.path.join(obj_dir, name) + return '_'.join(remove_dups(name.split('_'))) + name = fixup_obj_name(name) + else: + name = filename - def choose_mp_bits(): - mp_bits = [mod.mp_bits for mod in modules if mod.mp_bits != 0] + name = name.replace('.cpp', obj_suffix) + yield os.path.join(obj_dir, name) - if mp_bits == []: - return 32 # default +def generate_build_info(build_paths, modules, cc, arch, osinfo, options): + # pylint: disable=too-many-locals - # Check that settings are consistent across modules - for mp_bit in mp_bits[1:]: - if mp_bit != mp_bits[0]: - raise Exception('Incompatible mp_bits settings found') + # first create a map of src_file->owning module - return mp_bits[0] + module_that_owns = {} - """ - Form snippets of makefile for building each source file - """ - def build_commands(sources, obj_dir, flags): - for (obj_file,src) in zip(objectfile_list(sources, obj_dir), sources): - yield '%s: %s\n\t$(CXX) %s%s $(%s_FLAGS) %s$? %s$@\n' % ( - obj_file, src, - cc.add_include_dir_option, - build_config.include_dir, - flags, - cc.compile_option, - cc.output_to_option) - - def makefile_list(items): - items = list(items) # force evaluation so we can slice it - return (' '*16).join([item + ' \\\n' for item in items[:-1]] + - [items[-1]]) - - def prefix_with_build_dir(path): - if options.with_build_dir != None: - return os.path.join(options.with_build_dir, path) - return path - - def warning_flags(normal_flags, - maintainer_flags, - maintainer_mode): - if maintainer_mode and maintainer_flags != '': - return maintainer_flags - return normal_flags - - return { - 'version_major': build_config.version_major, - 'version_minor': build_config.version_minor, - 'version_patch': build_config.version_patch, - 'version_vc_rev': build_config.version_vc_rev, - 'so_abi_rev': build_config.version_so_rev, - 'version': build_config.version_string, + for mod in modules: + for src in mod.sources(): + module_that_owns[src] = mod - 'distribution_info': options.distribution_info, + def _isa_specific_flags(src): + if os.path.basename(src) == 'test_simd.cpp': + return cc.get_isa_specific_flags(['simd'], arch, options) - 'version_datestamp': build_config.version_datestamp, + if src in module_that_owns: + module = module_that_owns[src] + isas = module.need_isa + if 'simd' in module.dependencies(osinfo): + isas.append('simd') - 'timestamp': build_config.timestamp(), - 'user': build_config.username(), - 'hostname': build_config.hostname(), - 'command_line': ' '.join(sys.argv), - 'local_config': slurp_file(options.local_config), - 'makefile_style': options.makefile_style or cc.makefile_style, + return cc.get_isa_specific_flags(isas, arch, options) - 'makefile_path': prefix_with_build_dir('Makefile'), + if src.startswith('botan_all_'): + isas = src.replace('botan_all_', '').replace('.cpp', '').split('_') + return cc.get_isa_specific_flags(isas, arch, options) - 'prefix': options.prefix or osinfo.install_root, - 'libdir': options.libdir or osinfo.lib_dir, - 'includedir': options.includedir or osinfo.header_dir, - 'docdir': options.docdir or osinfo.doc_dir, + return '' - 'build_dir': build_config.build_dir, - 'doc_output_dir': build_config.doc_output_dir, + def _build_info(sources, objects, target_type): + output = [] + for (obj_file, src) in zip(objects, sources): + info = { + 'src': src, + 'obj': obj_file, + 'isa_flags': _isa_specific_flags(src) + } - 'build_doc_commands': build_config.build_doc_commands, + if target_type == 'fuzzer': + fuzz_basename = os.path.basename(obj_file).replace('.' + osinfo.obj_suffix, '') + info['exe'] = os.path.join(build_paths.fuzzer_output_dir, fuzz_basename) - 'python_dir': build_config.python_dir, + output.append(info) - 'os': options.os, - 'arch': options.arch, - 'submodel': options.cpu, + return output - 'mp_bits': choose_mp_bits(), + out = {} - 'cc': (options.compiler_binary or cc.binary_name) + - cc.mach_abi_link_flags(options.os, options.arch, - options.cpu, options.debug_build), + targets = ['lib', 'cli', 'test', 'fuzzer'] - 'lib_opt': cc.library_opt_flags(options), - 'mach_opt': cc.mach_opts(options.arch, options.cpu), - 'check_opt': '' if options.no_optimizations else cc.check_opt_flags, - 'lang_flags': cc.lang_flags + options.extra_flags, - 'warn_flags': warning_flags(cc.warning_flags, - cc.maintainer_warning_flags, - options.maintainer_mode), + out['isa_build_info'] = [] - 'shared_flags': cc.gen_shared_flags(options), - 'visibility_attribute': cc.gen_visibility_attribute(options), + fuzzer_bin = [] + for t in targets: + src_list, src_dir = build_paths.src_info(t) - 'so_link': cc.so_link_command_for(osinfo.basename), + src_key = '%s_srcs' % (t) + obj_key = '%s_objs' % (t) + build_key = '%s_build_info' % (t) - 'link_to': ' '.join([cc.add_lib_option + lib for lib in link_to()]), + objects = [] + build_info = [] - 'module_defines': make_cpp_macros(sorted(flatten([m.defines() for m in modules]))), + if src_list is not None: + src_list.sort() + objects = list(yield_objectfile_list(src_list, src_dir, osinfo.obj_suffix)) + build_info = _build_info(src_list, objects, t) - 'target_os_defines': make_cpp_macros(osinfo.defines()), + for b in build_info: + if b['isa_flags'] != '': + out['isa_build_info'].append(b) - 'target_compiler_defines': make_cpp_macros( - cc.defines(options.with_tr1)), + if t == 'fuzzer': + fuzzer_bin = [b['exe'] for b in build_info] - 'target_cpu_defines': make_cpp_macros(arch.defines(options)), + out[src_key] = src_list if src_list else [] + out[obj_key] = objects + out[build_key] = build_info - 'include_files': makefile_list(build_config.public_headers), + out['fuzzer_bin'] = ' '.join(fuzzer_bin) + out['cli_headers'] = build_paths.cli_headers - 'lib_objs': makefile_list( - objectfile_list(build_config.build_sources, - build_config.libobj_dir)), + return out - 'check_objs': makefile_list( - objectfile_list(build_config.check_sources, - build_config.checkobj_dir)), +def create_template_vars(source_paths, build_paths, options, modules, cc, arch, osinfo): + #pylint: disable=too-many-locals,too-many-branches,too-many-statements - 'lib_build_cmds': '\n'.join( - build_commands(build_config.build_sources, - build_config.libobj_dir, 'LIB')), + """ + Create the template variables needed to process the makefile, build.h, etc + """ - 'check_build_cmds': '\n'.join( - build_commands(build_config.check_sources, - build_config.checkobj_dir, 'CHECK')), + def external_link_cmd(): + return (' ' + cc.add_lib_dir_option + options.with_external_libdir) if options.with_external_libdir else '' - 'python_obj_dir': build_config.pyobject_dir, + def link_to(module_member_name): + """ + Figure out what external libraries/frameworks are needed based on selected modules + """ + if not (module_member_name == 'libs' or module_member_name == 'frameworks'): + raise InternalError("Invalid argument") - 'python_objs': makefile_list( - objectfile_list(build_config.python_sources, - build_config.pyobject_dir)), + 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: + libs |= set(module_link_to) + else: + match = re.match('^all!(.*)', osname) + if match is not None: + exceptions = match.group(1).split(',') + if osinfo.basename not in exceptions: + libs |= set(module_link_to) - 'python_build_cmds': '\n'.join( - build_commands(build_config.python_sources, - build_config.pyobject_dir, 'PYTHON')), + return sorted(libs) - 'ar_command': cc.ar_command or osinfo.ar_command, - 'ranlib_command': osinfo.ranlib_command(), - 'install_cmd_exec': osinfo.install_cmd_exec, - 'install_cmd_data': osinfo.install_cmd_data, + def choose_mp_bits(): + mp_bits = arch.wordsize # allow command line override? + logging.debug('Using MP bits %d' % (mp_bits)) + return mp_bits + + def innosetup_arch(os_name, arch): + if os_name == 'windows': + inno_arch = {'x86_32': '', 'x86_64': 'x64', 'ia64': 'ia64'} + if arch in inno_arch: + return inno_arch[arch] + else: + logging.warning('Unknown arch in innosetup_arch %s' % (arch)) + return None - 'check_prefix': prefix_with_build_dir(''), - 'lib_prefix': prefix_with_build_dir(''), + def configure_command_line(): + # Cut absolute path from main executable (e.g. configure.py or python interpreter) + # to get the same result when configuring the same thing on different machines + main_executable = os.path.basename(sys.argv[0]) + return ' '.join([main_executable] + sys.argv[1:]) - 'static_suffix': osinfo.static_suffix, - 'so_suffix': osinfo.so_suffix, + def cmake_escape(s): + return s.replace('(', '\\(').replace(')', '\\)') - 'botan_config': prefix_with_build_dir( - os.path.join(build_config.build_dir, - build_config.config_shell_script())), + def sysroot_option(): + if options.with_sysroot_dir == '': + return '' + if cc.add_sysroot_option == '': + logging.error("This compiler doesn't support --sysroot option") + return cc.add_sysroot_option + options.with_sysroot_dir - 'botan_pkgconfig': prefix_with_build_dir( - os.path.join(build_config.build_dir, - build_config.pkg_config_file())), + def ar_command(): + if options.ar_command: + return options.ar_command - 'mod_list': '\n'.join(sorted([m.basename for m in modules])), + if cc.ar_command: + if cc.ar_command == cc.binary_name: + return options.compiler_binary or cc.binary_name + else: + return cc.ar_command - 'python_version': options.python_version - } + return osinfo.ar_command -""" -Determine which modules to load based on options, target, etc -""" -def choose_modules_to_use(modules, archinfo, options): + def choose_endian(arch_info, options): + if options.with_endian != None: + return options.with_endian - for mod in modules.values(): - mod.dependencies_exist(modules) + if options.cpu.endswith('eb') or options.cpu.endswith('be'): + return 'big' + elif options.cpu.endswith('el') or options.cpu.endswith('le'): + return 'little' - to_load = [] - maybe_dep = [] - not_using_because = {} + logging.info('Defaulting to assuming %s endian', arch_info.endian) + return arch_info.endian - def cannot_use_because(mod, reason): - not_using_because.setdefault(reason, []).append(mod) + build_dir = options.with_build_dir or os.path.curdir + program_suffix = options.program_suffix or osinfo.program_suffix - for modname in options.enabled_modules: - if modname not in modules: - logging.warning("Unknown enabled module %s" % (modname)) + def join_with_build_dir(path): + # For some unknown reason MinGW doesn't like ./foo + if build_dir == os.path.curdir and options.os == 'mingw': + return path + return os.path.join(build_dir, path) - for modname in options.disabled_modules: - if modname not in modules: - logging.warning("Unknown disabled module %s" % (modname)) + def shared_lib_uses_symlinks(): + if options.os in ['windows', 'openbsd']: + return False + return True - for (modname, module) in modules.items(): - if modname in options.disabled_modules: - cannot_use_because(modname, 'disabled by user') - elif modname in options.enabled_modules: - to_load.append(modname) # trust the user + variables = { + 'version_major': Version.major(), + 'version_minor': Version.minor(), + 'version_patch': Version.patch(), + 'version_vc_rev': Version.vc_rev(), + 'abi_rev': Version.so_rev(), - elif not module.compatible_os(options.os): - cannot_use_because(modname, 'incompatible OS') - elif not module.compatible_compiler(options.compiler): - cannot_use_because(modname, 'incompatible compiler') - elif not module.compatible_cpu(archinfo, options): - cannot_use_because(modname, 'incompatible CPU') - elif not module.tr1_ok(options.with_tr1): - cannot_use_because(modname, 'missing TR1') + 'version': Version.as_string(), + 'release_type': Version.release_type(), + 'version_datestamp': Version.datestamp(), - else: - if module.load_on == 'never': - cannot_use_because(modname, 'disabled as buggy') - elif module.load_on == 'request': - cannot_use_because(modname, 'by request only') - elif module.load_on == 'dep': - maybe_dep.append(modname) - - elif module.load_on == 'always': - to_load.append(modname) - - elif module.load_on == 'asm_ok': - if options.asm_ok: - if options.no_autoload: - maybe_dep.append(modname) - else: - to_load.append(modname) - else: - cannot_use_because(modname, - 'uses assembly and --disable-asm set') - elif module.load_on == 'auto': - if options.no_autoload: - maybe_dep.append(modname) - else: - to_load.append(modname) - else: - logging.warning('Unknown load_on %s in %s' % ( - module.load_on, modname)) + 'distribution_info': options.distribution_info, - dependency_failure = True + 'darwin_so_compat_ver': '%s.%s.0' % (Version.packed(), Version.so_rev()), + 'darwin_so_current_ver': '%s.%s.%s' % (Version.packed(), Version.so_rev(), Version.patch()), - while dependency_failure: - dependency_failure = False - for modname in to_load: - for deplist in [s.split('|') for s in modules[modname].dependencies()]: + 'base_dir': source_paths.base_dir, + 'src_dir': source_paths.src_dir, + 'doc_dir': source_paths.doc_dir, + 'scripts_dir': normalize_source_path(source_paths.scripts_dir), + 'python_dir': source_paths.python_dir, - dep_met = False - for mod in deplist: - if dep_met is True: - break + 'cli_exe_name': osinfo.cli_exe_name + program_suffix, + 'cli_exe': join_with_build_dir(osinfo.cli_exe_name + program_suffix), + 'test_exe': join_with_build_dir('botan-test' + program_suffix), - if mod in to_load: - dep_met = True - elif mod in maybe_dep: - maybe_dep.remove(mod) - to_load.append(mod) - dep_met = True + 'lib_prefix': osinfo.lib_prefix, + 'static_suffix': osinfo.static_suffix, + 'lib_suffix': options.library_suffix, + 'libname': osinfo.library_name.format(major=Version.major(), + minor=Version.minor(), + suffix=options.library_suffix), - if dep_met == False: - dependency_failure = True - if modname in to_load: - to_load.remove(modname) - if modname in maybe_dep: - maybe_dep.remove(modname) - cannot_use_because(modname, 'dependency failure') + 'command_line': configure_command_line(), + 'local_config': read_textfile(options.local_config), - for not_a_dep in maybe_dep: - cannot_use_because(not_a_dep, 'loaded only if needed by dependency') + 'program_suffix': program_suffix, - for reason in sorted(not_using_because.keys()): - disabled_mods = sorted(set([mod for mod in not_using_because[reason]])) + 'prefix': options.prefix or osinfo.install_root, + 'bindir': options.bindir or osinfo.bin_dir, + 'libdir': options.libdir or osinfo.lib_dir, + 'mandir': options.mandir or osinfo.man_dir, + 'includedir': options.includedir or osinfo.header_dir, + 'docdir': options.docdir or osinfo.doc_dir, - if disabled_mods != []: - logging.info('Skipping, %s - %s' % ( - reason, ' '.join(disabled_mods))) + 'with_documentation': options.with_documentation, + 'with_sphinx': options.with_sphinx, + 'with_pdf': options.with_pdf, + 'with_rst2man': options.with_rst2man, + 'sphinx_config_dir': source_paths.sphinx_config_dir, + 'with_doxygen': options.with_doxygen, - for mod in sorted(to_load): - if mod.startswith('mp_'): - logging.info('Using MP module ' + mod) - if mod.startswith('simd_') and mod != 'simd_engine': - logging.info('Using SIMD module ' + mod) - if modules[mod].comment: - logging.info('%s: %s' % (mod, modules[mod].comment)) + 'out_dir': build_dir, + 'build_dir': build_paths.build_dir, - logging.debug('Loading modules %s', ' '.join(sorted(to_load))) + 'doc_stamp_file': os.path.join(build_paths.build_dir, 'doc.stamp'), + 'makefile_path': os.path.join(build_paths.build_dir, '..', 'Makefile'), - return [modules[mod] for mod in to_load] + 'build_static_lib': options.build_static_lib, + 'build_shared_lib': options.build_shared_lib, -""" -Load the info files about modules, targets, etc -""" -def load_info_files(options): + 'build_fuzzers': options.build_fuzzers, - def find_files_named(desired_name, in_path): - for (dirpath, dirnames, filenames) in os.walk(in_path): - if desired_name in filenames: - yield os.path.join(dirpath, desired_name) + 'build_coverage' : options.with_coverage_info or options.with_coverage, - modules = dict([(mod.basename, mod) for mod in - [ModuleInfo(info) for info in - find_files_named('info.txt', options.src_dir)]]) + 'symlink_shared_lib': options.build_shared_lib and shared_lib_uses_symlinks(), - def list_files_in_build_data(subdir): - for (dirpath, dirnames, filenames) in \ - os.walk(os.path.join(options.build_data, subdir)): - for filename in filenames: - if filename.endswith('.txt'): - yield os.path.join(dirpath, filename) + 'libobj_dir': build_paths.libobj_dir, + 'cliobj_dir': build_paths.cliobj_dir, + 'testobj_dir': build_paths.testobj_dir, + 'fuzzobj_dir': build_paths.fuzzobj_dir, - def form_name(filepath): - return os.path.basename(filepath).replace('.txt', '') + 'fuzzer_output_dir': build_paths.fuzzer_output_dir if build_paths.fuzzer_output_dir else '', + 'doc_output_dir': build_paths.doc_output_dir, + 'doc_output_dir_manual': build_paths.doc_output_dir_manual, + 'doc_output_dir_doxygen': build_paths.doc_output_dir_doxygen, - archinfo = dict([(form_name(info), ArchInfo(info)) - for info in list_files_in_build_data('arch')]) + 'os': options.os, + 'arch': options.arch, + 'cpu_family': arch.family, + 'endian': choose_endian(arch, options), + 'cpu_is_64bit': arch.wordsize == 64, - osinfo = dict([(form_name(info), OsInfo(info)) - for info in list_files_in_build_data('os')]) + 'bakefile_arch': 'x86' if options.arch == 'x86_32' else 'x86_64', - ccinfo = dict([(form_name(info), CompilerInfo(info)) - for info in list_files_in_build_data('cc')]) + 'innosetup_arch': innosetup_arch(options.os, options.arch), - def info_file_load_report(type, num): - if num > 0: - logging.debug('Loaded %d %s info files' % (num, type)) - else: - logging.warning('Failed to load any %s info files' % (type)) + 'mp_bits': choose_mp_bits(), - info_file_load_report('CPU', len(archinfo)); - info_file_load_report('OS', len(osinfo)) - info_file_load_report('compiler', len(ccinfo)) + 'python_exe': os.path.basename(sys.executable), + 'python_version': options.python_version, - return (modules, archinfo, ccinfo, osinfo) + 'cxx': (options.compiler_binary or cc.binary_name), + 'cxx_abi_flags': cc.mach_abi_link_flags(options), + 'linker': cc.linker_name or '$(CXX)', + 'make_supports_phony': cc.basename != 'msvc', -""" -Perform the filesystem operations needed to setup the build -""" -def setup_build(build_config, options, template_vars): + 'sanitizer_types' : sorted(cc.sanitizer_types), - """ - Choose the link method based on system availablity and user request - """ - def choose_link_method(req_method): + 'cc_compile_opt_flags': cc.cc_compile_flags(options, False, True), + 'cc_compile_debug_flags': cc.cc_compile_flags(options, True, False), - def useable_methods(): - if 'symlink' in os.__dict__: - yield 'symlink' - if 'link' in os.__dict__: - yield 'hardlink' - yield 'copy' + # These are for CMake + 'cxx_abi_opt_flags': cc.mach_abi_link_flags(options, False), + 'cxx_abi_debug_flags': cc.mach_abi_link_flags(options, True), - for method in useable_methods(): - if req_method is None or req_method == method: - return method + 'dash_o': cc.output_to_object, + 'dash_c': cc.compile_flags, - logging.info('Could not use requested link method %s' % (req_method)) - return 'copy' + 'cc_lang_flags': cc.cc_lang_flags(), + 'cc_sysroot': sysroot_option(), + 'cc_compile_flags': options.cxxflags or cc.cc_compile_flags(options), + 'ldflags': options.ldflags or '', + 'cc_warning_flags': cc.cc_warning_flags(options), + 'output_to_exe': cc.output_to_exe, + 'cc_macro': cc.macro_name, - """ - Copy or link the file, depending on what the platform offers - """ - def portable_symlink(filename, target_dir, method): + 'shared_flags': cc.gen_shared_flags(options), + 'cmake_shared_flags': cmake_escape(cc.gen_shared_flags(options)), + 'visibility_attribute': cc.gen_visibility_attribute(options), - if not os.access(filename, os.R_OK): - logging.warning('Missing file %s' % (filename)) - return + 'lib_link_cmd': cc.so_link_command_for(osinfo.basename, options) + external_link_cmd(), + 'exe_link_cmd': cc.binary_link_command_for(osinfo.basename, options) + external_link_cmd(), + 'post_link_cmd': '', + + 'ar_command': ar_command(), + 'ar_options': cc.ar_options or osinfo.ar_options, + 'ar_output_to': cc.ar_output_to, + + 'link_to': ' '.join( + [cc.add_lib_option + lib for lib in link_to('libs')] + + [cc.add_framework_option + fw for fw in link_to('frameworks')] + ), + + 'cmake_link_to': ' '.join( + [lib for lib in link_to('libs')] + + [('"' + cc.add_framework_option + fw + '"') for fw in link_to('frameworks')] + ), - if method == 'symlink': - def count_dirs(dir, accum = 0): - if dir in ['', '/', os.path.curdir]: - return accum - (dir,basename) = os.path.split(dir) - return accum + 1 + count_dirs(dir) + 'fuzzer_lib': (cc.add_lib_option + options.fuzzer_lib) if options.fuzzer_lib else '', + 'libs_used': [lib.replace('.lib', '') for lib in link_to('libs')], - dirs_up = count_dirs(target_dir) + 'include_paths': build_paths.format_include_paths(cc, options.with_external_includedir), + 'module_defines': sorted(flatten([m.defines() for m in modules])), + + 'os_features': osinfo.enabled_features(options), + 'os_name': osinfo.basename, + 'cpu_features': arch.supported_isa_extensions(cc, options), + + 'fuzzer_mode': options.unsafe_fuzzer_mode, + 'fuzzer_type': options.build_fuzzers.upper() if options.build_fuzzers else '', + + 'with_valgrind': options.with_valgrind, + 'with_openmp': options.with_openmp, + 'with_debug_asserts': options.with_debug_asserts, + 'test_mode': options.test_mode, + + 'mod_list': sorted([m.basename for m in modules]) + } - source = os.path.join(os.path.join(*[os.path.pardir]*dirs_up), - filename) + if options.os != 'windows': + variables['botan_pkgconfig'] = os.path.join(build_paths.build_dir, 'botan-%d.pc' % (Version.major())) - target = os.path.join(target_dir, os.path.basename(filename)) + # The name is always set because Windows build needs it + variables['static_lib_name'] = '%s%s.%s' % (variables['lib_prefix'], variables['libname'], + variables['static_suffix']) - os.symlink(source, target) + if options.build_shared_lib: + if osinfo.soname_pattern_base != None: + variables['soname_base'] = osinfo.soname_pattern_base.format(**variables) + variables['shared_lib_name'] = variables['soname_base'] - elif method == 'hardlink': - os.link(filename, - os.path.join(target_dir, os.path.basename(filename))) + if osinfo.soname_pattern_abi != None: + variables['soname_abi'] = osinfo.soname_pattern_abi.format(**variables) + variables['shared_lib_name'] = variables['soname_abi'] + + if osinfo.soname_pattern_patch != None: + variables['soname_patch'] = osinfo.soname_pattern_patch.format(**variables) + + variables['lib_link_cmd'] = variables['lib_link_cmd'].format(**variables) + variables['post_link_cmd'] = osinfo.so_post_link_command.format(**variables) if options.build_shared_lib else '' + + lib_targets = [] + if options.build_static_lib: + lib_targets.append('static_lib_name') + if options.build_shared_lib: + lib_targets.append('shared_lib_name') + + variables['library_targets'] = ' '.join([join_with_build_dir(variables[t]) for t in lib_targets]) + + if options.os == 'llvm' or options.compiler == 'msvc': + # llvm-link and msvc require just naming the file directly + variables['link_to_botan'] = os.path.join(build_dir, variables['static_lib_name']) + else: + variables['link_to_botan'] = '%s%s %s%s' % (cc.add_lib_dir_option, build_dir, + cc.add_lib_option, variables['libname']) + + return variables + +class ModulesChooser(object): + """ + Determine which modules to load based on options, target, etc + """ - elif method == 'copy': - shutil.copy(filename, target_dir) + def __init__(self, modules, module_policy, archinfo, osinfo, ccinfo, cc_min_version, options): + self._modules = modules + self._module_policy = module_policy + self._archinfo = archinfo + self._osinfo = osinfo + self._ccinfo = ccinfo + self._cc_min_version = cc_min_version + self._options = options + + self._maybe_dep = set() + self._to_load = set() + # string to set mapping with reasons as key and modules as value + self._not_using_because = collections.defaultdict(set) + + ModulesChooser._validate_dependencies_exist(self._modules) + ModulesChooser._validate_user_selection( + 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): + 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 + def _display_module_information_unused(skipped_modules): + for reason in sorted(skipped_modules.keys()): + disabled_mods = sorted(skipped_modules[reason]) + if disabled_mods: + logging.info('Skipping (%s): %s' % (reason, ' '.join(disabled_mods))) + + @staticmethod + def _display_module_information_to_load(all_modules, modules_to_load): + sorted_modules_to_load = sorted(modules_to_load) + + for modname in sorted_modules_to_load: + if modname.startswith('simd_') and modname != 'simd_engine': + logging.info('Using SIMD module ' + modname) + + for modname in sorted_modules_to_load: + if all_modules[modname].comment: + logging.info('%s: %s' % (modname, all_modules[modname].comment)) + if all_modules[modname].warning: + logging.warning('%s: %s' % (modname, all_modules[modname].warning)) + if all_modules[modname].load_on == 'vendor': + logging.info('Enabling use of external dependency %s' % modname) + + if sorted_modules_to_load: + logging.info('Loading modules: %s', ' '.join(sorted_modules_to_load)) else: - raise Exception('Unknown link method %s' % (method)) + logging.error('This configuration disables every submodule and is invalid') + + @staticmethod + def _validate_state(used_modules, unused_modules): + for reason, unused_for_reason in unused_modules.items(): + intersection = unused_for_reason & used_modules + if intersection: + raise InternalError( + "Disabled modules (%s) and modules to load have common elements: %s" + % (reason, intersection)) + + @staticmethod + def _validate_dependencies_exist(modules): + for module in modules.values(): + module.dependencies_exist(modules) + + @staticmethod + def _validate_user_selection(modules, enabled_modules, disabled_modules): + for modname in enabled_modules: + if modname not in modules: + logging.error("Module not found: %s" % modname) + + for modname in disabled_modules: + if modname not in modules: + logging.warning("Disabled module not found: %s" % modname) + + def _handle_by_module_policy(self, modname, usable): + if self._module_policy is not None: + if modname in self._module_policy.required: + if not usable: + logging.error('Module policy requires module %s not usable on this platform' % (modname)) + elif modname in self._options.disabled_modules: + logging.error('Module %s was disabled but is required by policy' % (modname)) + self._to_load.add(modname) + return True + elif modname in self._module_policy.if_available: + if modname in self._options.disabled_modules: + self._not_using_because['disabled by user'].add(modname) + elif usable: + logging.debug('Enabling optional module %s' % (modname)) + self._to_load.add(modname) + return True + elif modname in self._module_policy.prohibited: + if modname in self._options.enabled_modules: + logging.error('Module %s was requested but is prohibited by policy' % (modname)) + self._not_using_because['prohibited by module policy'].add(modname) + return True + + return False - def choose_makefile_template(style): - if style == 'nmake': - return 'nmake.in' - elif style == 'unix': - return ('unix_shr.in' if options.build_shared_lib else 'unix.in') + @staticmethod + def resolve_dependencies(available_modules, dependency_table, module, loaded_modules=None): + """ + Parameters + - available_modules: modules to choose from. Constant. + - dependency_table: module to dependencies map. Constant. + - module: name of the module to resolve dependencies. Constant. + - loaded_modules: modules already loaded. Defensive copy in order to not change value for caller. + """ + if loaded_modules is None: + loaded_modules = set([]) else: - raise Exception('Unknown makefile style "%s"' % (style)) + loaded_modules = copy.copy(loaded_modules) - # First delete the build tree, if existing - try: - if options.clean_build_tree: - shutil.rmtree(build_config.build_dir) - except OSError as e: - if e.errno != errno.ENOENT: - logging.error('Problem while removing build dir: %s' % (e)) + if module not in available_modules: + return False, None - for dir in build_config.build_dirs: - try: - os.makedirs(dir) - except OSError as e: - if e.errno != errno.EEXIST: - logging.error('Error while creating "%s": %s' % (dir, e)) + loaded_modules.add(module) + for dependency in dependency_table[module]: + dependency_choices = set(dependency.split('|')) + + dependency_met = False + + if not set(dependency_choices).isdisjoint(loaded_modules): + dependency_met = True + else: + possible_mods = dependency_choices.intersection(available_modules) + + for mod in possible_mods: + ok, dependency_modules = ModulesChooser.resolve_dependencies( + available_modules, dependency_table, mod, loaded_modules) + if ok: + dependency_met = True + loaded_modules.add(mod) + loaded_modules.update(dependency_modules) + break - makefile_template = os.path.join( - options.makefile_dir, - choose_makefile_template(template_vars['makefile_style'])) + if not dependency_met: + return False, None - logging.debug('Using makefile template %s' % (makefile_template)) + return True, loaded_modules - templates_to_proc = { - makefile_template: template_vars['makefile_path'] - } + def _modules_dependency_table(self): + out = {} + for modname in self._modules: + out[modname] = self._modules[modname].dependencies(self._osinfo) + return out - def templates_to_use(): - yield (options.build_data, 'buildh.in', 'build.h') - yield (options.build_data, 'botan.doxy.in', 'botan.doxy') + def _resolve_dependencies_for_all_modules(self): + available_modules = set(self._to_load) | set(self._maybe_dep) + dependency_table = self._modules_dependency_table() - if options.os != 'windows': - yield (options.build_data, 'botan.pc.in', build_config.pkg_config_file()) - yield (options.build_data, 'botan-config.in', build_config.config_shell_script()) + successfully_loaded = set() - if options.os == 'windows': - yield (options.build_data, 'innosetup.in', 'botan.iss') + for modname in self._to_load: + # This will try to recursively load all dependencies of modname + ok, modules = self.resolve_dependencies(available_modules, dependency_table, modname) + if ok: + successfully_loaded.add(modname) + successfully_loaded.update(modules) + else: + # Skip this module + pass + + self._not_using_because['dependency failure'].update(self._to_load - successfully_loaded) + self._to_load = successfully_loaded + self._maybe_dep -= successfully_loaded + + def _handle_by_load_on(self, module): # pylint: disable=too-many-branches + modname = module.basename + if module.load_on == 'never': + self._not_using_because['disabled as buggy'].add(modname) + elif module.load_on == 'request': + if self._options.with_everything: + self._to_load.add(modname) + else: + self._not_using_because['by request only'].add(modname) + elif module.load_on == 'vendor': + if self._options.with_everything: + self._to_load.add(modname) + else: + self._not_using_because['requires external dependency'].add(modname) + elif module.load_on == 'dep': + self._maybe_dep.add(modname) - if options.boost_python: - yield (options.makefile_dir, 'python.in', 'Makefile.python') + elif module.load_on == 'always': + self._to_load.add(modname) - for (template_dir, template, sink) in templates_to_use(): - source = os.path.join(template_dir, template) - if template_dir == options.build_data: - sink = os.path.join(build_config.build_dir, sink) - templates_to_proc[source] = sink + elif module.load_on == 'auto': + if self._options.no_autoload or self._module_policy is not None: + self._maybe_dep.add(modname) + else: + self._to_load.add(modname) + else: + logging.error('Unknown load_on %s in %s' % ( + module.load_on, modname)) - for (template, sink) in templates_to_proc.items(): - try: - f = open(sink, 'w') - f.write(process_template(template, template_vars)) - finally: - f.close() + def choose(self): + for (modname, module) in self._modules.items(): + usable = self._check_usable(module, modname) - link_method = choose_link_method(options.link_method) - logging.info('Using %s to link files into build directory' % (link_method)) + module_handled = self._handle_by_module_policy(modname, usable) + if module_handled: + continue - def link_headers(header_list, type, dir): - logging.debug('Linking %d %s header files in %s' % ( - len(header_list), type, dir)) + if modname in self._options.disabled_modules: + self._not_using_because['disabled by user'].add(modname) + elif usable: + if modname in self._options.enabled_modules: + self._to_load.add(modname) # trust the user + else: + self._handle_by_load_on(module) - for header_file in header_list: - try: - portable_symlink(header_file, dir, link_method) - except OSError as e: - if e.errno != errno.EEXIST: - logging.error('Error linking %s into %s: %s' % ( - header_file, dir, e)) + if 'compression' in self._to_load: + # Confirm that we have at least one compression library enabled + # Otherwise we leave a lot of useless support code compiled in, plus a + # make_compressor call that always fails + if 'zlib' not in self._to_load and 'bzip2' not in self._to_load and 'lzma' not in self._to_load: + self._to_load.remove('compression') + self._not_using_because['no enabled compression schemes'].add('compression') - link_headers(build_config.public_headers, 'public', - build_config.botan_include_dir) + self._resolve_dependencies_for_all_modules() - link_headers(build_config.build_internal_headers, 'internal', - build_config.internal_include_dir) + for not_a_dep in self._maybe_dep: + self._not_using_because['not requested'].add(not_a_dep) -""" -Generate Amalgamation -""" -def generate_amalgamation(build_config): - def ending_with_suffix(suffix): - def predicate(val): - return val.endswith(suffix) - return predicate - - def strip_header_goop(header_name, contents): - header_guard = re.compile('^#define BOTAN_.*_H__$') - - while len(contents) > 0: - if header_guard.match(contents[0]): - contents = contents[1:] - break + ModulesChooser._validate_state(self._to_load, self._not_using_because) + ModulesChooser._display_module_information_unused(self._not_using_because) + ModulesChooser._display_module_information_to_load(self._modules, self._to_load) - contents = contents[1:] + return self._to_load - if len(contents) == 0: - raise Exception("No header guard found in " + header_name) +def choose_link_method(options): + """ + Choose the link method based on system availability and user request + """ - while contents[0] == '\n': - contents = contents[1:] + req = options.link_method + + def useable_methods(): + # 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': + yield 'symlink' + if 'link' in os.__dict__: + yield 'hardlink' + yield 'copy' + + for method in useable_methods(): + if req is None or req == method: + logging.info('Using %s to link files into build dir ' \ + '(use --link-method to change)' % (method)) + return method + + logging.warning('Could not use link method "%s", will copy instead' % (req)) + return 'copy' + +def portable_symlink(file_path, target_dir, method): + """ + Copy or link the file, depending on what the platform offers + """ - while contents[-1] == '\n': - contents = contents[0:-1] - if contents[-1] == '#endif\n': - contents = contents[0:-1] + if not os.access(file_path, os.R_OK): + logging.warning('Missing file %s' % (file_path)) + return + + if method == 'symlink': + rel_file_path = os.path.relpath(file_path, start=target_dir) + os.symlink(rel_file_path, os.path.join(target_dir, os.path.basename(file_path))) + elif method == 'hardlink': + os.link(file_path, os.path.join(target_dir, os.path.basename(file_path))) + elif method == 'copy': + shutil.copy(file_path, target_dir) + else: + raise UserError('Unknown link method %s' % (method)) - return contents - botan_include = re.compile('#include $') - std_include = re.compile('#include <([^/\.]+)>$') +class AmalgamationHelper(object): + # All include types may have trailing comment like e.g. '#include // IWYU pragma: export' + _any_include = re.compile(r'#include <(.*)>') + _botan_include = re.compile(r'#include ') - class Amalgamation_Generator: - def __init__(self, input_list): + # Only matches at the beginning of the line. By convention, this means that the include + # is not wrapped by condition macros + _unconditional_any_include = re.compile(r'^#include <(.*)>') + _unconditional_std_include = re.compile(r'^#include <([^/\.]+|stddef.h)>') - self.included_already = set() - self.all_std_includes = set() + @staticmethod + def is_any_include(cpp_source_line): + match = AmalgamationHelper._any_include.search(cpp_source_line) + if match: + return match.group(1) + else: + return None - self.file_contents = {} - for f in sorted(input_list): - contents = strip_header_goop(f, open(f).readlines()) - self.file_contents[os.path.basename(f)] = contents + @staticmethod + def is_botan_include(cpp_source_line): + match = AmalgamationHelper._botan_include.search(cpp_source_line) + if match: + return match.group(1) + else: + return None - self.contents = '' - for name in self.file_contents: - self.contents += ''.join(list(self.header_contents(name))) + @staticmethod + def is_unconditional_any_include(cpp_source_line): + match = AmalgamationHelper._unconditional_any_include.search(cpp_source_line) + if match: + return match.group(1) + else: + return None - self.header_includes = '' - for std_header in self.all_std_includes: - self.header_includes += '#include <%s>\n' % (std_header) - self.header_includes += '\n' + @staticmethod + def is_unconditional_std_include(cpp_source_line): + match = AmalgamationHelper._unconditional_std_include.search(cpp_source_line) + if match: + return match.group(1) + else: + return None - def header_contents(self, name): - name = name.replace('internal/', '') - if name in self.included_already: - return +class AmalgamationHeader(object): + def __init__(self, input_filepaths): - self.included_already.add(name) + self.included_already = set() + self.all_std_includes = set() - if name not in self.file_contents: - return + encoding_kwords = {} + if sys.version_info[0] == 3: + encoding_kwords['encoding'] = 'utf8' - for line in self.file_contents[name]: - match = botan_include.search(line) - if match: - for c in self.header_contents(match.group(1)): - yield c - else: - match = std_include.search(line) + 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) + self.file_contents[os.path.basename(filepath)] = contents + except IOError as e: + logging.error('Error processing file %s for amalgamation: %s' % (filepath, e)) + + self.contents = '' + for name in sorted(self.file_contents): + self.contents += ''.join(list(self.header_contents(name))) + + self.header_includes = '' + for std_header in sorted(self.all_std_includes): + self.header_includes += '#include <%s>\n' % (std_header) + self.header_includes += '\n' + + def header_contents(self, name): + name = name.replace('internal/', '') + + if name in self.included_already: + return - if match and match.group(1) != 'functional': - self.all_std_includes.add(match.group(1)) - else: - yield line + if name == 'botan.h': + return - amalg_basename = 'botan_all' + self.included_already.add(name) - header_name = '%s.h' % (amalg_basename) + if name not in self.file_contents: + return - botan_h = open(header_name, 'w') + for line in self.file_contents[name]: + header = AmalgamationHelper.is_botan_include(line) + if header: + for c in self.header_contents(header): + yield c + else: + std_header = AmalgamationHelper.is_unconditional_std_include(line) - pub_header_amalag = Amalgamation_Generator(build_config.public_headers) + if std_header: + self.all_std_includes.add(std_header) + else: + yield line - amalg_header = """/* + @staticmethod + def write_banner(fd): + fd.write("""/* * Botan %s Amalgamation -* (C) 1999-2011 Jack Lloyd and others +* (C) 1999-2018 The Botan Authors * -* Distributed under the terms of the Botan license +* Botan is released under the Simplified BSD License (see license.txt) */ -""" % (build_config.version_string) +""" % (Version.as_string())) - botan_h.write(amalg_header) + @staticmethod + def _write_start_include_guard(fd, title): + fd.write(""" +#ifndef %s +#define %s - botan_h.write(""" -#ifndef BOTAN_AMALGAMATION_H__ -#define BOTAN_AMALGAMATION_H__ +""" % (title, title)) -""") + @staticmethod + def _write_end_include_guard(fd, title): + fd.write("\n#endif // %s\n" % (title)) - botan_h.write(pub_header_amalag.header_includes) - botan_h.write(pub_header_amalag.contents) - botan_h.write("\n#endif\n") + def write_to_file(self, filepath, include_guard): + with open(filepath, 'w') as f: + self.write_banner(f) + self._write_start_include_guard(f, include_guard) + f.write(self.header_includes) + f.write(self.contents) + self._write_end_include_guard(f, include_guard) - internal_header_amalag = Amalgamation_Generator( - [s for s in build_config.internal_headers - if s.find('asm_macr_') == -1]) - botan_cpp = open('%s.cpp' % (amalg_basename), 'w') +class AmalgamationGenerator(object): + filename_prefix = 'botan_all' - botan_cpp.write(amalg_header) + _header_guard_pattern = re.compile('^#define BOTAN_.*_H_$') - botan_cpp.write('\n#include "%s"\n' % (header_name)) + @staticmethod + def strip_header_goop(header_name, header_lines): + lines = copy.copy(header_lines) # defensive copy - botan_cpp.write(internal_header_amalag.header_includes) - botan_cpp.write(internal_header_amalag.contents) + start_header_guard_index = None + for index, line in enumerate(lines): + if AmalgamationGenerator._header_guard_pattern.match(line): + start_header_guard_index = index + break + if start_header_guard_index is None: + raise InternalError("No header guard start found in " + header_name) + + end_header_guard_index = None + for index, line in enumerate(lines): + if line == '#endif\n': + end_header_guard_index = index # override with last found + if end_header_guard_index is None: + raise InternalError("No header guard end found in " + header_name) + + lines = lines[start_header_guard_index+1 : end_header_guard_index] + + # Strip leading and trailing empty lines + while lines[0].strip() == "": + lines = lines[1:] + while lines[-1].strip() == "": + lines = lines[0:-1] + + return lines + + def __init__(self, build_paths, modules, options): + self._build_paths = build_paths + self._modules = modules + self._options = options + + def _target_for_module(self, mod): + target = '' + if not self._options.single_amalgamation_file: + if mod.need_isa != []: + target = '_'.join(sorted(mod.need_isa)) + if target == 'sse2' and self._options.arch == 'x86_64': + target = '' # SSE2 is always available on x86-64 + + if self._options.arch == 'x86_32' and 'simd' in mod.requires: + target = 'sse2' + return target + + def _isas_for_target(self, target): + for mod in sorted(self._modules, key=lambda module: module.basename): + # Only first module for target is considered. Does this make sense? + if self._target_for_module(mod) == target: + out = set() + for isa in mod.need_isa: + if isa == 'aesni': + isa = "aes,ssse3,pclmul" + elif isa == 'rdrand': + isa = 'rdrnd' + out.add(isa) + return out + # Return set such that we can also iterate over result in the NA case + return set() + + def _generate_headers(self): + pub_header_amalag = AmalgamationHeader(self._build_paths.public_headers) + header_name = '%s.h' % (AmalgamationGenerator.filename_prefix) + 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) + 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 + + def _generate_sources(self, amalgamation_headers, included_in_headers): #pylint: disable=too-many-locals,too-many-branches + encoding_kwords = {} + if sys.version_info[0] == 3: + encoding_kwords['encoding'] = 'utf8' + + # target to filepath map + amalgamation_sources = {} + for mod in self._modules: + target = self._target_for_module(mod) + amalgamation_sources[target] = '%s%s.cpp' % ( + AmalgamationGenerator.filename_prefix, + '_' + target if target else '') + + # file descriptors for all `amalgamation_sources` + amalgamation_files = {} + for target, filepath in amalgamation_sources.items(): + logging.info('Writing amalgamation source to %s' % (filepath)) + amalgamation_files[target] = open(filepath, 'w', **encoding_kwords) + + for target, f in amalgamation_files.items(): + AmalgamationHeader.write_banner(f) + f.write('\n') + for header in amalgamation_headers: + f.write('#include "%s"\n' % (header)) + f.write('\n') + + for isa in self._isas_for_target(target): + + if isa == 'sse41': + isa = 'sse4.1' + elif isa == 'sse42': + isa = 'ssse4.2' + + f.write('#if defined(__GNUG__) && !defined(__clang__)\n') + f.write('#pragma GCC target ("%s")\n' % (isa)) + f.write('#endif\n') + + # target to include header map + unconditional_headers_written = {} + for target, _ in amalgamation_sources.items(): + unconditional_headers_written[target] = included_in_headers.copy() + + for mod in sorted(self._modules, key=lambda module: module.basename): + tgt = self._target_for_module(mod) + for src in sorted(mod.source): + with open(src, 'r', **encoding_kwords) as f: + for line in f: + if AmalgamationHelper.is_botan_include(line): + # Botan headers are inlined in amalgamation headers + continue - for src in build_config.sources: - if src.endswith('.S'): - continue + if AmalgamationHelper.is_any_include(line) in unconditional_headers_written[tgt]: + # This include (conditional or unconditional) was unconditionally added before + continue + + amalgamation_files[tgt].write(line) + unconditional_header = AmalgamationHelper.is_unconditional_any_include(line) + if unconditional_header: + unconditional_headers_written[tgt].add(unconditional_header) + + for f in amalgamation_files.values(): + f.close() + + 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) + return (sorted(amalgamation_sources), sorted(amalgamation_headers)) - contents = open(src).readlines() - for line in contents: - if botan_include.search(line): - continue - else: - botan_cpp.write(line) -""" -Test for the existence of a program -""" def have_program(program): + """ + Test for the existence of a program + """ def exe_test(path, program): exe_file = os.path.join(path, program) @@ -1663,45 +2606,114 @@ def have_program(program): if exe_test(path, program + suffix): return True + logging.debug('Program %s not found' % (program)) return False -""" -Main driver -""" -def main(argv = None): - if argv is None: - argv = sys.argv - logging.basicConfig(stream = sys.stdout, - format = '%(levelname) 7s: %(message)s') +class BotanConfigureLogHandler(logging.StreamHandler, object): + def emit(self, record): + # Do the default stuff first + super(BotanConfigureLogHandler, self).emit(record) + # Exit script if and ERROR or worse occurred + if record.levelno >= logging.ERROR: + sys.exit(1) - options = process_command_line(argv[1:]) - def log_level(): - if options.verbose: - return logging.DEBUG - if options.quiet: - return logging.WARNING - return logging.INFO +def setup_logging(options): + if options.verbose: + log_level = logging.DEBUG + elif options.quiet: + log_level = logging.WARNING + else: + log_level = logging.INFO - logging.getLogger().setLevel(log_level()) + lh = BotanConfigureLogHandler(sys.stdout) + lh.setFormatter(logging.Formatter('%(levelname) 7s: %(message)s')) + logging.getLogger().addHandler(lh) + logging.getLogger().setLevel(log_level) - logging.debug('%s invoked with options "%s"' % ( - argv[0], ' '.join(argv[1:]))) - logging.debug('Platform: OS="%s" machine="%s" proc="%s"' % ( - platform.system(), platform.machine(), platform.processor())) +def load_info_files(search_dir, descr, filename_matcher, class_t): + info = {} - if options.os == "java": - raise Exception("Jython detected: need --os and --cpu to set target") + def filename_matches(filename): + if isinstance(filename_matcher, str): + return filename == filename_matcher + else: + return filename_matcher.match(filename) is not None + + for (dirpath, _, filenames) in os.walk(search_dir): + for filename in filenames: + filepath = os.path.join(dirpath, filename) + if filename_matches(filename): + info_obj = class_t(filepath) + info[info_obj.basename] = info_obj + + if info: + infotxt_basenames = ' '.join(sorted([key for key in info])) + logging.debug('Loaded %d %s files: %s' % (len(info), descr, infotxt_basenames)) + else: + logging.warning('Failed to load any %s files' % (descr)) + + return info + + +def load_build_data_info_files(source_paths, descr, subdir, class_t): + matcher = re.compile(r'[_a-z0-9]+\.txt$') + return load_info_files(os.path.join(source_paths.build_data_dir, subdir), descr, matcher, class_t) + + +# Workaround for Windows systems where antivirus is enabled GH #353 +def robust_rmtree(path, max_retries=5): + for _ in range(max_retries): + try: + shutil.rmtree(path) + return + except OSError: + time.sleep(0.1) + + # Final attempt, pass any exceptions up to caller. + shutil.rmtree(path) + + +# Workaround for Windows systems where antivirus is enabled GH #353 +def robust_makedirs(directory, max_retries=5): + for _ in range(max_retries): + try: + os.makedirs(directory) + return + except OSError as e: + if e.errno == errno.EEXIST: + raise + else: + time.sleep(0.1) - options.base_dir = os.path.dirname(argv[0]) - options.src_dir = os.path.join(options.base_dir, 'src') + # Final attempt, pass any exceptions up to caller. + os.makedirs(directory) - options.build_data = os.path.join(options.src_dir, 'build-data') - options.makefile_dir = os.path.join(options.build_data, 'makefile') - (modules, archinfo, ccinfo, osinfo) = load_info_files(options) +# This is for otions that have --with-XYZ and --without-XYZ. If user does not +# set any of those, we choose a default here. +# Mutates `options` +def set_defaults_for_unset_options(options, info_arch, info_cc): # pylint: disable=too-many-branches + if options.os is None: + system_from_python = platform.system().lower() + if re.match('^cygwin_.*', system_from_python): + logging.debug("Converting '%s' to 'cygwin'", system_from_python) + options.os = 'cygwin' + else: + options.os = system_from_python + logging.info('Guessing target OS is %s (use --os to set)' % (options.os)) + + def deduce_compiler_type_from_cc_bin(cc_bin): + if cc_bin.find('clang') != -1 or cc_bin in ['emcc', 'em++']: + return 'clang' + if cc_bin.find('-g++') != -1: + return 'gcc' + return None + + if options.compiler is None and options.compiler_binary != None: + options.compiler = deduce_compiler_type_from_cc_bin(options.compiler_binary) if options.compiler is None: if options.os == 'windows': @@ -1709,173 +2721,455 @@ def main(argv = None): options.compiler = 'gcc' else: options.compiler = 'msvc' + elif options.os in ['darwin', 'freebsd', 'openbsd', 'ios']: + # Prefer Clang on these systems + if have_program('clang++'): + options.compiler = 'clang' + else: + options.compiler = 'gcc' + if options.os == 'openbsd': + # The assembler shipping with OpenBSD 5.9 does not support avx2 + del info_cc['gcc'].isa_flags['avx2'] else: options.compiler = 'gcc' - logging.info('Guessing to use compiler %s (use --cc to set)' % ( - options.compiler)) - if options.os is None: - options.os = platform.system().lower() + if options.compiler is None: + logging.error('Could not guess which compiler to use, use --cc or CXX to set') + else: + logging.info('Guessing to use compiler %s (use --cc or CXX to set)' % (options.compiler)) - if re.match('^cygwin_.*', options.os): - logging.debug("Converting '%s' to 'cygwin'", options.os) - options.os = 'cygwin' + if options.cpu is None: + (arch, cpu) = guess_processor(info_arch) + options.arch = arch + options.cpu = cpu + logging.info('Guessing target processor is a %s (use --cpu to set)' % (options.arch)) + + if options.with_documentation is True: + if options.with_sphinx is None and have_program('sphinx-build'): + logging.info('Found sphinx-build (use --without-sphinx to disable)') + options.with_sphinx = True + if options.with_rst2man is None and have_program('rst2man'): + logging.info('Found rst2man (use --without-rst2man to disable)') + options.with_rst2man = True + + +# Mutates `options` +def canonicalize_options(options, info_os, info_arch): + # pylint: disable=too-many-branches + if options.os not in info_os: + def find_canonical_os_name(os_name_variant): + for (canonical_os_name, os_info) in info_os.items(): + if os_info.matches_name(os_name_variant): + return canonical_os_name + return os_name_variant # not found + options.os = find_canonical_os_name(options.os) - if options.os == 'windows' and options.compiler == 'gcc': - logging.warning('Detected GCC on Windows; use --os=cygwin or --os=mingw?') + # canonical ARCH/CPU + options.arch = canon_processor(info_arch, options.cpu) + if options.arch is None: + raise UserError('Unknown or unidentifiable processor "%s"' % (options.cpu)) - logging.info('Guessing target OS is %s (use --os to set)' % (options.os)) + if options.cpu != options.arch: + logging.info('Canonicalized CPU target %s to %s', options.cpu, options.arch) - if options.compiler not in ccinfo: - raise Exception('Unknown compiler "%s"; available options: %s' % ( - options.compiler, ' '.join(sorted(ccinfo.keys())))) + shared_libs_supported = options.os in info_os and info_os[options.os].building_shared_supported() - if options.os not in osinfo: + if not shared_libs_supported: + if options.build_shared_lib is not None: + logging.warning('Shared libs not supported on %s, disabling shared lib support' % (options.os)) + options.build_shared_lib = False + else: + logging.info('Shared libs not supported on %s, disabling shared lib support' % (options.os)) - def find_canonical_os_name(os): - for (name, info) in osinfo.items(): - if os in info.aliases: - return name - return os # not found + if options.os == 'windows' and options.build_shared_lib is None and options.build_static_lib is None: + options.build_shared_lib = True - options.os = find_canonical_os_name(options.os) + if options.with_stack_protector is None: + if options.os in info_os: + options.with_stack_protector = info_os[options.os].use_stack_protector + + if options.build_shared_lib is None: + if options.os == 'windows' and options.build_static_lib: + pass + else: + options.build_shared_lib = shared_libs_supported - if options.os not in osinfo: - raise Exception('Unknown OS "%s"; available options: %s' % ( - options.os, ' '.join(sorted(osinfo.keys())))) + if options.build_static_lib is None: + if options.os == 'windows' and options.build_shared_lib: + pass + else: + options.build_static_lib = True - if options.cpu is None: - (options.arch, options.cpu) = guess_processor(archinfo) - logging.info('Guessing target processor is a %s/%s (use --cpu to set)' % ( - options.arch, options.cpu)) - else: - cpu_from_user = options.cpu - (options.arch, options.cpu) = canon_processor(archinfo, options.cpu) - logging.info('Canonicalizized --cpu=%s to %s/%s' % ( - cpu_from_user, options.arch, options.cpu)) + # Set default fuzzing lib + if options.build_fuzzers == 'libfuzzer' and options.fuzzer_lib is None: + options.fuzzer_lib = 'Fuzzer' + +# Checks user options for consistency +# This method DOES NOT change options on behalf of the user but explains +# why the given configuration does not work. +def validate_options(options, info_os, info_cc, available_module_policies): + # pylint: disable=too-many-branches + + if options.single_amalgamation_file and not options.amalgamation: + raise UserError("--single-amalgamation-file requires --amalgamation.") + + if options.os == "java": + raise UserError("Jython detected: need --os and --cpu to set target") + + if options.os not in info_os: + raise UserError('Unknown OS "%s"; available options: %s' % ( + options.os, ' '.join(sorted(info_os.keys())))) + + if options.compiler not in info_cc: + raise UserError('Unknown compiler "%s"; available options: %s' % ( + options.compiler, ' '.join(sorted(info_cc.keys())))) + + if options.cc_min_version is not None and not re.match(r'^[0-9]+\.[0-9]+$', options.cc_min_version): + raise UserError("--cc-min-version must have the format MAJOR.MINOR") + + if options.module_policy and options.module_policy not in available_module_policies: + raise UserError("Unknown module set %s" % options.module_policy) + + if options.os == 'llvm' or options.cpu == 'llvm': + if options.compiler != 'clang': + raise UserError('LLVM target requires using Clang') + 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 not in ['libfuzzer', 'afl', 'klee', 'test']: + raise UserError('Bad value to --build-fuzzers') + + if options.build_fuzzers == 'klee' and options.os != 'llvm': + raise UserError('Building for KLEE requires targeting LLVM') + + if options.build_static_lib is False and options.build_shared_lib is False: + raise UserError('With both --disable-static-library and --disable-shared-library, nothing to do') + + if options.os == 'windows' and options.build_static_lib is True and options.build_shared_lib is True: + raise UserError('On Windows only one of static lib and DLL can be selected') + + if options.with_documentation is False: + if options.with_doxygen: + raise UserError('Using --with-doxygen plus --without-documentation makes no sense') + if options.with_sphinx: + raise UserError('Using --with-sphinx plus --without-documentation makes no sense') + if options.with_pdf: + raise UserError('Using --with-pdf plus --without-documentation makes no sense') + + if options.with_pdf and not options.with_sphinx: + raise UserError('Option --with-pdf requires --with-sphinx') - logging.info('Target is %s-%s-%s-%s' % ( - options.compiler, options.os, options.arch, options.cpu)) + if options.with_bakefile: + if options.os != 'windows' or options.compiler != 'msvc' or options.build_shared_lib is False: + raise UserError("Building via bakefile is only supported for MSVC DLL build") - cc = ccinfo[options.compiler] + if options.arch not in ['x86_64', 'x86_32']: + raise UserError("Bakefile only supports x86 targets") - # Kind of a hack... - options.extra_flags = '' - if options.compiler == 'gcc': + # Warnings + if options.os == 'windows' and options.compiler != 'msvc': + logging.warning('The windows target is oriented towards MSVC; maybe you want --os=cygwin or --os=mingw') - def get_gcc_version(gcc_bin): + if options.msvc_runtime: + if options.compiler != 'msvc': + raise UserError("Makes no sense to specify MSVC runtime for %s" % (options.compiler)) + + if options.msvc_runtime not in ['MT', 'MD', 'MTd', 'MDd']: + logging.warning("MSVC runtime option '%s' not known", (options.msvc_runtime)) + +def run_compiler_preproc(options, ccinfo, source_file, default_return, extra_flags=None): + if extra_flags is None: + extra_flags = [] + + cc_bin = options.compiler_binary or ccinfo.binary_name + + cmd = cc_bin.split(' ') + ccinfo.preproc_flags.split(' ') + extra_flags + [source_file] + + try: + logging.debug("Running '%s'", ' '.join(cmd)) + stdout, _ = subprocess.Popen( + cmd, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + universal_newlines=True).communicate() + cc_output = stdout + except OSError as e: + logging.warning('Could not execute %s: %s' % (cmd, e)) + return default_return + + def cleanup_output(output): + return ('\n'.join([l for l in output.splitlines() if l.startswith('#') is False])).strip() + + return cleanup_output(cc_output) + +def calculate_cc_min_version(options, ccinfo, source_paths): + version_patterns = { + 'msvc': r'^ *MSVC ([0-9]{2})([0-9]{2})$', + 'gcc': r'^ *GCC ([0-9]+) ([0-9]+)$', + 'clang': r'^ *CLANG ([0-9]+) ([0-9]+)$', + 'xlc': r'^ *XLC (0x[0-9a-fA-F]{2})([0-9a-fA-F]{2})$' + } + + if ccinfo.basename not in version_patterns: + logging.info("No compiler version detection available for %s" % (ccinfo.basename)) + return "0.0" + + detect_version_source = os.path.join(source_paths.build_data_dir, "detect_version.cpp") + + cc_output = run_compiler_preproc(options, ccinfo, detect_version_source, "0.0") + + match = re.search(version_patterns[ccinfo.basename], cc_output, flags=re.MULTILINE) + if match is None: + logging.warning("Tried to get %s version, but output '%s' does not match expected version format" % ( + ccinfo.basename, cc_output)) + return "0.0" + + major_version = int(match.group(1), 0) + minor_version = int(match.group(2), 0) + cc_version = "%d.%d" % (major_version, minor_version) + logging.info('Auto-detected compiler version %s' % (cc_version)) + + if ccinfo.basename == 'msvc': + if major_version == 18: + logging.warning('MSVC 2013 support is deprecated and will be removed in a future release') + return cc_version + +def check_compiler_arch(options, ccinfo, archinfo, source_paths): + detect_version_source = os.path.join(source_paths.build_data_dir, 'detect_arch.cpp') + + 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']: + logging.warning('Unable to detect target architecture via compiler macro checks') + return None + + if cc_output not in archinfo: + # Should not happen + logging.warning("Error detecting compiler target arch: '%s'", cc_output) + return None + + logging.info('Auto-detected compiler arch %s' % (cc_output)) + 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 + + try: + robust_rmtree(build_paths.build_dir) + except OSError as e: + if e.errno != errno.ENOENT: + logging.error('Problem while removing build dir: %s' % (e)) + + for build_dir in build_paths.build_dirs(): + try: + robust_makedirs(build_dir) + except OSError as e: + if e.errno != errno.EEXIST: + logging.error('Error while creating "%s": %s' % (build_dir, e)) + + def write_template(sink, template): + with open(sink, 'w') as f: + f.write(process_template(template, template_vars)) + + def in_build_dir(p): + return os.path.join(build_paths.build_dir, p) + def in_build_data(p): + return os.path.join(source_paths.build_data_dir, p) + + write_template(in_build_dir('build.h'), in_build_data('buildh.in')) + write_template(in_build_dir('botan.doxy'), in_build_data('botan.doxy.in')) + + if 'botan_pkgconfig' in template_vars: + write_template(template_vars['botan_pkgconfig'], in_build_data('botan.pc.in')) + + if options.os == 'windows': + write_template(in_build_dir('botan.iss'), in_build_data('innosetup.in')) + + link_method = choose_link_method(options) + + def link_headers(headers, visibility, directory): + logging.debug('Linking %d %s header files in %s' % (len(headers), visibility, directory)) + + for header_file in headers: try: - gcc_proc = subprocess.Popen( - gcc_bin.split(' ') + ['-dumpversion'], - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - universal_newlines=True) + portable_symlink(header_file, directory, link_method) + except OSError as e: + if e.errno != errno.EEXIST: + raise UserError('Error linking %s into %s: %s' % (header_file, directory, e)) - (stdout, stderr) = gcc_proc.communicate() + link_headers(build_paths.public_headers, 'public', + build_paths.botan_include_dir) - if gcc_proc.returncode != 0: - logging.warning("GCC returned non-zero result %s" % (stderr)) - return None + link_headers(build_paths.internal_headers, 'internal', + build_paths.internal_include_dir) - gcc_version = stdout.strip() + link_headers(build_paths.external_headers, 'external', + build_paths.external_include_dir) - logging.info('Detected gcc version %s' % (gcc_version)) - return gcc_version - except OSError: - logging.warning('Could not execute %s for version check' % (gcc_bin)) - return None + if options.amalgamation: + (amalg_cpp_files, amalg_headers) = AmalgamationGenerator(build_paths, using_mods, options).generate() + build_paths.lib_sources = amalg_cpp_files + template_vars['generated_files'] = ' '.join(amalg_cpp_files + amalg_headers) - def is_64bit_arch(arch): - if arch.endswith('64') or arch in ['alpha', 's390x']: - return True - return False + template_vars.update(generate_build_info(build_paths, using_mods, cc, arch, osinfo, options)) + + with open(os.path.join(build_paths.build_dir, 'build_config.json'), 'w') as f: + json.dump(template_vars, f, sort_keys=True, indent=2) + + if options.with_cmake: + logging.warning("CMake build is only for development: use make for production builds") + cmake_template = os.path.join(source_paths.build_data_dir, 'cmake.in') + write_template('CMakeLists.txt', cmake_template) + elif options.with_bakefile: + logging.warning("Bakefile build is only for development: use make for production builds") + bakefile_template = os.path.join(source_paths.build_data_dir, 'bakefile.in') + write_template('botan.bkl', bakefile_template) + else: + makefile_template = os.path.join(source_paths.build_data_dir, 'makefile.in') + write_template(template_vars['makefile_path'], makefile_template) + + if options.with_rst2man: + rst2man_file = os.path.join(build_paths.build_dir, 'botan.rst') + cli_doc = os.path.join(source_paths.doc_dir, 'manual/cli.rst') - gcc_version = get_gcc_version(options.compiler_binary or cc.binary_name) + cli_doc_contents = open(cli_doc).readlines() - if gcc_version: + while cli_doc_contents[0] != "\n": + cli_doc_contents.pop(0) - if not is_64bit_arch(options.arch) and not options.dumb_gcc: - matching_version = '(4\.[01234]\.)|(3\.[34]\.)|(2\.95\.[0-4])' + rst2man_header = """ +botan +============================= - if re.search(matching_version, gcc_version): - options.dumb_gcc = True +:Subtitle: Botan command line util +:Manual section: 1 - versions_without_tr1 = '(4\.0\.)|(3\.[0-4]\.)|(2\.95\.[0-4])' + """.strip() - if options.with_tr1 == None and \ - re.search(versions_without_tr1, gcc_version): - logging.info('Disabling TR1 support for this gcc, too old') - options.with_tr1 = 'none' + with open(rst2man_file, 'w') as f: + f.write(rst2man_header) + f.write("\n") + for line in cli_doc_contents: + f.write(line) - versions_without_visibility = '(3\.[0-4]\.)|(2\.95\.[0-4])' - if options.with_visibility == None and \ - re.search(versions_without_visibility, gcc_version): - logging.info('Disabling DSO visibility support for this gcc, too old') - options.with_visibility = False + logging.info('Botan %s (revision %s) (%s %s) build setup is complete' % ( + Version.as_string(), + Version.vc_rev(), + Version.release_type(), + ('dated %d' % (Version.datestamp())) if Version.datestamp() != 0 else 'undated')) - if options.dumb_gcc is True: - logging.info('Setting -fpermissive to work around gcc bug') - options.extra_flags = ' -fpermissive' + if options.unsafe_fuzzer_mode: + logging.warning("The fuzzer mode flag is labeled unsafe for a reason, this version is for testing only") - if options.with_visibility is None: - options.with_visibility = True +def list_os_features(all_os_features, info_os): + for feat in all_os_features: + os_with_feat = [o for o in info_os.keys() if feat in info_os[o].target_features] + os_without_feat = [o for o in info_os.keys() if feat not in info_os[o].target_features] - if options.with_tr1 == None: - if cc.has_tr1: - logging.info('Assuming %s has TR1 (use --with-tr1=none to disable)' % ( - options.compiler)) - options.with_tr1 = 'system' + if len(os_with_feat) < len(os_without_feat): + print("%s: %s" % (feat, ' '.join(sorted(os_with_feat)))) else: - options.with_tr1 = 'none' + print("%s: %s" % (feat, '!' + ' !'.join(sorted(os_without_feat)))) + return 0 - if options.with_sphinx is None: - if have_program('sphinx-build'): - logging.info('Found sphinx-build, will use it ' + - '(use --without-sphinx to disable)') - options.with_sphinx = True - if options.via_amalgamation: - options.gen_amalgamation = True +def main(argv): + """ + Main driver + """ - if options.gen_amalgamation: - if options.asm_ok: - logging.info('Disabling assembly code, cannot use in amalgamation') - options.asm_ok = False + # pylint: disable=too-many-locals - modules_to_use = choose_modules_to_use(modules, - archinfo[options.arch], - options) + options = process_command_line(argv[1:]) - if not osinfo[options.os].build_shared: - if options.build_shared_lib: - logging.info('Disabling shared lib on %s' % (options.os)) - options.build_shared_lib = False + setup_logging(options) + + source_paths = SourcePaths(os.path.dirname(argv[0])) + + info_modules = load_info_files(source_paths.lib_dir, 'Modules', "info.txt", ModuleInfo) + + if options.list_modules: + for mod in sorted(info_modules.keys()): + print(mod) + return 0 - build_config = BuildConfigurationInformation(options, modules_to_use) - build_config.public_headers.append( - os.path.join(build_config.build_dir, 'build.h')) + info_arch = load_build_data_info_files(source_paths, 'CPU info', 'arch', ArchInfo) + info_os = load_build_data_info_files(source_paths, 'OS info', 'os', OsInfo) + info_cc = load_build_data_info_files(source_paths, 'compiler info', 'cc', CompilerInfo) + info_module_policies = load_build_data_info_files(source_paths, 'module policy', 'policy', ModulePolicyInfo) - template_vars = create_template_vars(build_config, options, - modules_to_use, - cc, - archinfo[options.arch], - osinfo[options.os]) + all_os_features = sorted(set(flatten([o.target_features for o in info_os.values()]))) - # Performs the I/O - setup_build(build_config, options, template_vars) + if options.list_os_features: + return list_os_features(all_os_features, info_os) - if options.gen_amalgamation: - generate_amalgamation(build_config) + for mod in info_modules.values(): + mod.cross_check(info_arch, info_cc, all_os_features) - logging.info('Botan %s build setup is complete' % ( - build_config.version_string)) + for policy in info_module_policies.values(): + policy.cross_check(info_modules) + + logging.info('%s invoked with options "%s"', argv[0], ' '.join(argv[1:])) + + logging.info('Autodetected platform information: OS="%s" machine="%s" proc="%s"', + platform.system(), platform.machine(), platform.processor()) + + logging.debug('Known CPU names: ' + ' '.join( + sorted(flatten([[ainfo.basename] + ainfo.aliases for ainfo in info_arch.values()])))) + + set_defaults_for_unset_options(options, info_arch, info_cc) + canonicalize_options(options, info_os, info_arch) + validate_options(options, info_os, info_cc, info_module_policies) + + cc = info_cc[options.compiler] + arch = info_arch[options.arch] + osinfo = info_os[options.os] + module_policy = info_module_policies[options.module_policy] if options.module_policy else None + + if options.enable_cc_tests: + cc_min_version = options.cc_min_version or calculate_cc_min_version(options, cc, source_paths) + cc_arch = check_compiler_arch(options, cc, info_arch, source_paths) + + if cc_arch is not None and cc_arch != options.arch: + logging.warning("Configured target is %s but compiler probe indicates %s", options.arch, cc_arch) + else: + cc_min_version = options.cc_min_version or "0.0" + + logging.info('Target is %s:%s-%s-%s' % ( + options.compiler, cc_min_version, options.os, options.arch)) + + chooser = ModulesChooser(info_modules, module_policy, arch, osinfo, cc, cc_min_version, options) + loaded_module_names = chooser.choose() + using_mods = [info_modules[modname] for modname in loaded_module_names] + + build_paths = BuildPaths(source_paths, options, using_mods) + build_paths.public_headers.append(os.path.join(build_paths.build_dir, 'build.h')) + + template_vars = create_template_vars(source_paths, build_paths, options, using_mods, cc, arch, osinfo) + + # Now we start writing to disk + do_io_for_build(cc, arch, osinfo, using_mods, build_paths, source_paths, template_vars, options) + + return 0 if __name__ == '__main__': try: - main() - except Exception as e: - logging.error(str(e)) - #import traceback - #traceback.print_exc(file=sys.stderr) - sys.exit(1) + sys.exit(main(argv=sys.argv)) + except UserError as e: + logging.debug(traceback.format_exc()) + logging.error(e) + except Exception as e: # pylint: disable=broad-except + # error() will stop script, so wrap all information into one call + 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 + +You'll meet friendly people happy to help!""" % traceback.format_exc()) + sys.exit(0) diff --git a/src/libs/3rdparty/botan/doc/license.txt b/src/libs/3rdparty/botan/doc/license.txt deleted file mode 100644 index aefcee3954..0000000000 --- a/src/libs/3rdparty/botan/doc/license.txt +++ /dev/null @@ -1,49 +0,0 @@ - -.. _license: -.. highlight:: none - -License -======================================== - -Botan (http://botan.randombit.net/) is distributed under these terms:: - - Copyright (C) 1999-2011 Jack Lloyd - 2001 Peter J Jones - 2004-2007 Justin Karneges - 2004 Vaclav Ovsik - 2005 Matthew Gregan - 2005-2006 Matt Johnston - 2006 Luca Piccarreta - 2007 Yves Jerschow - 2007-2008 FlexSecure GmbH - 2007-2008 Technische Universitat Darmstadt - 2007-2008 Falko Strenzke - 2007-2008 Martin Doering - 2007 Manuel Hartl - 2007 Christoph Ludwig - 2007 Patrick Sona - 2010 Olivier de Gaalon - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions, and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) "AS IS" AND ANY EXPRESS OR - IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/src/libs/3rdparty/botan/license.txt b/src/libs/3rdparty/botan/license.txt new file mode 100644 index 0000000000..e6c8859565 --- /dev/null +++ b/src/libs/3rdparty/botan/license.txt @@ -0,0 +1,24 @@ +Copyright (C) 1999-2018 The Botan Authors +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions, and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. diff --git a/src/libs/3rdparty/botan/readme.rst b/src/libs/3rdparty/botan/readme.rst new file mode 100644 index 0000000000..5d96cb3829 --- /dev/null +++ b/src/libs/3rdparty/botan/readme.rst @@ -0,0 +1,183 @@ +Botan: Crypto and TLS for C++11 +======================================== + +Botan (Japanese for peony) is a cryptography library written in C++11 +and released under the permissive `Simplified BSD +`_ 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, +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 +`_ are available. +Find the full feature list below. + +Development is coordinated on `GitHub `_ +and contributions are welcome (read `doc/contributing.rst` for more info). + +If you need help with a problem, please open an `issue on GitHub +`_ or email the +`botan-devel mailing list +`_. + +New releases are announced on the +`botan-announce mailing list +`_. + +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 `_, 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. + +.. image:: https://travis-ci.org/randombit/botan.svg?branch=master + :target: https://travis-ci.org/randombit/botan + :alt: Travis CI status + +.. image:: https://ci.appveyor.com/api/projects/status/n9f94dljd03j2lce/branch/master?svg=true + :target: https://ci.appveyor.com/project/randombit/botan/branch/master + :alt: AppVeyor CI status + +.. image:: https://botan-ci.kullo.net/badge + :target: https://botan-ci.kullo.net/ + :alt: Kullo CI status + +.. image:: https://codecov.io/github/randombit/botan/coverage.svg?branch=master + :target: https://codecov.io/github/randombit/botan + :alt: Code coverage report + +.. image:: https://scan.coverity.com/projects/624/badge.svg + :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 `_ and +`security advisories `_ + +All releases are signed with a +`PGP key `_:: + + pub 2048R/EFBADFBC 2004-10-30 + Key fingerprint = 621D AF64 11E1 851C 4CF9 A2E1 6211 EBF1 EFBA DFBC + uid Botan Distribution Key + +Some `distributions `_ +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 `_ +`(sig) `_ +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 `_ +`(sig) `_ +released on 2017-10-02 + +Find Enclosed +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +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. +* 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. +* Key exchange using CECPQ1, ECDH, FFDHE, or RSA + +Public Key Infrastructure +---------------------------------------- + +* X.509v3 certificates and CRL creation and handling +* PKIX certificate path validation, including name constraints. +* OCSP request creation and response handling +* PKCS #10 certificate request generation and processing +* SQL database backed certificate store + +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 +* Post-quantum signature scheme XMSS +* Post-quantum key agreement schemes McEliece and NewHope +* ElGamal encryption +* Padding schemes OAEP, PSS, PKCS #1 v1.5, X9.31 + +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 + +Other Useful Things +---------------------------------------- + +* Full C++ PKCS #11 API wrapper +* Interfaces for TPM v1.2 device access +* 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) +* 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 +* Format preserving encryption scheme FE1 +* Threshold secret sharing +* NIST key wrapping diff --git a/src/libs/3rdparty/botan/readme.txt b/src/libs/3rdparty/botan/readme.txt deleted file mode 100644 index e7b052a0c1..0000000000 --- a/src/libs/3rdparty/botan/readme.txt +++ /dev/null @@ -1,15 +0,0 @@ -Botan 1.10.2, 2012-06-17 -http://botan.randombit.net/ - -Botan is a C++ class library for performing a wide variety of -cryptographic operations. It is released under the 2 clause BSD -license; see doc/license.txt for the specifics. You can file bugs in -Bugzilla (http://bugs.randombit.net/) or by sending a report to the -botan-devel mailing list. More information about the mailing list is -at http://lists.randombit.net/mailman/listinfo/botan-devel/ - -You can find documentation online at http://botan.randombit.net/ as -well as in the doc directory in the distribution. Several examples can -be found in doc/examples as well. - -Jack Lloyd (lloyd@randombit.net) diff --git a/src/libs/3rdparty/botan/src/build-data/arch/alpha.txt b/src/libs/3rdparty/botan/src/build-data/arch/alpha.txt new file mode 100644 index 0000000000..c251cbee9c --- /dev/null +++ b/src/libs/3rdparty/botan/src/build-data/arch/alpha.txt @@ -0,0 +1,7 @@ +endian little +wordsize 64 + + +axp +alphaaxp + diff --git a/src/libs/3rdparty/botan/src/build-data/arch/arm32.txt b/src/libs/3rdparty/botan/src/build-data/arch/arm32.txt new file mode 100644 index 0000000000..d2fe782b3b --- /dev/null +++ b/src/libs/3rdparty/botan/src/build-data/arch/arm32.txt @@ -0,0 +1,20 @@ +endian little +family arm + + +arm +armeb +armel # For Debian +armhf # For Debian +evbarm # For NetBSD + +armv7 +armv7l +armv7-a + +armv8l # For AlpineLinux + + + +neon + diff --git a/src/libs/3rdparty/botan/src/build-data/arch/arm64.txt b/src/libs/3rdparty/botan/src/build-data/arch/arm64.txt new file mode 100644 index 0000000000..d4781c8740 --- /dev/null +++ b/src/libs/3rdparty/botan/src/build-data/arch/arm64.txt @@ -0,0 +1,15 @@ +endian little +wordsize 64 + +family arm + + +aarch64 +armv8 +armv8-a + + + +neon +armv8crypto + diff --git a/src/libs/3rdparty/botan/src/build-data/arch/hppa.txt b/src/libs/3rdparty/botan/src/build-data/arch/hppa.txt new file mode 100644 index 0000000000..8828126b65 --- /dev/null +++ b/src/libs/3rdparty/botan/src/build-data/arch/hppa.txt @@ -0,0 +1,8 @@ + +hp-pa +parisc +parisc64 +pa-risc +hp-parisc +hp-pa-risc + diff --git a/src/libs/3rdparty/botan/src/build-data/arch/ia64.txt b/src/libs/3rdparty/botan/src/build-data/arch/ia64.txt new file mode 100644 index 0000000000..8a448ff881 --- /dev/null +++ b/src/libs/3rdparty/botan/src/build-data/arch/ia64.txt @@ -0,0 +1,6 @@ +wordsize 64 + + +itanium +itanic + diff --git a/src/libs/3rdparty/botan/src/build-data/arch/llvm.txt b/src/libs/3rdparty/botan/src/build-data/arch/llvm.txt new file mode 100644 index 0000000000..3b8c13ffd5 --- /dev/null +++ b/src/libs/3rdparty/botan/src/build-data/arch/llvm.txt @@ -0,0 +1 @@ +wordsize 64 diff --git a/src/libs/3rdparty/botan/src/build-data/arch/m68k.txt b/src/libs/3rdparty/botan/src/build-data/arch/m68k.txt new file mode 100644 index 0000000000..f171f4534f --- /dev/null +++ b/src/libs/3rdparty/botan/src/build-data/arch/m68k.txt @@ -0,0 +1,6 @@ +endian big + + +680x0 +68k + diff --git a/src/libs/3rdparty/botan/src/build-data/arch/mips32.txt b/src/libs/3rdparty/botan/src/build-data/arch/mips32.txt new file mode 100644 index 0000000000..d9849e8484 --- /dev/null +++ b/src/libs/3rdparty/botan/src/build-data/arch/mips32.txt @@ -0,0 +1,6 @@ + +mips +mipsbe # RedHat +mipsle # RedHat +mipsel # Debian + diff --git a/src/libs/3rdparty/botan/src/build-data/arch/mips64.txt b/src/libs/3rdparty/botan/src/build-data/arch/mips64.txt new file mode 100644 index 0000000000..6d67128ede --- /dev/null +++ b/src/libs/3rdparty/botan/src/build-data/arch/mips64.txt @@ -0,0 +1,5 @@ +wordsize 64 + + +mips64el + diff --git a/src/libs/3rdparty/botan/src/build-data/arch/powerpcspe.txt b/src/libs/3rdparty/botan/src/build-data/arch/powerpcspe.txt new file mode 100644 index 0000000000..37d3b3c0f6 --- /dev/null +++ b/src/libs/3rdparty/botan/src/build-data/arch/powerpcspe.txt @@ -0,0 +1,3 @@ +endian big + +family ppc diff --git a/src/libs/3rdparty/botan/src/build-data/arch/ppc32.txt b/src/libs/3rdparty/botan/src/build-data/arch/ppc32.txt new file mode 100644 index 0000000000..da8b7654ad --- /dev/null +++ b/src/libs/3rdparty/botan/src/build-data/arch/ppc32.txt @@ -0,0 +1,12 @@ +endian big + +family ppc + + +powerpc +ppc + + + +altivec + diff --git a/src/libs/3rdparty/botan/src/build-data/arch/ppc64.txt b/src/libs/3rdparty/botan/src/build-data/arch/ppc64.txt new file mode 100644 index 0000000000..aed017f20d --- /dev/null +++ b/src/libs/3rdparty/botan/src/build-data/arch/ppc64.txt @@ -0,0 +1,14 @@ +endian big + +family ppc +wordsize 64 + + +powerpc64 +ppc64le + + + +altivec +ppccrypto + diff --git a/src/libs/3rdparty/botan/src/build-data/arch/riscv64.txt b/src/libs/3rdparty/botan/src/build-data/arch/riscv64.txt new file mode 100644 index 0000000000..b9bc16939a --- /dev/null +++ b/src/libs/3rdparty/botan/src/build-data/arch/riscv64.txt @@ -0,0 +1 @@ +family riscv diff --git a/src/libs/3rdparty/botan/src/build-data/arch/s390.txt b/src/libs/3rdparty/botan/src/build-data/arch/s390.txt new file mode 100644 index 0000000000..64a1abdd37 --- /dev/null +++ b/src/libs/3rdparty/botan/src/build-data/arch/s390.txt @@ -0,0 +1 @@ +endian big diff --git a/src/libs/3rdparty/botan/src/build-data/arch/s390x.txt b/src/libs/3rdparty/botan/src/build-data/arch/s390x.txt new file mode 100644 index 0000000000..eb6a87d69b --- /dev/null +++ b/src/libs/3rdparty/botan/src/build-data/arch/s390x.txt @@ -0,0 +1,2 @@ +endian big +wordsize 64 diff --git a/src/libs/3rdparty/botan/src/build-data/arch/sparc32.txt b/src/libs/3rdparty/botan/src/build-data/arch/sparc32.txt new file mode 100644 index 0000000000..0680fdfc3d --- /dev/null +++ b/src/libs/3rdparty/botan/src/build-data/arch/sparc32.txt @@ -0,0 +1,7 @@ +endian big + +family sparc + + +sparc + diff --git a/src/libs/3rdparty/botan/src/build-data/arch/sparc64.txt b/src/libs/3rdparty/botan/src/build-data/arch/sparc64.txt new file mode 100644 index 0000000000..56130f26cf --- /dev/null +++ b/src/libs/3rdparty/botan/src/build-data/arch/sparc64.txt @@ -0,0 +1,2 @@ +family sparc +wordsize 64 diff --git a/src/libs/3rdparty/botan/src/build-data/arch/superh.txt b/src/libs/3rdparty/botan/src/build-data/arch/superh.txt new file mode 100644 index 0000000000..6af6dbe682 --- /dev/null +++ b/src/libs/3rdparty/botan/src/build-data/arch/superh.txt @@ -0,0 +1,4 @@ + + +sh4 + diff --git a/src/libs/3rdparty/botan/src/build-data/arch/x32.txt b/src/libs/3rdparty/botan/src/build-data/arch/x32.txt new file mode 100644 index 0000000000..d69e1247d7 --- /dev/null +++ b/src/libs/3rdparty/botan/src/build-data/arch/x32.txt @@ -0,0 +1,16 @@ +endian little + +family x86 + + +aesni +avx2 +bmi2 +rdrand +rdseed +sha +sse2 +sse41 +sse42 +ssse3 + 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 new file mode 100644 index 0000000000..6cbc5d0b33 --- /dev/null +++ b/src/libs/3rdparty/botan/src/build-data/arch/x86_32.txt @@ -0,0 +1,29 @@ +endian little + +family x86 + + +ia32 +x86 +ix86 +80x86 +i86pc # for Solaris +x86pc # for QNX +bepc # for Haiku + +i686 +i386 + + + +aesni +avx2 +bmi2 +rdrand +rdseed +sha +sse2 +sse41 +sse42 +ssse3 + diff --git a/src/libs/3rdparty/botan/src/build-data/arch/x86_64.txt b/src/libs/3rdparty/botan/src/build-data/arch/x86_64.txt new file mode 100644 index 0000000000..729363e6fa --- /dev/null +++ b/src/libs/3rdparty/botan/src/build-data/arch/x86_64.txt @@ -0,0 +1,25 @@ +endian little +wordsize 64 + +family x86 + + +amd64 +x86-64 +em64t +x64 +x86_amd64 + + + +aesni +avx2 +bmi2 +rdrand +rdseed +sha +sse2 +sse41 +sse42 +ssse3 + diff --git a/src/libs/3rdparty/botan/src/build-data/bakefile.in b/src/libs/3rdparty/botan/src/build-data/bakefile.in new file mode 100644 index 0000000000..a1c0ff134e --- /dev/null +++ b/src/libs/3rdparty/botan/src/build-data/bakefile.in @@ -0,0 +1,51 @@ +toolsets = vs2013; +shared-library botan { + defines = "BOTAN_DLL=__declspec(dllexport)"; + sources { +%{for lib_srcs} + %{i} +%{endfor} + } +} + +program cli { + deps = botan; + sources { +%{for cli_srcs} + %{i} +%{endfor} + } + + headers { +%{for cli_headers} + %{i} +%{endfor} + } + +} + +program tests { + deps = botan; + sources { +%{for test_srcs} + %{i} +%{endfor} + } +} + +includedirs += build/include/; +includedirs += build/include/external; + +%{for libs_used} +libs += "%{i}"; +%{endfor} + +archs = %{bakefile_arch}; + +vs2013.option.ClCompile.DisableSpecificWarnings = "4250;4251;4275"; +vs2013.option.ClCompile.WarningLevel = Level4; +vs2013.option.ClCompile.ExceptionHandling = SyncCThrow; +vs2013.option.ClCompile.RuntimeTypeInfo = true; +if ( $(config) == Release ) { + vs2013.option.Configuration.WholeProgramOptimization = true; +} diff --git a/src/libs/3rdparty/botan/src/build-data/botan.doxy.in b/src/libs/3rdparty/botan/src/build-data/botan.doxy.in new file mode 100644 index 0000000000..bbb0bbaf7c --- /dev/null +++ b/src/libs/3rdparty/botan/src/build-data/botan.doxy.in @@ -0,0 +1,213 @@ +# Doxyfile 1.5.4 + +PROJECT_NAME = Botan +PROJECT_NUMBER = %{version} +PROJECT_BRIEF = Crypto and TLS for C++11 +OUTPUT_DIRECTORY = %{doc_output_dir}/doxygen +DOXYFILE_ENCODING = UTF-8 +CREATE_SUBDIRS = NO +OUTPUT_LANGUAGE = English +BRIEF_MEMBER_DESC = YES +REPEAT_BRIEF = YES +ABBREVIATE_BRIEF = +ALWAYS_DETAILED_SEC = NO +INLINE_INHERITED_MEMB = YES +FULL_PATH_NAMES = YES +STRIP_FROM_PATH = +STRIP_FROM_INC_PATH = +SHORT_NAMES = NO +JAVADOC_AUTOBRIEF = NO +QT_AUTOBRIEF = NO +MULTILINE_CPP_IS_BRIEF = NO +INHERIT_DOCS = YES +SEPARATE_MEMBER_PAGES = NO +TAB_SIZE = 8 +ALIASES = +OPTIMIZE_OUTPUT_FOR_C = NO +OPTIMIZE_OUTPUT_JAVA = NO +BUILTIN_STL_SUPPORT = NO +CPP_CLI_SUPPORT = NO +SIP_SUPPORT = NO +DISTRIBUTE_GROUP_DOC = NO +SUBGROUPING = YES +TYPEDEF_HIDES_STRUCT = NO + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# Set this to NO to get warnings about undocumented members/classes +EXTRACT_ALL = YES +EXTRACT_PRIVATE = NO +EXTRACT_STATIC = NO +EXTRACT_LOCAL_CLASSES = NO +EXTRACT_LOCAL_METHODS = NO +EXTRACT_ANON_NSPACES = NO +HIDE_UNDOC_MEMBERS = NO +HIDE_UNDOC_CLASSES = NO +HIDE_FRIEND_COMPOUNDS = NO +HIDE_IN_BODY_DOCS = NO +INTERNAL_DOCS = NO +CASE_SENSE_NAMES = YES +HIDE_SCOPE_NAMES = NO +SHOW_INCLUDE_FILES = YES +INLINE_INFO = YES +SORT_MEMBER_DOCS = YES +SORT_BRIEF_DOCS = YES +SORT_BY_SCOPE_NAME = NO +GENERATE_TODOLIST = YES +GENERATE_TESTLIST = YES +GENERATE_BUGLIST = YES +GENERATE_DEPRECATEDLIST= YES +ENABLED_SECTIONS = +MAX_INITIALIZER_LINES = 30 +SHOW_USED_FILES = YES +FILE_VERSION_FILTER = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- +QUIET = YES +WARNINGS = YES +WARN_IF_UNDOCUMENTED = YES +WARN_IF_DOC_ERROR = YES +WARN_NO_PARAMDOC = YES +WARN_FORMAT = "$file:$line: $text" +WARN_LOGFILE = +WARN_AS_ERROR = YES + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- +INPUT = %{src_dir}/lib +INPUT_ENCODING = UTF-8 +FILE_PATTERNS = +RECURSIVE = YES +EXCLUDE = +EXCLUDE_SYMLINKS = NO +EXCLUDE_PATTERNS = */wrap/* +EXCLUDE_SYMBOLS = +EXAMPLE_PATH = +EXAMPLE_PATTERNS = +EXAMPLE_RECURSIVE = NO +IMAGE_PATH = +INPUT_FILTER = +FILTER_PATTERNS = +FILTER_SOURCE_FILES = NO +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- +SOURCE_BROWSER = YES +INLINE_SOURCES = YES +STRIP_CODE_COMMENTS = NO +REFERENCED_BY_RELATION = YES +REFERENCES_RELATION = YES +REFERENCES_LINK_SOURCE = YES +USE_HTAGS = NO +VERBATIM_HEADERS = YES +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- +ALPHABETICAL_INDEX = YES +COLS_IN_ALPHA_INDEX = 5 +IGNORE_PREFIX = +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- +GENERATE_HTML = YES +HTML_OUTPUT = . +HTML_FILE_EXTENSION = .html +HTML_HEADER = +HTML_FOOTER = +HTML_STYLESHEET = +GENERATE_HTMLHELP = NO +HTML_DYNAMIC_SECTIONS = NO +CHM_FILE = +HHC_LOCATION = +GENERATE_CHI = NO +BINARY_TOC = NO +TOC_EXPAND = NO +DISABLE_INDEX = NO +ENUM_VALUES_PER_LINE = 4 +GENERATE_TREEVIEW = NO +TREEVIEW_WIDTH = 250 + +#--------------------------------------------------------------------------- +# Configuration options related to other output formats +#--------------------------------------------------------------------------- +GENERATE_LATEX = NO +GENERATE_MAN = NO +GENERATE_RTF = NO +GENERATE_XML = NO + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- +ENABLE_PREPROCESSING = YES +MACRO_EXPANSION = YES +EXPAND_ONLY_PREDEF = NO +SEARCH_INCLUDES = YES +INCLUDE_PATH = +INCLUDE_FILE_PATTERNS = +PREDEFINED = BOTAN_HAS_AES_ARMV8 \ + BOTAN_HAS_AES_NI \ + BOTAN_HAS_AES_POWER8 \ + BOTAN_HAS_AES_SSSE3 \ + BOTAN_HAS_CHACHA_SSE2 \ + BOTAN_HAS_IDEA_SSE2 \ + BOTAN_HAS_NOEKEON_SIMD \ + BOTAN_HAS_SERPENT_SIMD \ + 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_THREEFISH_512_AVX2 \ + BOTAN_DEPRECATED(msg)= \ + BOTAN_PUBLIC_API(maj,min)= + + +EXPAND_AS_DEFINED = +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- +TAGFILES = +GENERATE_TAGFILE = +ALLEXTERNALS = NO +EXTERNAL_GROUPS = YES +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- +CLASS_DIAGRAMS = YES +MSCGEN_PATH = +HIDE_UNDOC_RELATIONS = YES +HAVE_DOT = NO +CLASS_GRAPH = YES +COLLABORATION_GRAPH = YES +GROUP_GRAPHS = YES +UML_LOOK = NO +TEMPLATE_RELATIONS = NO +INCLUDE_GRAPH = YES +INCLUDED_BY_GRAPH = YES +CALL_GRAPH = NO +CALLER_GRAPH = NO +GRAPHICAL_HIERARCHY = YES +DIRECTORY_GRAPH = YES +DOT_IMAGE_FORMAT = png +DOT_PATH = +DOTFILE_DIRS = +DOT_GRAPH_MAX_NODES = 50 +MAX_DOT_GRAPH_DEPTH = 0 +DOT_TRANSPARENT = YES +DOT_MULTI_TARGETS = NO +GENERATE_LEGEND = YES +DOT_CLEANUP = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- +SEARCHENGINE = NO diff --git a/src/libs/3rdparty/botan/src/build-data/botan.pc.in b/src/libs/3rdparty/botan/src/build-data/botan.pc.in new file mode 100644 index 0000000000..e19f0efed1 --- /dev/null +++ b/src/libs/3rdparty/botan/src/build-data/botan.pc.in @@ -0,0 +1,12 @@ +prefix=%{prefix} +exec_prefix=${prefix} +libdir=${prefix}/%{libdir} +includedir=${prefix}/include/botan-%{version_major} + +Name: Botan +Description: Crypto and TLS for C++11 +Version: %{version} + +Libs: -L${libdir} -lbotan-%{version_major} %{cxx_abi_flags} +Libs.private: %{link_to} +Cflags: -I${includedir} diff --git a/src/libs/3rdparty/botan/src/build-data/buildh.in b/src/libs/3rdparty/botan/src/build-data/buildh.in new file mode 100644 index 0000000000..f34cf26a39 --- /dev/null +++ b/src/libs/3rdparty/botan/src/build-data/buildh.in @@ -0,0 +1,258 @@ +#ifndef BOTAN_BUILD_CONFIG_H_ +#define BOTAN_BUILD_CONFIG_H_ + +/* +* This file was automatically generated running +* '%{command_line}' +* +* Target +* - Compiler: %{cxx} %{cxx_abi_flags} %{cc_lang_flags} %{cc_compile_flags} +* - Arch: %{arch} +* - OS: %{os} +*/ + +#define BOTAN_VERSION_MAJOR %{version_major} +#define BOTAN_VERSION_MINOR %{version_minor} +#define BOTAN_VERSION_PATCH %{version_patch} +#define BOTAN_VERSION_DATESTAMP %{version_datestamp} + +#define BOTAN_VERSION_RELEASE_TYPE "%{release_type}" + +#define BOTAN_VERSION_VC_REVISION "%{version_vc_rev}" + +#define BOTAN_DISTRIBUTION_INFO "%{distribution_info}" + +/* How many bits per limb in a BigInt */ +#define BOTAN_MP_WORD_BITS %{mp_bits} + +%{if fuzzer_mode} +#define BOTAN_UNSAFE_FUZZER_MODE +%{endif} +%{if fuzzer_type} +#define BOTAN_FUZZER_IS_%{fuzzer_type} +%{endif} + +#define BOTAN_INSTALL_PREFIX R"(%{prefix})" +#define BOTAN_INSTALL_HEADER_DIR "%{includedir}/botan-%{version_major}" +#define BOTAN_INSTALL_LIB_DIR "%{libdir}" +#define BOTAN_LIB_LINK "%{link_to}" +#define BOTAN_LINK_FLAGS "%{cxx_abi_flags}" + +#ifndef BOTAN_DLL + #define BOTAN_DLL %{visibility_attribute} +#endif + +/* Target identification and feature test macros */ + +#define BOTAN_TARGET_OS_IS_%{os_name|upper} + +%{for os_features} +#define BOTAN_TARGET_OS_HAS_%{i|upper} +%{endfor} + +#define BOTAN_BUILD_COMPILER_IS_%{cc_macro} + +%{for sanitizer_types} +#define BOTAN_HAS_SANITIZER_%{i|upper} +%{endfor} + +%{if test_mode} +#define BOTAN_TEST_MODE +%{endif} + +#define BOTAN_TARGET_ARCH_IS_%{arch|upper} +%{if endian} +#define BOTAN_TARGET_CPU_IS_%{endian|upper}_ENDIAN +%{endif} +%{if cpu_family} +#define BOTAN_TARGET_CPU_IS_%{cpu_family|upper}_FAMILY +%{endif} +%{if cpu_is_64bit} +#define BOTAN_TARGET_CPU_HAS_NATIVE_64BIT +%{endif} + +%{for cpu_features} +#define BOTAN_TARGET_SUPPORTS_%{i|upper} +%{endfor} + +%{if with_valgrind} +#define BOTAN_HAS_VALGRIND +%{endif} + +%{if with_openmp} +#define BOTAN_TARGET_HAS_OPENMP +%{endif} + +%{if with_debug_asserts} +#define BOTAN_ENABLE_DEBUG_ASSERTS +%{endif} + +/* +* Module availability definitions +*/ +%{for module_defines} +#define BOTAN_HAS_%{i} +%{endfor} + +/* +* Local/misc configuration options (if any) follow +*/ +%{local_config} + +/* +* Things you can edit (but probably shouldn't) +*/ + +#if !defined(BOTAN_DEPRECATED_PUBLIC_MEMBER_VARIABLES) + + #if defined(BOTAN_NO_DEPRECATED) + #define BOTAN_DEPRECATED_PUBLIC_MEMBER_VARIABLES private + #else + #define BOTAN_DEPRECATED_PUBLIC_MEMBER_VARIABLES public + #endif + +#endif + +/* How much to allocate for a buffer of no particular size */ +#define BOTAN_DEFAULT_BUFFER_SIZE 1024 + +/* Minimum and maximum sizes to allocate out of the mlock pool (bytes) + Default min is 16 as smaller values are easily bruteforceable and thus + likely not cryptographic keys. +*/ +#define BOTAN_MLOCK_ALLOCATOR_MIN_ALLOCATION 16 +#define BOTAN_MLOCK_ALLOCATOR_MAX_ALLOCATION 128 + +/* +* Total maximum amount of RAM (in KiB) we will lock into memory, even +* if the OS would let us lock more +*/ +#define BOTAN_MLOCK_ALLOCATOR_MAX_LOCKED_KB 512 + +/* +* If enabled uses memset via volatile function pointer to zero memory, +* otherwise does a byte at a time write via a volatile pointer. +*/ +#define BOTAN_USE_VOLATILE_MEMSET_FOR_ZERO 1 + +/* +* Normally blinding is performed by choosing a random starting point (plus +* its inverse, of a form appropriate to the algorithm being blinded), and +* then choosing new blinding operands by successive squaring of both +* values. This is much faster than computing a new starting point but +* introduces some possible corelation +* +* To avoid possible leakage problems in long-running processes, the blinder +* periodically reinitializes the sequence. This value specifies how often +* a new sequence should be started. +*/ +#define BOTAN_BLINDING_REINIT_INTERVAL 64 + +/* +* Userspace RNGs like HMAC_DRBG will reseed after a specified number +* of outputs are generated. Set to zero to disable automatic reseeding. +*/ +#define BOTAN_RNG_DEFAULT_RESEED_INTERVAL 1024 +#define BOTAN_RNG_RESEED_POLL_BITS 256 + +#define BOTAN_RNG_AUTO_RESEED_TIMEOUT std::chrono::milliseconds(10) +#define BOTAN_RNG_RESEED_DEFAULT_TIMEOUT std::chrono::milliseconds(50) + +/* +* Specifies (in order) the list of entropy sources that will be used +* to seed an in-memory RNG. The first in the default list: "rdseed" +* and "rdrand" do not count as contributing any entropy but are +* included as they are fast and help protect against a seriously +* broken system RNG. +*/ +#define BOTAN_ENTROPY_DEFAULT_SOURCES \ + { "rdseed", "rdrand", "darwin_secrandom", "getentropy", \ + "dev_random", "system_rng", "proc_walk", "system_stats" } + +/* Multiplier on a block cipher's native parallelism */ +#define BOTAN_BLOCK_CIPHER_PAR_MULT 4 + +/* +* 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" } + +/* +* This directory will be monitored by ProcWalking_EntropySource and +* the contents provided as entropy inputs to the RNG. May also be +* usefully set to something like "/sys", depending on the system being +* deployed to. Set to an empty string to disable. +*/ +#define BOTAN_ENTROPY_PROC_FS_PATH "/proc" + +/* +* These paramaters control how many bytes to read from the system +* PRNG, and how long to block if applicable. The timeout only applies +* to reading /dev/urandom and company. +*/ +#define BOTAN_SYSTEM_RNG_POLL_REQUEST 64 +#define BOTAN_SYSTEM_RNG_POLL_TIMEOUT_MS 20 + +/* +How many times to read from the RDRAND/RDSEED RNGs. +Each read generates 32 bits of output +*/ +#define BOTAN_ENTROPY_INTEL_RNG_POLLS 32 + +// According to Intel, RDRAND is guaranteed to generate a random number within 10 retries on a working CPU +#define BOTAN_ENTROPY_RDRAND_RETRIES 10 + +/* +* RdSeed is not guaranteed to generate a random number within a specific number of retries +* Define the number of retries here +*/ +#define BOTAN_ENTROPY_RDSEED_RETRIES 20 + +/* +* If no way of dynamically determining the cache line size for the +* system exists, this value is used as the default. Used by the side +* channel countermeasures rather than for alignment purposes, so it is +* better to be on the smaller side if the exact value cannot be +* determined. Typically 32 or 64 bytes on modern CPUs. +*/ +#if !defined(BOTAN_TARGET_CPU_DEFAULT_CACHE_LINE_SIZE) + #define BOTAN_TARGET_CPU_DEFAULT_CACHE_LINE_SIZE 32 +#endif + +/** +* Controls how AutoSeeded_RNG is instantiated +*/ +#if !defined(BOTAN_AUTO_RNG_HMAC) + + #if defined(BOTAN_HAS_SHA2_64) + #define BOTAN_AUTO_RNG_HMAC "HMAC(SHA-384)" + #elif defined(BOTAN_HAS_SHA2_32) + #define BOTAN_AUTO_RNG_HMAC "HMAC(SHA-256)" + #elif defined(BOTAN_HAS_SHA3) + #define BOTAN_AUTO_RNG_HMAC "HMAC(SHA-3(256))" + #elif defined(BOTAN_HAS_SHA1) + #define BOTAN_AUTO_RNG_HMAC "HMAC(SHA-1)" + #endif + // Otherwise, no hash found: leave BOTAN_AUTO_RNG_HMAC undefined + +#endif + +// Check for a common build problem: + +#if defined(BOTAN_TARGET_ARCH_IS_X86_64) && ((defined(_MSC_VER) && !defined(_WIN64)) || \ + (defined(__clang__) && !defined(__x86_64__)) || \ + (defined(__GNUG__) && !defined(__x86_64__))) + #error "Trying to compile Botan configured as x86_64 with non-x86_64 compiler." +#endif + +#if defined(BOTAN_TARGET_ARCH_IS_X86_32) && ((defined(_MSC_VER) && defined(_WIN64)) || \ + (defined(__clang__) && !defined(__i386__)) || \ + (defined(__GNUG__) && !defined(__i386__))) + + #error "Trying to compile Botan configured as x86_32 with non-x86_32 compiler." +#endif + +#include + +#endif diff --git a/src/libs/3rdparty/botan/src/build-data/cc/clang.txt b/src/libs/3rdparty/botan/src/build-data/cc/clang.txt new file mode 100644 index 0000000000..948a881cf8 --- /dev/null +++ b/src/libs/3rdparty/botan/src/build-data/cc/clang.txt @@ -0,0 +1,82 @@ +macro_name CLANG + +binary_name clang++ + +lang_flags "-std=c++11 -D_REENTRANT" + +warning_flags "-Wall -Wextra -Wpedantic -Wshadow -Wstrict-aliasing -Wstrict-overflow=5 -Wcast-align -Wmissing-declarations -Wpointer-arith -Wcast-qual" +maintainer_warning_flags "-Wunreachable-code -Wdocumentation -Qunused-arguments -Werror -Wno-error=unused-parameter -Wno-error=unreachable-code" + +optimization_flags "-O3" +sanitizer_optimization_flags "-O1 -fno-optimize-sibling-calls -fno-omit-frame-pointer" +size_optimization_flags "-Os" + +add_sysroot_option "--sysroot=" + + +default -> address,undefined + +address -> "-fsanitize=address" +undefined -> "-fsanitize=undefined -fno-sanitize-recover=undefined" +coverage -> "-fsanitize-coverage=edge,indirect-calls,8bit-counters" +memory -> "-fsanitize=memory" + + +shared_flags "-fPIC" +coverage_flags "--coverage" +stack_protector_flags "-fstack-protector" + +visibility_build_flags "-fvisibility=hidden" +visibility_attribute '__attribute__((visibility("default")))' + + +darwin -> "$(CXX) -dynamiclib -fPIC -install_name $(INSTALLED_LIB_DIR)/{soname_abi} -current_version {darwin_so_current_ver} -compatibility_version {darwin_so_compat_ver}" + +# The default works for GNU ld and several other Unix linkers +default -> "$(CXX) -shared -fPIC -Wl,-soname,{soname_abi}" + + + +darwin -> "$(LINKER) -headerpad_max_install_names" +linux -> "$(LINKER) -Wl,-rpath=\$$ORIGIN" +freebsd -> "$(LINKER) -Wl,-rpath=\$$ORIGIN" +default -> "$(LINKER)" +llvm -> "llvm-link" + + + +sse2 -> "-msse2" +ssse3 -> "-mssse3" +sse41 -> "-msse4.1" +sse42 -> "-msse4.2" +avx2 -> "-mavx2" +bmi2 -> "-mbmi -mbmi2" +aesni -> "-maes -mpclmul -mssse3" +rdrand -> "-mrdrnd" +rdseed -> "-mrdseed" +sha -> "-msha" +altivec -> "-maltivec" + +arm64:armv8crypto -> "" + +arm32:neon -> "-mfpu=neon" +arm64:neon -> "" + + + +llvm -> "-emit-llvm -fno-use-cxa-atexit" + + + +all!haiku,darwin -> "-pthread" + +openmp -> "-fopenmp" + +x86_32 -> "-m32" +x86_64 -> "-m64" +ppc64 -> "-m64" + +darwin -> "-stdlib=libc++" +ios -> "-stdlib=libc++" +netbsd -> "-D_NETBSD_SOURCE" + diff --git a/src/libs/3rdparty/botan/src/build-data/cc/ekopath.txt b/src/libs/3rdparty/botan/src/build-data/cc/ekopath.txt new file mode 100644 index 0000000000..490396ac43 --- /dev/null +++ b/src/libs/3rdparty/botan/src/build-data/cc/ekopath.txt @@ -0,0 +1,17 @@ +macro_name PATHSCALE + +binary_name pathCC + +optimization_flags "-O3" + +lang_flags "-D_REENTRANT -ansi -Wno-long-long" +warning_flags "-W -Wall" + +ar_command pathCC +ar_options "-ar -o" + +shared_flags "-fPIC" + + +default -> "$(CXX) -shared -fPIC -Wl,-soname,{soname_abi}" + diff --git a/src/libs/3rdparty/botan/src/build-data/cc/gcc.txt b/src/libs/3rdparty/botan/src/build-data/cc/gcc.txt new file mode 100644 index 0000000000..98f1a21674 --- /dev/null +++ b/src/libs/3rdparty/botan/src/build-data/cc/gcc.txt @@ -0,0 +1,99 @@ +macro_name GCC + +binary_name g++ + +lang_flags "-std=c++11 -D_REENTRANT" + +# This should only contain flags which are included in GCC 4.8 +warning_flags "-Wall -Wextra -Wpedantic -Wstrict-aliasing -Wcast-align -Wmissing-declarations -Wpointer-arith -Wcast-qual -Wzero-as-null-pointer-constant -Wnon-virtual-dtor" + +maintainer_warning_flags "-Wstrict-overflow=5 -Wold-style-cast -Wsuggest-override -Wshadow -Werror -Wno-error=strict-overflow" + +optimization_flags "-O3" +sanitizer_optimization_flags "-O1 -fno-optimize-sibling-calls -fno-omit-frame-pointer" +size_optimization_flags "-Os" + +shared_flags "-fPIC" +coverage_flags "--coverage" +stack_protector_flags "-fstack-protector" + +add_sysroot_option "--sysroot=" + + +default -> iterator,address + +iterator -> "-D_GLIBCXX_DEBUG" +address -> "-fsanitize=address" +undefined -> "-fsanitize=undefined -fno-sanitize-recover=undefined" + + +visibility_build_flags "-fvisibility=hidden" +visibility_attribute '__attribute__((visibility("default")))' + + +# The default works for GNU ld and several other Unix linkers +default -> "$(CXX) -shared -fPIC -Wl,-soname,{soname_abi}" + +# Darwin, HP-UX and Solaris linkers use different syntax +darwin -> "$(CXX) -dynamiclib -fPIC -install_name $(INSTALLED_LIB_DIR)/{soname_abi}" +hpux -> "$(CXX) -shared -fPIC -Wl,+h,{soname_abi}" +solaris -> "$(CXX) -shared -fPIC -Wl,-h,{soname_abi}" + +# AIX and OpenBSD don't use sonames at all +aix -> "$(CXX) -shared -fPIC" +openbsd -> "$(CXX) -shared -fPIC" + + + +linux -> "$(LINKER) -Wl,-rpath=\$$ORIGIN" +default -> "$(LINKER)" + + + +sse2 -> "-msse2" +ssse3 -> "-mssse3" +sse41 -> "-msse4.1" +sse42 -> "-msse4.2" +avx2 -> "-mavx2" +bmi2 -> "-mbmi -mbmi2" +aesni -> "-maes -mpclmul -mssse3" +rdrand -> "-mrdrnd" +rdseed -> "-mrdseed" +sha -> "-msha" +altivec -> "-maltivec" + +ppccrypto -> "-mcrypto" + +arm64:armv8crypto -> "" + +# For Aarch32 -mfpu=neon is required +# For Aarch64 NEON is enabled by default +arm32:neon -> "-mfpu=neon" +arm64:neon -> "" + + + +x86_32 -> "-momit-leaf-frame-pointer" +x86_64 -> "-momit-leaf-frame-pointer" + + +# Flags set here are included at compile and link time + +all!haiku -> "-pthread" + +openmp -> "-fopenmp" + +mips64 -> "-mabi=64" +s390 -> "-m31" +s390x -> "-m64" +sparc32 -> "-m32 -mno-app-regs" +sparc64 -> "-m64 -mno-app-regs" +ppc64 -> "-m64" +x86_32 -> "-m32" +x86_64 -> "-m64" +x32 -> "-mx32" + +netbsd -> "-D_NETBSD_SOURCE" +qnx -> "-fexceptions -D_QNX_SOURCE" +cygwin -> "-U__STRICT_ANSI__" + diff --git a/src/libs/3rdparty/botan/src/build-data/cc/hpcc.txt b/src/libs/3rdparty/botan/src/build-data/cc/hpcc.txt new file mode 100644 index 0000000000..cbe50c37d9 --- /dev/null +++ b/src/libs/3rdparty/botan/src/build-data/cc/hpcc.txt @@ -0,0 +1,18 @@ +macro_name HP_ACC + +binary_name aCC + +lang_flags "-AA -ext +eh -z" +optimization_flags "+O2" +warning_flags "+w" +shared_flags "+Z" + + +hppa1.0 -> "+DAportable" +hppa1.1 -> "+DA1.1" +hppa2.0 -> "+DA2.0W" + + + +default -> "$(CXX) +Z -b -Wl,+h,{soname_abi}" # Documented in cc(1), but not CC(1) (?) + diff --git a/src/libs/3rdparty/botan/src/build-data/cc/icc.txt b/src/libs/3rdparty/botan/src/build-data/cc/icc.txt new file mode 100644 index 0000000000..c8a1aa3dc7 --- /dev/null +++ b/src/libs/3rdparty/botan/src/build-data/cc/icc.txt @@ -0,0 +1,24 @@ +macro_name INTEL + +binary_name icpc + +optimization_flags "-O2" +size_optimization_flags "-Os" + +lang_flags "-std=c++11" +warning_flags "-w1" +shared_flags "-fPIC" + + +sse2 -> "-msse2" +ssse3 -> "-mssse3" +sse41 -> "-msse4.1" +sse42 -> "-msse4.2" +avx2 -> "-march=core-avx2" +aesni -> "-march=corei7" +rdrand -> "-march=core-avx-i" + + + +default -> "$(CXX) -fPIC -shared -Wl,-soname,{soname_abi}" + diff --git a/src/libs/3rdparty/botan/src/build-data/cc/msvc.txt b/src/libs/3rdparty/botan/src/build-data/cc/msvc.txt new file mode 100644 index 0000000000..ed32a3c3cd --- /dev/null +++ b/src/libs/3rdparty/botan/src/build-data/cc/msvc.txt @@ -0,0 +1,66 @@ +macro_name MSVC + +binary_name cl +linker_name link + +output_to_object "/Fo" +output_to_exe "/OUT:" + +add_include_dir_option "/I" +add_lib_dir_option "/LIBPATH:" +add_lib_option "" + +compile_flags "/nologo /c" + +optimization_flags "/O2 /Oi" +size_optimization_flags "/O1 /Os" + +# for debug info in the object file: +#debug_info_flags "/Z7" + +# for using a PDB file: +debug_info_flags "/Zi /FS" + +preproc_flags "/nologo /EP" + +lang_flags "/EHs /GR" +warning_flags "/W4 /wd4250 /wd4251 /wd4275" + +visibility_build_flags "/DBOTAN_DLL=__declspec(dllexport)" +visibility_attribute "__declspec(dllimport)" + +ar_command lib +ar_options "/nologo" +ar_output_to "/OUT:" + + +sse2 -> "" +ssse3 -> "" +sse41 -> "" +sse42 -> "" +x86_64:avx2 -> "" +bmi2 -> "" +aesni -> "" +clmul -> "" +rdrand -> "" +rdseed -> "" +sha -> "" + + + +default -> "$(LINKER) /DLL" +default-debug -> "$(LINKER) /DLL /DEBUG" + + + +default -> "$(LINKER)" +default-debug -> "$(LINKER) /DEBUG" + + + +all -> "/bigobj" + +# These can be overridden with --msvc-runtime option +rt -> "/MD" +rt-debug -> "/MDd" + diff --git a/src/libs/3rdparty/botan/src/build-data/cc/pgi.txt b/src/libs/3rdparty/botan/src/build-data/cc/pgi.txt new file mode 100644 index 0000000000..5ec6586280 --- /dev/null +++ b/src/libs/3rdparty/botan/src/build-data/cc/pgi.txt @@ -0,0 +1,11 @@ +macro_name PORTLAND_GROUP + +binary_name pgCC + +optimization_flags "-fast -Minline" +shared_flags "-fPIC" + + +linux -> "$(CXX) -shared -fPIC -Wl,-soname,{soname_abi}" +solaris -> "$(CXX) -G -fPIC -Wl,-h,{soname_abi}" + diff --git a/src/libs/3rdparty/botan/src/build-data/cc/sunstudio.txt b/src/libs/3rdparty/botan/src/build-data/cc/sunstudio.txt new file mode 100644 index 0000000000..c5dac65de1 --- /dev/null +++ b/src/libs/3rdparty/botan/src/build-data/cc/sunstudio.txt @@ -0,0 +1,39 @@ +macro_name SUN_STUDIO + +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__" + +ar_command CC +ar_options "-xar -o" + + +default -> "$(CXX) -G -h{soname_abi}" + + + +# Needed on some Linux distros +linux -> "-library=stlport4" + +sparc64 -> "-xarch=v9" +x86_64 -> "-m64" + + + +# Botan needs C++11, and that requires Sun Studio 12.4 or above. +# Sun Studio 12.4 supports upto -xarch=avx2, but the processor must support it +# AESNI requires -xarch=aes, and RDRAND requires -xarch=avx_i. +# https://docs.oracle.com/cd/E37069_01/html/E37074/bjapp.html#OSSCGbkazd +sse2 -> "-xarch=sse2" +ssse3 -> "-xarch=ssse3" +sse41 -> "-xarch=sse4.1" +sse42 -> "-xarch=sse4.2" +aesni -> "-xarch=aes" +avx -> "-xarch=avx" +rdrand -> "-xarch=avx_i" +avx2 -> "-xarch=avx2" + diff --git a/src/libs/3rdparty/botan/src/build-data/cc/xlc.txt b/src/libs/3rdparty/botan/src/build-data/cc/xlc.txt new file mode 100644 index 0000000000..fa3bb85f0b --- /dev/null +++ b/src/libs/3rdparty/botan/src/build-data/cc/xlc.txt @@ -0,0 +1,24 @@ +macro_name XLC + +binary_name xlC + +optimization_flags "-O2" + +lang_flags "-std=c++11" + +visibility_build_flags "-fvisibility=hidden" +visibility_attribute '__attribute__((visibility("default")))' + + +altivec -> "-qaltivec" + + + +default -> "$(CXX) -qmkshrobj" + + + +default -> "-qcheck=all" +address -> "-qcheck=bounds:stackclobber:unset" +undefined -> "-qcheck=nullptr:divzero" + diff --git a/src/libs/3rdparty/botan/src/build-data/cmake.in b/src/libs/3rdparty/botan/src/build-data/cmake.in new file mode 100644 index 0000000000..1595401f66 --- /dev/null +++ b/src/libs/3rdparty/botan/src/build-data/cmake.in @@ -0,0 +1,73 @@ +cmake_minimum_required(VERSION 2.8.0) +project(botan) + +if(POLICY CMP0042) +cmake_policy(SET CMP0042 NEW) +endif() + +set(BOTAN_SOURCES +%{for lib_srcs} + "%{i}" +%{endfor} +) + +set(BOTAN_CLI +%{for cli_srcs} + "%{i}" +%{endfor} +) + +set(BOTAN_TESTS +%{for test_srcs} + "%{i}" +%{endfor} +) + +%{for isa_build_info} +set_source_files_properties("%{src}" PROPERTIES COMPILE_FLAGS "%{isa_flags}") +%{endfor} + +option(ENABLED_OPTIONAL_WARINIGS "If enabled more strict warning policy will be used" OFF) +option(ENABLED_LTO "If enabled link time optimization will be used" OFF) + +set(COMPILER_FEATURES_RELEASE %{cc_lang_flags} %{cc_compile_opt_flags} %{cxx_abi_opt_flags}) +set(COMPILER_FEATURES_DEBUG %{cc_lang_flags} %{cc_compile_debug_flags} %{cxx_abi_debug_flags}) +set(COMPILER_FEATURES $<$>:${COMPILER_FEATURES_RELEASE}> $<$:${COMPILER_FEATURES_DEBUG}>) +set(SHARED_FEATURES %{cmake_shared_flags}) +set(STATIC_FEATURES -DBOTAN_DLL=) +set(COMPILER_WARNINGS %{cc_warning_flags}) +set(COMPILER_INCLUDE_DIRS build/include build/include/external) +if(ENABLED_LTO) + set(COMPILER_FEATURES ${COMPILER_FEATURES} -lto) +endif() +if(ENABLED_OPTIONAL_WARINIGS) + set(COMPILER_OPTIONAL_WARNINGS -Wsign-promo -Wctor-dtor-privacy -Wdeprecated -Winit-self -Wnon-virtual-dtor -Wunused-macros -Wold-style-cast -Wuninitialized) +endif() + +add_library(${PROJECT_NAME} STATIC ${BOTAN_SOURCES}) +target_link_libraries(${PROJECT_NAME} PUBLIC %{cmake_link_to}) +target_compile_options(${PROJECT_NAME} PUBLIC ${COMPILER_WARNINGS} ${COMPILER_FEATURES} ${COMPILER_OPTIONAL_WARNINGS} PRIVATE ${STATIC_FEATURES}) +target_include_directories(${PROJECT_NAME} PUBLIC ${COMPILER_INCLUDE_DIRS}) + +set_target_properties(${PROJECT_NAME} PROPERTIES OUTPUT_NAME ${PROJECT_NAME}-static) + +add_library(${PROJECT_NAME}_shared SHARED ${BOTAN_SOURCES}) +target_link_libraries(${PROJECT_NAME}_shared PUBLIC %{cmake_link_to}) +target_compile_options(${PROJECT_NAME}_shared PUBLIC ${COMPILER_WARNINGS} ${COMPILER_FEATURES} ${COMPILER_OPTIONAL_WARNINGS} PRIVATE ${SHARED_FEATURES}) +target_include_directories(${PROJECT_NAME}_shared PUBLIC ${COMPILER_INCLUDE_DIRS}) +set_target_properties(${PROJECT_NAME}_shared PROPERTIES OUTPUT_NAME ${PROJECT_NAME}) + +add_executable(${PROJECT_NAME}_cli ${BOTAN_CLI}) +target_link_libraries(${PROJECT_NAME}_cli PRIVATE ${PROJECT_NAME}_shared ) +set_target_properties(${PROJECT_NAME}_cli PROPERTIES OUTPUT_NAME ${PROJECT_NAME}-cli) + +add_executable(${PROJECT_NAME}_tests ${BOTAN_TESTS}) +target_link_libraries(${PROJECT_NAME}_tests PRIVATE ${PROJECT_NAME}_shared ) +set_target_properties(${PROJECT_NAME}_tests PROPERTIES OUTPUT_NAME botan-test) + +set(GLOBAL_CONFIGURATION_FILES configure.py .gitignore news.rst readme.rst) +file(GLOB_RECURSE CONFIGURATION_FILES src/configs/* ) +file(GLOB_RECURSE DOCUMENTATION_FILES doc/* ) +file(GLOB_RECURSE HEADER_FILES src/*.h ) +file(GLOB_RECURSE INFO_FILES src/lib/*info.txt ) +add_custom_target(CONFIGURATION_DUMMY SOURCES ${GLOBAL_CONFIGURATION_FILES} ${CONFIGURATION_FILES} ${DOCUMENTATION_FILES} ${INFO_FILES} ${HEADER_FILES}) diff --git a/src/libs/3rdparty/botan/src/build-data/detect_arch.cpp b/src/libs/3rdparty/botan/src/build-data/detect_arch.cpp new file mode 100644 index 0000000000..f5e6ecd582 --- /dev/null +++ b/src/libs/3rdparty/botan/src/build-data/detect_arch.cpp @@ -0,0 +1,63 @@ + +#if defined(__x86_64__) && defined(__ILP32__) + X32 + +#elif defined(__x86_64__) || defined(_M_X64) + X86_64 + +#elif defined(__i386__) || defined(__i386) || defined(_M_IX86) + X86_32 + +#elif defined(__aarch64__) || defined(__ARM_ARCH_ISA_A64) + ARM64 + +#elif defined(__arm__) || defined(_M_ARM) || defined(__ARM_ARCH_7A__) + ARM32 + +#elif defined(__powerpc64__) || defined(__ppc64__) || defined(_ARCH_PPC64) + PPC64 + +#elif defined(__powerpc__) || defined(__ppc__) || defined(_ARCH_PPC) + PPC32 + +#elif defined(__mips__) || defined(__mips) + + #if defined(__LP64__) || defined(_LP64) + MIPS64 + #else + MIPS32 + #endif + +#elif defined(__sparc__) + + #if defined(__LP64__) || defined(_LP64) + SPARC64 + #else + SPARC32 + #endif + +#elif defined(__alpha__) + ALPHA + +#elif defined(__hppa__) || defined(__hppa) + HPPA + +#elif defined(__ia64__) + IA64 + +#elif defined(__m68k__) + M68K + +#elif defined(__sh__) + SH + +#elif defined(__s390x__) + S390X + +#elif defined(__s390__) + S390 + +#else + UNKNOWN + +#endif diff --git a/src/libs/3rdparty/botan/src/build-data/detect_version.cpp b/src/libs/3rdparty/botan/src/build-data/detect_version.cpp new file mode 100644 index 0000000000..12a5a707e3 --- /dev/null +++ b/src/libs/3rdparty/botan/src/build-data/detect_version.cpp @@ -0,0 +1,60 @@ +/* +* This file is preprocessed to produce output that is examined by +* configure.py to determine the compilers version number. +*/ + +#if defined(_MSC_VER) + + /* + _MSC_VER Defined as an integer literal that encodes the major and + minor number elements of the compiler's version number. The major + number is the first element of the period-delimited version number + and the minor number is the second element. For example, if the + version number of the Visual C++ compiler is 17.00.51106.1, the + _MSC_VER macro evaluates to 1700. + https://msdn.microsoft.com/en-us/library/b0084kay.aspx + */ + MSVC _MSC_VER + +#elif defined(__xlC__) + + XLC __xlC__ + +#elif defined(__clang__) && defined(__apple_build_version__) + + /* + Map Apple LLVM versions as used in XCode back to standard Clang. + This is not exact since the versions used in XCode are actually + forks of Clang and do not coorespond perfectly to standard Clang + releases. In addition we don't bother mapping very old versions + (anything before XCode 7 is treated like Clang 3.5, which is the + oldest version we support) and for "future" versions we simply + treat them as Clang 4.0, since we don't currenly rely on any + features not included in 4.0 + */ + + #if __clang_major__ >= 9 + CLANG 4 0 + #elif __clang_major__ == 8 + CLANG 3 9 + #elif __clang_major__ == 7 && __clang_minor__ == 3 + CLANG 3 8 + #elif __clang_major__ == 7 + CLANG 3 7 + #else + CLANG 3 5 + #endif + +#elif defined(__clang__) + + CLANG __clang_major__ __clang_minor__ + +#elif defined(__GNUG__) + + GCC __GNUC__ __GNUC_MINOR__ + +#else + + UNKNOWN 0 0 + +#endif diff --git a/src/libs/3rdparty/botan/src/build-data/innosetup.in b/src/libs/3rdparty/botan/src/build-data/innosetup.in new file mode 100644 index 0000000000..86df5f27bf --- /dev/null +++ b/src/libs/3rdparty/botan/src/build-data/innosetup.in @@ -0,0 +1,73 @@ +; A script for packaging botan with InnoSetup + +[Setup] +AppName=Botan +AppVerName=Botan %{version} + +AppPublisher=Jack Lloyd +AppPublisherURL=https://botan.randombit.net/ +AppVersion=%{version} + +VersionInfoCopyright=Copyright (C) 1999-2012 Jack Lloyd and others +VersionInfoVersion=%{version_major}.%{version_minor}.%{version_patch}.0 + +; Require at least Windows XP +MinVersion=5.1 + +ArchitecturesAllowed=%{innosetup_arch} +ArchitecturesInstallIn64BitMode=%{innosetup_arch} + +DefaultDirName={pf}\botan +DefaultGroupName=botan + +SolidCompression=yes + +OutputDir=. +OutputBaseFilename=botan-%{version}-%{arch} + +[Types] +Name: "user"; Description: "User" +Name: "devel"; Description: "Developer" +Name: "custom"; Description: "Custom"; Flags: iscustom + +[Components] +name: "dll"; Description: "Runtime DLLs"; Types: user devel custom; Flags: fixed +name: "implib"; Description: "Import Library"; Types: devel +name: "includes"; Description: "Include Files"; Types: devel +name: "docs"; Description: "Developer Documentation"; Types: devel + +[Files] +; DLL and license file is always included +Source: "..\doc\license.rst"; DestDir: "{app}"; Components: dll; AfterInstall: ConvertLineEndings +Source: "..\botan.dll"; DestDir: "{app}"; Components: dll +Source: "..\botan.dll.manifest"; DestDir: "{app}"; Components: dll; Flags: skipifsourcedoesntexist + +Source: "include\botan\*"; DestDir: "{app}\include\botan"; Components: includes; AfterInstall: ConvertLineEndings + +Source: "..\doc\*.rst"; DestDir: "{app}\doc"; Excludes: "license.rst"; Components: docs; AfterInstall: ConvertLineEndings + +Source: "..\doc\examples\*.cpp"; DestDir: "{app}\doc\examples"; Components: docs; AfterInstall: ConvertLineEndings + +Source: "..\botan.exp"; DestDir: "{app}"; Components: implib +Source: "..\botan.lib"; DestDir: "{app}"; Components: implib + +[Code] +const + LF = #10; + CR = #13; + CRLF = CR + LF; + +procedure ConvertLineEndings(); + var + FilePath : String; + FileContents : String; +begin + FilePath := ExpandConstant(CurrentFileName) + + if ExtractFileName(CurrentFileName) <> 'build.h' then + begin + LoadStringFromFile(FilePath, FileContents); + StringChangeEx(FileContents, LF, CRLF, False); + SaveStringToFile(FilePath, FileContents, False); + end; +end; diff --git a/src/libs/3rdparty/botan/src/build-data/makefile.in b/src/libs/3rdparty/botan/src/build-data/makefile.in new file mode 100644 index 0000000000..7cd04360f1 --- /dev/null +++ b/src/libs/3rdparty/botan/src/build-data/makefile.in @@ -0,0 +1,132 @@ +# Paths to relevant programs + +CXX = %{cxx} +LINKER = %{linker} +AR = %{ar_command} +PYTHON_EXE = %{python_exe} + +# Compiler Flags + +ABI_FLAGS = %{cc_sysroot} %{cxx_abi_flags} +LANG_FLAGS = %{cc_lang_flags} +CXXFLAGS = %{cc_compile_flags} +WARN_FLAGS = %{cc_warning_flags} +SO_OBJ_FLAGS = %{shared_flags} +LDFLAGS = %{ldflags} + +EXE_LINK_CMD = %{exe_link_cmd} +POST_LINK_CMD = %{post_link_cmd} + +LIB_LINKS_TO = %{link_to} +EXE_LINKS_TO = %{link_to_botan} $(LIB_LINKS_TO) + +BUILD_FLAGS = $(ABI_FLAGS) $(LANG_FLAGS) $(CXXFLAGS) $(WARN_FLAGS) + +SCRIPTS_DIR = %{scripts_dir} +INSTALLED_LIB_DIR = %{prefix}/%{libdir} + +# The primary target +all: libs cli docs tests + +# Executable targets +CLI = %{cli_exe} +TEST = %{test_exe} +LIBRARIES = %{library_targets} + +cli: $(CLI) +tests: $(TEST) +libs: $(LIBRARIES) +docs: %{doc_stamp_file} + +# Misc targets + +%{if make_supports_phony} +.PHONY = all cli libs tests docs clean distclean install +%{endif} + +%{doc_stamp_file}: %{doc_dir}/manual/*.rst + $(PYTHON_EXE) $(SCRIPTS_DIR)/build_docs.py --build-dir="%{build_dir}" + +clean: + $(PYTHON_EXE) $(SCRIPTS_DIR)/cleanup.py --build-dir="%{build_dir}" + +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} + +# Object Files +LIBOBJS = %{join lib_objs} + +CLIOBJS = %{join cli_objs} + +TESTOBJS = %{join test_objs} + +# Executable targets + +$(CLI): $(LIBRARIES) $(CLIOBJS) + $(EXE_LINK_CMD) $(ABI_FLAGS) $(LDFLAGS) $(CLIOBJS) $(EXE_LINKS_TO) %{output_to_exe}$@ + $(POST_LINK_CMD) + +$(TEST): $(LIBRARIES) $(TESTOBJS) + $(EXE_LINK_CMD) $(ABI_FLAGS) $(LDFLAGS) $(TESTOBJS) $(EXE_LINKS_TO) %{output_to_exe}$@ + $(POST_LINK_CMD) + +%{if build_fuzzers} + +FUZZERS = %{fuzzer_bin} + +fuzzers: libs $(FUZZERS) + +fuzzer_corpus: + git clone --depth=1 https://github.com/randombit/crypto-corpus.git fuzzer_corpus + +fuzzer_corpus_zip: fuzzer_corpus + ./src/scripts/create_corpus_zip.py fuzzer_corpus %{fuzzobj_dir} + +%{endif} + +# Library targets + +%{if build_static_lib} + +%{out_dir}/%{static_lib_name}: $(LIBOBJS) + $(AR) %{ar_options} %{ar_output_to}$@ $(LIBOBJS) + +%{endif} + +%{if build_shared_lib} + +%{out_dir}/%{shared_lib_name}: $(LIBOBJS) + %{lib_link_cmd} $(ABI_FLAGS) $(LDFLAGS) $(LIBOBJS) $(LIB_LINKS_TO) %{output_to_exe}$@ +%{endif} +%{if symlink_shared_lib} + cd %{out_dir} && ln -fs %{shared_lib_name} %{soname_base} + cd %{out_dir} && ln -fs %{shared_lib_name} %{soname_patch} +%{endif} + +# Build Commands + +%{for lib_build_info} +%{obj}: %{src} + $(CXX) $(SO_OBJ_FLAGS) $(BUILD_FLAGS) %{isa_flags} %{include_paths} %{dash_c} %{src} %{dash_o}$@ +%{endfor} + +%{for cli_build_info} +%{obj}: %{src} + $(CXX) $(BUILD_FLAGS) %{isa_flags} %{include_paths} %{dash_c} %{src} %{dash_o}$@ +%{endfor} + +%{for test_build_info} +%{obj}: %{src} + $(CXX) $(BUILD_FLAGS) %{isa_flags} %{include_paths} %{dash_c} %{src} %{dash_o}$@ +%{endfor} + +%{for fuzzer_build_info} +%{obj}: %{src} + $(CXX) $(BUILD_FLAGS) %{isa_flags} %{include_paths} %{dash_c} %{src} %{dash_o}$@ + +%{exe}: %{obj} $(LIBRARIES) + $(EXE_LINK_CMD) $(ABI_FLAGS) %{obj} $(EXE_LINKS_TO) %{fuzzer_lib} %{output_to_exe}$@ +%{endfor} diff --git a/src/libs/3rdparty/botan/src/build-data/oids.txt b/src/libs/3rdparty/botan/src/build-data/oids.txt new file mode 100644 index 0000000000..55acc0e9bd --- /dev/null +++ b/src/libs/3rdparty/botan/src/build-data/oids.txt @@ -0,0 +1,295 @@ +# Regenerate with ./src/scripts/oids.py oids > src/lib/asn1/oid_maps.cpp +# AND ./src/scripts/oids.py dn_ub > src/lib/x509/x509_dn_ub.cpp +# (if you modified something under [dn] +# AND ./src/scripts/oids.py pads > src/lib/pk_pad/padding.cpp +# (if you modified something under [signature] + +# Public key types +[pubkey] +1.2.840.113549.1.1.1 = RSA +2.5.8.1.1 = RSA +1.2.840.10040.4.1 = DSA +1.2.840.10046.2.1 = DH +1.3.6.1.4.1.3029.1.2.1 = ElGamal +1.3.6.1.4.1.25258.1.3 = McEliece +1.3.101.110 = Curve25519 +1.3.6.1.4.1.25258.1.5 = XMSS +1.3.101.112 = Ed25519 + +# X9.62 ecPublicKey, valid for ECDSA and ECDH (RFC 3279 sec 2.3.5) +1.2.840.10045.2.1 = ECDSA +1.3.132.1.12 = ECDH + +1.2.156.10197.1.301.1 = SM2_Sig +1.2.156.10197.1.301.2 = SM2_Kex +1.2.156.10197.1.301.3 = SM2_Enc + +# ecgPublicKey (see https://www.teletrust.de/projekte/oid/) +1.3.36.3.3.2.5.2.1 = ECGDSA + +# EC-KCDSA mechanism (Elliptic Curve KCDSA) +1.0.14888.3.0.5 = ECKCDSA + +1.2.643.2.2.19 = GOST-34.10 + +# OpenPGP (RFC4880bis) +1.3.6.1.4.1.11591.15.1 = OpenPGP.Ed25519 +1.3.6.1.4.1.3029.1.5.1 = OpenPGP.Curve25519 + +[cipher] +# 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 +2.16.840.1.101.3.4.1.42 = AES-256/CBC +1.2.410.200004.1.4 = SEED/CBC +1.2.156.10197.1.104.2 = SM4/CBC + +1.2.840.113549.1.9.16.3.18 = ChaCha20Poly1305 + +2.16.840.1.101.3.4.1.6 = AES-128/GCM +2.16.840.1.101.3.4.1.26 = AES-192/GCM +2.16.840.1.101.3.4.1.46 = AES-256/GCM + +2.16.840.1.101.3.4.1.7 = AES-128/CCM +2.16.840.1.101.3.4.1.27 = AES-192/CCM +2.16.840.1.101.3.4.1.47 = AES-256/CCM + +1.2.392.200011.61.1.1.1.2 = Camellia-128/CBC +1.2.392.200011.61.1.1.1.3 = Camellia-192/CBC +1.2.392.200011.61.1.1.1.4 = Camellia-256/CBC + +0.3.4401.5.3.1.9.6 = Camellia-128/GCM +0.3.4401.5.3.1.9.26 = Camellia-192/GCM +0.3.4401.5.3.1.9.46 = Camellia-256/GCM + +1.2.156.10197.1.104.8 = SM4/GCM + +1.3.6.1.4.1.25258.3.1 = Serpent/CBC +1.3.6.1.4.1.25258.3.2 = Threefish-512/CBC +1.3.6.1.4.1.25258.3.3 = Twofish/CBC + +1.3.6.1.4.1.25258.3.101 = Serpent/GCM +1.3.6.1.4.1.25258.3.102 = Twofish/GCM + +1.3.6.1.4.1.25258.3.2.1 = AES-128/OCB +1.3.6.1.4.1.25258.3.2.2 = AES-192/OCB +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 + +[hash] +# Hash functions +1.2.840.113549.2.5 = MD5 +1.3.6.1.4.1.11591.12.2 = Tiger(24,3) + +1.2.156.10197.1.401 = SM3 + +1.3.14.3.2.26 = SHA-160 + +1.3.36.3.2.1 = RIPEMD-160 + +# From NIST: +2.16.840.1.101.3.4.2.1 = SHA-256 +2.16.840.1.101.3.4.2.2 = SHA-384 +2.16.840.1.101.3.4.2.3 = SHA-512 +2.16.840.1.101.3.4.2.4 = SHA-224 +2.16.840.1.101.3.4.2.6 = SHA-512-256 +2.16.840.1.101.3.4.2.7 = SHA-3(224) +2.16.840.1.101.3.4.2.8 = SHA-3(256) +2.16.840.1.101.3.4.2.9 = SHA-3(384) +2.16.840.1.101.3.4.2.10 = SHA-3(512) +2.16.840.1.101.3.4.2.11 = SHAKE-128 +2.16.840.1.101.3.4.2.12 = SHAKE-256 + +1.2.643.7.1.1.2.2 = Streebog-256 +1.2.643.7.1.1.2.3 = Streebog-512 + +[mac] +# MACs +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.2.10 = HMAC(SHA-384) +1.2.840.113549.2.11 = HMAC(SHA-512) + +[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 +2.16.840.1.101.3.4.1.45 = KeyWrap.AES-256 + +[compression] +1.2.840.113549.1.9.16.3.8 = Compression.Zlib + +# Signature algos +[signature] +1.2.840.113549.1.1.4 = RSA/EMSA3(MD5) +1.2.840.113549.1.1.5 = RSA/EMSA3(SHA-160) +1.2.840.113549.1.1.8 = MGF1 +1.2.840.113549.1.1.10 = RSA/EMSA4 +1.2.840.113549.1.1.11 = RSA/EMSA3(SHA-256) +1.2.840.113549.1.1.12 = RSA/EMSA3(SHA-384) +1.2.840.113549.1.1.13 = RSA/EMSA3(SHA-512) +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.504 = RSA/EMSA3(SM3) + +1.2.840.10040.4.3 = DSA/EMSA1(SHA-160) + +2.16.840.1.101.3.4.3.1 = DSA/EMSA1(SHA-224) +2.16.840.1.101.3.4.3.2 = DSA/EMSA1(SHA-256) +2.16.840.1.101.3.4.3.3 = DSA/EMSA1(SHA-384) +2.16.840.1.101.3.4.3.4 = DSA/EMSA1(SHA-512) +2.16.840.1.101.3.4.3.5 = DSA/EMSA1(SHA-3(224)) +2.16.840.1.101.3.4.3.6 = DSA/EMSA1(SHA-3(256)) +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.101.3.4.3.10 = ECDSA/EMSA1(SHA-3(256)) +2.16.840.1.101.3.4.3.11 = ECDSA/EMSA1(SHA-3(384)) +2.16.840.1.101.3.4.3.12 = ECDSA/EMSA1(SHA-3(512)) + +2.16.840.1.101.3.4.3.13 = RSA/EMSA3(SHA-3(224)) +2.16.840.1.101.3.4.3.14 = RSA/EMSA3(SHA-3(256)) +2.16.840.1.101.3.4.3.15 = RSA/EMSA3(SHA-3(384)) +2.16.840.1.101.3.4.3.16 = RSA/EMSA3(SHA-3(512)) + +1.2.840.10045.4.1 = ECDSA/EMSA1(SHA-160) +1.2.840.10045.4.3.1 = ECDSA/EMSA1(SHA-224) +1.2.840.10045.4.3.2 = ECDSA/EMSA1(SHA-256) +1.2.840.10045.4.3.3 = ECDSA/EMSA1(SHA-384) +1.2.840.10045.4.3.4 = ECDSA/EMSA1(SHA-512) + +1.3.36.3.3.2.5.4.1 = ECGDSA/EMSA1(RIPEMD-160) +1.3.36.3.3.2.5.4.2 = ECGDSA/EMSA1(SHA-160) +1.3.36.3.3.2.5.4.3 = ECGDSA/EMSA1(SHA-224) +1.3.36.3.3.2.5.4.4 = ECGDSA/EMSA1(SHA-256) +1.3.36.3.3.2.5.4.5 = ECGDSA/EMSA1(SHA-384) +1.3.36.3.3.2.5.4.6 = ECGDSA/EMSA1(SHA-512) + +1.2.410.200004.1.100.4.3 = ECKCDSA/EMSA1(SHA-1) +1.2.410.200004.1.100.4.4 = ECKCDSA/EMSA1(SHA-224) +1.2.410.200004.1.100.4.5 = ECKCDSA/EMSA1(SHA-256) + +1.2.643.2.2.3 = GOST-34.10/EMSA1(GOST-R-34.11-94) + +1.3.6.1.4.1.25258.1.6.1 = GOST-34.10/EMSA1(SHA-256) + +# Encryption algos +[encryption] +1.2.840.113549.1.1.7 = RSA/OAEP + +# DN with upper bounds from RFC 5280, Appendix A +[dn] +2.5.4.3 = X520.CommonName = 64 +2.5.4.4 = X520.Surname = 40 +2.5.4.5 = X520.SerialNumber = 64 +2.5.4.6 = X520.Country = 3 +2.5.4.7 = X520.Locality = 128 +2.5.4.8 = X520.State = 128 +2.5.4.10 = X520.Organization = 64 +2.5.4.11 = X520.OrganizationalUnit = 64 +2.5.4.12 = X520.Title = 64 +# the following three types are naming attributes of type "X520name" and inherit its bound +2.5.4.42 = X520.GivenName = 32768 +2.5.4.43 = X520.Initials = 32768 +2.5.4.44 = X520.GenerationalQualifier = 32768 +2.5.4.46 = X520.DNQualifier = 64 +2.5.4.65 = X520.Pseudonym = 128 + +[pbe] +1.2.840.113549.1.5.12 = PKCS5.PBKDF2 +1.2.840.113549.1.5.13 = PBE-PKCS5v20 + +1.3.6.1.4.1.11591.4.11 = Scrypt + +[pkcs9] +1.2.840.113549.1.9.1 = PKCS9.EmailAddress +1.2.840.113549.1.9.2 = PKCS9.UnstructuredName +1.2.840.113549.1.9.3 = PKCS9.ContentType +1.2.840.113549.1.9.4 = PKCS9.MessageDigest +1.2.840.113549.1.9.7 = PKCS9.ChallengePassword +1.2.840.113549.1.9.14 = PKCS9.ExtensionRequest + +[pkix] +2.5.29.14 = X509v3.SubjectKeyIdentifier +2.5.29.15 = X509v3.KeyUsage +2.5.29.17 = X509v3.SubjectAlternativeName +2.5.29.18 = X509v3.IssuerAlternativeName +2.5.29.19 = X509v3.BasicConstraints +2.5.29.20 = X509v3.CRLNumber +2.5.29.21 = X509v3.ReasonCode +2.5.29.23 = X509v3.HoldInstructionCode +2.5.29.24 = X509v3.InvalidityDate +2.5.29.28 = X509v3.CRLIssuingDistributionPoint +2.5.29.30 = X509v3.NameConstraints +2.5.29.31 = X509v3.CRLDistributionPoints +2.5.29.32 = X509v3.CertificatePolicies +2.5.29.35 = X509v3.AuthorityKeyIdentifier +2.5.29.36 = X509v3.PolicyConstraints +2.5.29.37 = X509v3.ExtendedKeyUsage +1.3.6.1.5.5.7.1.1 = PKIX.AuthorityInformationAccess + +2.5.29.32.0 = X509v3.AnyPolicy + +1.3.6.1.5.5.7.3.1 = PKIX.ServerAuth +1.3.6.1.5.5.7.3.2 = PKIX.ClientAuth +1.3.6.1.5.5.7.3.3 = PKIX.CodeSigning +1.3.6.1.5.5.7.3.4 = PKIX.EmailProtection +1.3.6.1.5.5.7.3.5 = PKIX.IPsecEndSystem +1.3.6.1.5.5.7.3.6 = PKIX.IPsecTunnel +1.3.6.1.5.5.7.3.7 = PKIX.IPsecUser +1.3.6.1.5.5.7.3.8 = PKIX.TimeStamping +1.3.6.1.5.5.7.3.9 = PKIX.OCSPSigning + +1.3.6.1.5.5.7.8.5 = PKIX.XMPPAddr + +1.3.6.1.5.5.7.48.1 = PKIX.OCSP +1.3.6.1.5.5.7.48.1.1 = PKIX.OCSP.BasicResponse +1.3.6.1.5.5.7.48.2 = PKIX.CertificateAuthorityIssuers + +1.3.6.1.4.1.311.20.2.2 = Microsoft SmartcardLogon + +# ECC param sets +[ecc_param] +1.3.132.0.8 = secp160r1 +1.3.132.0.9 = secp160k1 +1.3.132.0.10 = secp256k1 +1.3.132.0.30 = secp160r2 +1.3.132.0.31 = secp192k1 +1.3.132.0.32 = secp224k1 +1.3.132.0.33 = secp224r1 +1.3.132.0.34 = secp384r1 +1.3.132.0.35 = secp521r1 +1.3.6.1.4.1.8301.3.1.2.9.0.38 = secp521r1 + +1.2.840.10045.3.1.1 = secp192r1 +1.2.840.10045.3.1.2 = x962_p192v2 +1.2.840.10045.3.1.3 = x962_p192v3 +1.2.840.10045.3.1.4 = x962_p239v1 +1.2.840.10045.3.1.5 = x962_p239v2 +1.2.840.10045.3.1.6 = x962_p239v3 +1.2.840.10045.3.1.7 = secp256r1 + +1.2.156.10197.1.301 = sm2p256v1 + +1.3.36.3.3.2.8.1.1.1 = brainpool160r1 +1.3.36.3.3.2.8.1.1.3 = brainpool192r1 +1.3.36.3.3.2.8.1.1.5 = brainpool224r1 +1.3.36.3.3.2.8.1.1.7 = brainpool256r1 +1.3.36.3.3.2.8.1.1.9 = brainpool320r1 +1.3.36.3.3.2.8.1.1.11 = brainpool384r1 +1.3.36.3.3.2.8.1.1.13 = brainpool512r1 + +1.2.643.2.2.35.1 = gost_256A +1.2.643.2.2.36.0 = gost_256A +1.2.250.1.223.101.256.1 = frp256v1 diff --git a/src/libs/3rdparty/botan/src/build-data/os/aix.txt b/src/libs/3rdparty/botan/src/build-data/os/aix.txt new file mode 100644 index 0000000000..be5a8717e5 --- /dev/null +++ b/src/libs/3rdparty/botan/src/build-data/os/aix.txt @@ -0,0 +1,16 @@ + +soname_suffix "so" + +use_stack_protector no + + +posix1 +posix_mlock +clock_gettime +dev_random +proc_fs + +sockets +threads +filesystem + diff --git a/src/libs/3rdparty/botan/src/build-data/os/android.txt b/src/libs/3rdparty/botan/src/build-data/os/android.txt new file mode 100644 index 0000000000..3b0b0c09a6 --- /dev/null +++ b/src/libs/3rdparty/botan/src/build-data/os/android.txt @@ -0,0 +1,18 @@ + +soname_suffix "so" + + +posix1 +posix_mlock +clock_gettime + +dev_random + +# getauxval is available in Android NDK for min API 18 and in Crystax NDK +# for all min API levels. Use --without-os-feature=getauxval to disable +getauxval + +sockets +threads +filesystem + diff --git a/src/libs/3rdparty/botan/src/build-data/os/cygwin.txt b/src/libs/3rdparty/botan/src/build-data/os/cygwin.txt new file mode 100644 index 0000000000..1d106b06c1 --- /dev/null +++ b/src/libs/3rdparty/botan/src/build-data/os/cygwin.txt @@ -0,0 +1,18 @@ + +program_suffix .exe + +# Cygwin supports shared libs fine, but there are problems with making a Botan +# shared library when libraries it depends on are static-only (such as libz). +# So until I can figure out a work-around, it's disabled. + +install_root c:\Botan +doc_dir docs + + +posix1 +dev_random + +sockets +threads +filesystem + diff --git a/src/libs/3rdparty/botan/src/build-data/os/darwin.txt b/src/libs/3rdparty/botan/src/build-data/os/darwin.txt new file mode 100644 index 0000000000..056d535e7c --- /dev/null +++ b/src/libs/3rdparty/botan/src/build-data/os/darwin.txt @@ -0,0 +1,28 @@ + +soname_pattern_base "lib{libname}.dylib" +soname_pattern_abi "lib{libname}.{abi_rev}.dylib" +soname_pattern_patch "lib{libname}.{abi_rev}.{version_minor}.{version_patch}.dylib" + +# In order that these executables work from the build directory, +# we need to change the install names +so_post_link_command "install_name_tool -change '$(INSTALLED_LIB_DIR)/{soname_abi}' '@executable_path/{soname_abi}' $@" + +doc_dir doc + + +posix1 +posix_mlock +arc4random +dev_random +security_framework + +sockets +threads +filesystem + + + +macos +macosx +osx + diff --git a/src/libs/3rdparty/botan/src/build-data/os/dragonfly.txt b/src/libs/3rdparty/botan/src/build-data/os/dragonfly.txt new file mode 100644 index 0000000000..6cf7949488 --- /dev/null +++ b/src/libs/3rdparty/botan/src/build-data/os/dragonfly.txt @@ -0,0 +1,15 @@ + +soname_suffix "so" + + +posix1 +posix_mlock +clock_gettime +proc_fs +dev_random +arc4random + +sockets +threads +filesystem + diff --git a/src/libs/3rdparty/botan/src/build-data/os/freebsd.txt b/src/libs/3rdparty/botan/src/build-data/os/freebsd.txt new file mode 100644 index 0000000000..2ff60844a7 --- /dev/null +++ b/src/libs/3rdparty/botan/src/build-data/os/freebsd.txt @@ -0,0 +1,14 @@ + +soname_suffix "so" + + +posix1 +posix_mlock +clock_gettime +dev_random +arc4random + +sockets +threads +filesystem + diff --git a/src/libs/3rdparty/botan/src/build-data/os/haiku.txt b/src/libs/3rdparty/botan/src/build-data/os/haiku.txt new file mode 100644 index 0000000000..e203a0d268 --- /dev/null +++ b/src/libs/3rdparty/botan/src/build-data/os/haiku.txt @@ -0,0 +1,23 @@ + +soname_suffix "so" + +install_root /boot +header_dir develop/headers +lib_dir system/lib +doc_dir system/documentation + +use_stack_protector no + + +posix1 +clock_gettime +dev_random + +sockets +threads +filesystem + + + +beos + diff --git a/src/libs/3rdparty/botan/src/build-data/os/hpux.txt b/src/libs/3rdparty/botan/src/build-data/os/hpux.txt new file mode 100644 index 0000000000..f9a74f639c --- /dev/null +++ b/src/libs/3rdparty/botan/src/build-data/os/hpux.txt @@ -0,0 +1,18 @@ + +# It is "sl" on HP-PA, but HP-UX on PA is EOL +soname_suffix "so" + + +posix1 +posix_mlock +clock_gettime +dev_random + +sockets +threads +filesystem + + + +hp-ux + diff --git a/src/libs/3rdparty/botan/src/build-data/os/hurd.txt b/src/libs/3rdparty/botan/src/build-data/os/hurd.txt new file mode 100644 index 0000000000..6d12c9a489 --- /dev/null +++ b/src/libs/3rdparty/botan/src/build-data/os/hurd.txt @@ -0,0 +1,17 @@ + +soname_suffix "so" + + +posix1 +posix_mlock +dev_random +clock_gettime + +sockets +threads +filesystem + + + +gnu + diff --git a/src/libs/3rdparty/botan/src/build-data/os/includeos.txt b/src/libs/3rdparty/botan/src/build-data/os/includeos.txt new file mode 100644 index 0000000000..7d2ebfdc95 --- /dev/null +++ b/src/libs/3rdparty/botan/src/build-data/os/includeos.txt @@ -0,0 +1,4 @@ + +posix1 +dev_random + diff --git a/src/libs/3rdparty/botan/src/build-data/os/ios.txt b/src/libs/3rdparty/botan/src/build-data/os/ios.txt new file mode 100644 index 0000000000..0e3eb7c4b0 --- /dev/null +++ b/src/libs/3rdparty/botan/src/build-data/os/ios.txt @@ -0,0 +1,19 @@ + +soname_pattern_base "lib{libname}.{version_minor}.dylib" +soname_pattern_abi "lib{libname}.{version_minor}.{abi_rev}.dylib" +soname_pattern_patch "lib{libname}.{version_minor}.{abi_rev}.{version_patch}.dylib" + +doc_dir doc + + +posix1 +posix_mlock +arc4random + +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 new file mode 100644 index 0000000000..6f4f3d6443 --- /dev/null +++ b/src/libs/3rdparty/botan/src/build-data/os/linux.txt @@ -0,0 +1,20 @@ + +soname_suffix "so" + + +posix1 +posix_mlock + +dev_random +proc_fs +clock_gettime +getauxval + +sockets +threads +filesystem + + + +linux-gnu + diff --git a/src/libs/3rdparty/botan/src/build-data/os/llvm.txt b/src/libs/3rdparty/botan/src/build-data/os/llvm.txt new file mode 100644 index 0000000000..132d7749f1 --- /dev/null +++ b/src/libs/3rdparty/botan/src/build-data/os/llvm.txt @@ -0,0 +1,9 @@ + +obj_suffix bc + +ar_command llvm-link +ar_options -o + + +filesystem + diff --git a/src/libs/3rdparty/botan/src/build-data/os/mingw.txt b/src/libs/3rdparty/botan/src/build-data/os/mingw.txt new file mode 100644 index 0000000000..bbe17e0840 --- /dev/null +++ b/src/libs/3rdparty/botan/src/build-data/os/mingw.txt @@ -0,0 +1,24 @@ + +program_suffix .exe +obj_suffix o +static_suffix a + + +install_root /mingw +header_dir include +lib_dir lib +doc_dir share/doc + + +msys +mingw32.* + + + +win32 +rtlgenrandom +virtual_lock + +threads +filesystem + diff --git a/src/libs/3rdparty/botan/src/build-data/os/nacl.txt b/src/libs/3rdparty/botan/src/build-data/os/nacl.txt new file mode 100644 index 0000000000..55156e4013 --- /dev/null +++ b/src/libs/3rdparty/botan/src/build-data/os/nacl.txt @@ -0,0 +1,5 @@ + + + +threads + diff --git a/src/libs/3rdparty/botan/src/build-data/os/netbsd.txt b/src/libs/3rdparty/botan/src/build-data/os/netbsd.txt new file mode 100644 index 0000000000..2ff60844a7 --- /dev/null +++ b/src/libs/3rdparty/botan/src/build-data/os/netbsd.txt @@ -0,0 +1,14 @@ + +soname_suffix "so" + + +posix1 +posix_mlock +clock_gettime +dev_random +arc4random + +sockets +threads +filesystem + diff --git a/src/libs/3rdparty/botan/src/build-data/os/openbsd.txt b/src/libs/3rdparty/botan/src/build-data/os/openbsd.txt new file mode 100644 index 0000000000..ad35da15b9 --- /dev/null +++ b/src/libs/3rdparty/botan/src/build-data/os/openbsd.txt @@ -0,0 +1,18 @@ + +soname_pattern_base "lib{libname}.so" +soname_pattern_abi "lib{libname}.so.{abi_rev}.{version_minor}" +soname_pattern_patch "lib{libname}.so.{abi_rev}.{version_minor}" + + +posix1 +posix_mlock +clock_gettime +dev_random +arc4random +getentropy +explicit_bzero + +sockets +threads +filesystem + diff --git a/src/libs/3rdparty/botan/src/build-data/os/qnx.txt b/src/libs/3rdparty/botan/src/build-data/os/qnx.txt new file mode 100644 index 0000000000..1cf671ce7d --- /dev/null +++ b/src/libs/3rdparty/botan/src/build-data/os/qnx.txt @@ -0,0 +1,12 @@ +soname_suffix "so" + + +posix1 +posix_mlock +clock_gettime +dev_random + +sockets +threads +filesystem + diff --git a/src/libs/3rdparty/botan/src/build-data/os/solaris.txt b/src/libs/3rdparty/botan/src/build-data/os/solaris.txt new file mode 100644 index 0000000000..c729f6aa1e --- /dev/null +++ b/src/libs/3rdparty/botan/src/build-data/os/solaris.txt @@ -0,0 +1,18 @@ + +soname_suffix "so" + + +posix1 +posix_mlock +clock_gettime +dev_random +proc_fs + +threads +sockets +filesystem + + + +sunos + diff --git a/src/libs/3rdparty/botan/src/build-data/os/uwp.txt b/src/libs/3rdparty/botan/src/build-data/os/uwp.txt new file mode 100644 index 0000000000..df156f0a0b --- /dev/null +++ b/src/libs/3rdparty/botan/src/build-data/os/uwp.txt @@ -0,0 +1,23 @@ + +# ? +program_suffix .exe +obj_suffix obj +static_suffix lib + +install_root c:\\Botan +doc_dir docs + + +win32 +winsock2 +crypto_ng + +rtlsecurezeromemory + +threads +filesystem + + + +winphone + diff --git a/src/libs/3rdparty/botan/src/build-data/os/windows.txt b/src/libs/3rdparty/botan/src/build-data/os/windows.txt new file mode 100644 index 0000000000..db6245a83d --- /dev/null +++ b/src/libs/3rdparty/botan/src/build-data/os/windows.txt @@ -0,0 +1,35 @@ + +cli_exe_name botan-cli + +program_suffix .exe +obj_suffix obj +static_suffix lib +lib_prefix '' + +# For historical reasons? the library does not have the major number on Windows +# This should probably be fixed in a future major release. +library_name 'botan{suffix}' + +soname_pattern_base "{libname}.dll" + +install_root c:\\Botan +doc_dir docs + + +win32 +winsock2 + +rtlgenrandom +rtlsecurezeromemory + +virtual_lock +stl_filesystem_msvc + +threads +filesystem + + + +win32 +MSWin32 + diff --git a/src/libs/3rdparty/botan/src/build-data/version.txt b/src/libs/3rdparty/botan/src/build-data/version.txt new file mode 100644 index 0000000000..cc81f66a83 --- /dev/null +++ b/src/libs/3rdparty/botan/src/build-data/version.txt @@ -0,0 +1,10 @@ + +release_major = 2 +release_minor = 7 +release_patch = 0 +release_so_abi_rev = 7 + +# These are set by the distribution script +release_vc_rev = 'git:5874000d42c338ec95a7ff24cdc0c64e70f967b5' +release_datestamp = 20180702 +release_type = 'release' diff --git a/src/libs/3rdparty/botan/src/lib/asn1/alg_id.cpp b/src/libs/3rdparty/botan/src/lib/asn1/alg_id.cpp new file mode 100644 index 0000000000..0637a8f8d1 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/asn1/alg_id.cpp @@ -0,0 +1,117 @@ +/* +* Algorithm Identifier +* (C) 1999-2007 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include + +namespace Botan { + +/* +* Create an AlgorithmIdentifier +*/ +AlgorithmIdentifier::AlgorithmIdentifier(const OID& alg_id, + const std::vector& param) : + oid(alg_id), + parameters(param) + {} + +/* +* Create an AlgorithmIdentifier +*/ +AlgorithmIdentifier::AlgorithmIdentifier(const std::string& alg_id, + const std::vector& param) : + oid(OIDS::lookup(alg_id)), + parameters(param) + {} + +/* +* Create an AlgorithmIdentifier +*/ +AlgorithmIdentifier::AlgorithmIdentifier(const OID& alg_id, + Encoding_Option option) : + oid(alg_id), + parameters() + { + const uint8_t DER_NULL[] = { 0x05, 0x00 }; + + if(option == USE_NULL_PARAM) + parameters.assign(DER_NULL, DER_NULL + 2); + } + +/* +* Create an AlgorithmIdentifier +*/ +AlgorithmIdentifier::AlgorithmIdentifier(const std::string& alg_id, + Encoding_Option option) : + oid(OIDS::lookup(alg_id)), + parameters() + { + const uint8_t DER_NULL[] = { 0x05, 0x00 }; + + if(option == USE_NULL_PARAM) + parameters.assign(DER_NULL, DER_NULL + 2); + } + +/* +* Compare two AlgorithmIdentifiers +*/ +namespace { + +bool param_null_or_empty(const std::vector& p) + { + if(p.size() == 2 && (p[0] == 0x05) && (p[1] == 0x00)) + return true; + return p.empty(); + } + +} + +bool operator==(const AlgorithmIdentifier& a1, const AlgorithmIdentifier& a2) + { + if(a1.get_oid() != a2.get_oid()) + return false; + + if(param_null_or_empty(a1.get_parameters()) && + param_null_or_empty(a2.get_parameters())) + return true; + + return (a1.get_parameters() == a2.get_parameters()); + } + +/* +* Compare two AlgorithmIdentifiers +*/ +bool operator!=(const AlgorithmIdentifier& a1, const AlgorithmIdentifier& a2) + { + return !(a1 == a2); + } + +/* +* DER encode an AlgorithmIdentifier +*/ +void AlgorithmIdentifier::encode_into(DER_Encoder& codec) const + { + codec.start_cons(SEQUENCE) + .encode(get_oid()) + .raw_bytes(get_parameters()) + .end_cons(); + } + +/* +* Decode a BER encoded AlgorithmIdentifier +*/ +void AlgorithmIdentifier::decode_from(BER_Decoder& codec) + { + codec.start_cons(SEQUENCE) + .decode(oid) + .raw_bytes(parameters) + .end_cons(); + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/asn1/alg_id.h b/src/libs/3rdparty/botan/src/lib/asn1/alg_id.h new file mode 100644 index 0000000000..dc9ca23986 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/asn1/alg_id.h @@ -0,0 +1,59 @@ +/* +* Algorithm Identifier +* (C) 1999-2007 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_ALGORITHM_IDENTIFIER_H_ +#define BOTAN_ALGORITHM_IDENTIFIER_H_ + +#include +#include +#include +#include + +namespace Botan { + +/** +* Algorithm Identifier +*/ +class BOTAN_PUBLIC_API(2,0) AlgorithmIdentifier final : public ASN1_Object + { + public: + enum Encoding_Option { USE_NULL_PARAM, USE_EMPTY_PARAM }; + + void encode_into(class DER_Encoder&) const override; + void decode_from(class BER_Decoder&) override; + + AlgorithmIdentifier() = default; + + AlgorithmIdentifier(const OID& oid, Encoding_Option enc); + AlgorithmIdentifier(const std::string& oid_name, Encoding_Option enc); + + AlgorithmIdentifier(const OID& oid, const std::vector& params); + AlgorithmIdentifier(const std::string& oid_name, const std::vector& params); + + const OID& get_oid() const { return oid; } + const std::vector& get_parameters() const { return parameters; } + + BOTAN_DEPRECATED_PUBLIC_MEMBER_VARIABLES: + /* + * These values are public for historical reasons, but in a future release + * they will be made private. Do not access them. + */ + OID oid; + std::vector parameters; + }; + +/* +* Comparison Operations +*/ +bool BOTAN_PUBLIC_API(2,0) operator==(const AlgorithmIdentifier&, + const AlgorithmIdentifier&); +bool BOTAN_PUBLIC_API(2,0) operator!=(const AlgorithmIdentifier&, + const AlgorithmIdentifier&); + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/asn1/asn1_attribute.cpp b/src/libs/3rdparty/botan/src/lib/asn1/asn1_attribute.cpp new file mode 100644 index 0000000000..8ecd8fd5f3 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/asn1/asn1_attribute.cpp @@ -0,0 +1,58 @@ +/* +* Attribute +* (C) 1999-2007 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include + +namespace Botan { + +/* +* Create an Attribute +*/ +Attribute::Attribute(const OID& attr_oid, const std::vector& attr_value) : + oid(attr_oid), + parameters(attr_value) + {} + +/* +* Create an Attribute +*/ +Attribute::Attribute(const std::string& attr_oid, + const std::vector& attr_value) : + oid(OIDS::lookup(attr_oid)), + parameters(attr_value) + {} + +/* +* DER encode a Attribute +*/ +void Attribute::encode_into(DER_Encoder& codec) const + { + codec.start_cons(SEQUENCE) + .encode(oid) + .start_cons(SET) + .raw_bytes(parameters) + .end_cons() + .end_cons(); + } + +/* +* Decode a BER encoded Attribute +*/ +void Attribute::decode_from(BER_Decoder& codec) + { + codec.start_cons(SEQUENCE) + .decode(oid) + .start_cons(SET) + .raw_bytes(parameters) + .end_cons() + .end_cons(); + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/asn1/asn1_attribute.h b/src/libs/3rdparty/botan/src/lib/asn1/asn1_attribute.h new file mode 100644 index 0000000000..c9f69eb772 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/asn1/asn1_attribute.h @@ -0,0 +1,45 @@ +/* +* ASN.1 Attribute +* (C) 1999-2007,2012 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_ASN1_ATTRIBUTE_H_ +#define BOTAN_ASN1_ATTRIBUTE_H_ + +#include +#include +#include + +namespace Botan { + +/** +* Attribute +*/ +class BOTAN_PUBLIC_API(2,0) Attribute final : public ASN1_Object + { + public: + void encode_into(class DER_Encoder& to) const override; + void decode_from(class BER_Decoder& from) override; + + Attribute() = default; + Attribute(const OID&, const std::vector&); + Attribute(const std::string&, const std::vector&); + + const OID& get_oid() const { return oid; } + + const std::vector& get_parameters() const { return parameters; } + + BOTAN_DEPRECATED_PUBLIC_MEMBER_VARIABLES: + /* + * These values are public for historical reasons, but in a future release + * they will be made private. Do not access them. + */ + OID oid; + std::vector parameters; + }; + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/asn1/asn1_obj.cpp b/src/libs/3rdparty/botan/src/lib/asn1/asn1_obj.cpp new file mode 100644 index 0000000000..815bc4ef83 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/asn1/asn1_obj.cpp @@ -0,0 +1,235 @@ +/* +* ASN.1 Internals +* (C) 1999-2007,2018 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include +#include + +namespace Botan { + +std::vector ASN1_Object::BER_encode() const + { + std::vector output; + DER_Encoder der(output); + this->encode_into(der); + return output; + } + +/* +* Check a type invariant on BER data +*/ +void BER_Object::assert_is_a(ASN1_Tag type_tag_, ASN1_Tag class_tag_, + const std::string& descr) const + { + if(this->is_a(type_tag_, class_tag_) == false) + { + std::stringstream msg; + + msg << "Tag mismatch when decoding " << descr << " got "; + + if(class_tag == NO_OBJECT && type_tag == NO_OBJECT) + { + msg << "EOF"; + } + else + { + if(class_tag == UNIVERSAL || class_tag == CONSTRUCTED) + { + msg << asn1_tag_to_string(type_tag); + } + else + { + msg << std::to_string(type_tag); + } + + msg << "/" << asn1_class_to_string(class_tag); + } + + msg << " expected "; + + if(class_tag_ == UNIVERSAL || class_tag_ == CONSTRUCTED) + { + msg << asn1_tag_to_string(type_tag_); + } + else + { + msg << std::to_string(type_tag_); + } + + msg << "/" << asn1_class_to_string(class_tag_); + + throw BER_Decoding_Error(msg.str()); + } + } + +bool BER_Object::is_a(ASN1_Tag type_tag_, ASN1_Tag class_tag_) const + { + return (type_tag == type_tag_ && class_tag == class_tag_); + } + +bool BER_Object::is_a(int type_tag_, ASN1_Tag class_tag_) const + { + return is_a(ASN1_Tag(type_tag_), class_tag_); + } + +void BER_Object::set_tagging(ASN1_Tag t, ASN1_Tag c) + { + type_tag = t; + class_tag = c; + } + +std::string asn1_class_to_string(ASN1_Tag type) + { + switch(type) + { + case UNIVERSAL: + return "UNIVERSAL"; + case CONSTRUCTED: + return "CONSTRUCTED"; + case CONTEXT_SPECIFIC: + return "CONTEXT_SPECIFIC"; + case APPLICATION: + return "APPLICATION"; + case CONSTRUCTED | CONTEXT_SPECIFIC: + return "PRIVATE"; + case Botan::NO_OBJECT: + return "NO_OBJECT"; + default: + return "CLASS(" + std::to_string(static_cast(type)) + ")"; + } + } + +std::string asn1_tag_to_string(ASN1_Tag type) + { + switch(type) + { + case Botan::SEQUENCE: + return "SEQUENCE"; + + case Botan::SET: + return "SET"; + + case Botan::PRINTABLE_STRING: + return "PRINTABLE STRING"; + + case Botan::NUMERIC_STRING: + return "NUMERIC STRING"; + + case Botan::IA5_STRING: + return "IA5 STRING"; + + case Botan::T61_STRING: + return "T61 STRING"; + + case Botan::UTF8_STRING: + return "UTF8 STRING"; + + case Botan::VISIBLE_STRING: + return "VISIBLE STRING"; + + case Botan::BMP_STRING: + return "BMP STRING"; + + case Botan::UTC_TIME: + return "UTC TIME"; + + case Botan::GENERALIZED_TIME: + return "GENERALIZED TIME"; + + case Botan::OCTET_STRING: + return "OCTET STRING"; + + case Botan::BIT_STRING: + return "BIT STRING"; + + case Botan::ENUMERATED: + return "ENUMERATED"; + + case Botan::INTEGER: + return "INTEGER"; + + case Botan::NULL_TAG: + return "NULL"; + + case Botan::OBJECT_ID: + return "OBJECT"; + + case Botan::BOOLEAN: + return "BOOLEAN"; + + case Botan::NO_OBJECT: + return "NO_OBJECT"; + + default: + return "TAG(" + std::to_string(static_cast(type)) + ")"; + } + } + +/* +* BER Decoding Exceptions +*/ +BER_Decoding_Error::BER_Decoding_Error(const std::string& str) : + Decoding_Error("BER: " + str) {} + +BER_Bad_Tag::BER_Bad_Tag(const std::string& str, ASN1_Tag tag) : + BER_Decoding_Error(str + ": " + std::to_string(tag)) {} + +BER_Bad_Tag::BER_Bad_Tag(const std::string& str, + ASN1_Tag tag1, ASN1_Tag tag2) : + BER_Decoding_Error(str + ": " + std::to_string(tag1) + "/" + std::to_string(tag2)) {} + +namespace ASN1 { + +/* +* Put some arbitrary bytes into a SEQUENCE +*/ +std::vector put_in_sequence(const std::vector& contents) + { + return ASN1::put_in_sequence(contents.data(), contents.size()); + } + +std::vector put_in_sequence(const uint8_t bits[], size_t len) + { + std::vector output; + DER_Encoder(output) + .start_cons(SEQUENCE) + .raw_bytes(bits, len) + .end_cons(); + return output; + } + +/* +* Convert a BER object into a string object +*/ +std::string to_string(const BER_Object& obj) + { + return std::string(cast_uint8_ptr_to_char(obj.bits()), + obj.length()); + } + +/* +* Do heuristic tests for BER data +*/ +bool maybe_BER(DataSource& source) + { + uint8_t first_u8; + if(!source.peek_byte(first_u8)) + { + BOTAN_ASSERT_EQUAL(source.read_byte(first_u8), 0, "Expected EOF"); + throw Stream_IO_Error("ASN1::maybe_BER: Source was empty"); + } + + if(first_u8 == (SEQUENCE | CONSTRUCTED)) + return true; + return false; + } + +} + +} diff --git a/src/libs/3rdparty/botan/src/lib/asn1/asn1_obj.h b/src/libs/3rdparty/botan/src/lib/asn1/asn1_obj.h new file mode 100644 index 0000000000..572453b21a --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/asn1/asn1_obj.h @@ -0,0 +1,191 @@ +/* +* ASN.1 Internals +* (C) 1999-2007,2018 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_ASN1_H_ +#define BOTAN_ASN1_H_ + +#include +#include + +namespace Botan { + +class BER_Decoder; +class DER_Encoder; + +/** +* ASN.1 Type and Class Tags +*/ +enum ASN1_Tag : uint32_t { + UNIVERSAL = 0x00, + APPLICATION = 0x40, + CONTEXT_SPECIFIC = 0x80, + + CONSTRUCTED = 0x20, + + PRIVATE = CONSTRUCTED | CONTEXT_SPECIFIC, + + EOC = 0x00, + BOOLEAN = 0x01, + INTEGER = 0x02, + BIT_STRING = 0x03, + OCTET_STRING = 0x04, + NULL_TAG = 0x05, + OBJECT_ID = 0x06, + ENUMERATED = 0x0A, + SEQUENCE = 0x10, + SET = 0x11, + + UTF8_STRING = 0x0C, + NUMERIC_STRING = 0x12, + PRINTABLE_STRING = 0x13, + T61_STRING = 0x14, + IA5_STRING = 0x16, + VISIBLE_STRING = 0x1A, + UNIVERSAL_STRING = 0x1C, + BMP_STRING = 0x1E, + + UTC_TIME = 0x17, + GENERALIZED_TIME = 0x18, + UTC_OR_GENERALIZED_TIME = 0x19, + + NO_OBJECT = 0xFF00, + DIRECTORY_STRING = 0xFF01 +}; + +std::string BOTAN_UNSTABLE_API asn1_tag_to_string(ASN1_Tag type); +std::string BOTAN_UNSTABLE_API asn1_class_to_string(ASN1_Tag type); + +/** +* Basic ASN.1 Object Interface +*/ +class BOTAN_PUBLIC_API(2,0) ASN1_Object + { + public: + /** + * Encode whatever this object is into to + * @param to the DER_Encoder that will be written to + */ + virtual void encode_into(DER_Encoder& to) const = 0; + + /** + * Decode whatever this object is from from + * @param from the BER_Decoder that will be read from + */ + virtual void decode_from(BER_Decoder& from) = 0; + + /** + * Return the encoding of this object. This is a convenience + * method when just one object needs to be serialized. Use + * DER_Encoder for complicated encodings. + */ + std::vector BER_encode() const; + + ASN1_Object() = default; + ASN1_Object(const ASN1_Object&) = default; + ASN1_Object & operator=(const ASN1_Object&) = default; + virtual ~ASN1_Object() = default; + }; + +/** +* BER Encoded Object +*/ +class BOTAN_PUBLIC_API(2,0) BER_Object final + { + public: + BER_Object() : type_tag(NO_OBJECT), class_tag(UNIVERSAL) {} + + BER_Object(const BER_Object& other) = default; + + BER_Object& operator=(const BER_Object& other) = default; + +#if !defined(BOTAN_BUILD_COMPILER_IS_MSVC_2013) + BER_Object(BER_Object&& other) = default; + + BER_Object& operator=(BER_Object&& other) = default; +#endif + + bool is_set() const { return type_tag != NO_OBJECT; } + + ASN1_Tag tagging() const { return ASN1_Tag(type() | get_class()); } + + ASN1_Tag type() const { return type_tag; } + ASN1_Tag get_class() const { return class_tag; } + + const uint8_t* bits() const { return value.data(); } + + size_t length() const { return value.size(); } + + void assert_is_a(ASN1_Tag type_tag, ASN1_Tag class_tag, + const std::string& descr = "object") const; + + bool is_a(ASN1_Tag type_tag, ASN1_Tag class_tag) const; + + bool is_a(int type_tag, ASN1_Tag class_tag) const; + + BOTAN_DEPRECATED_PUBLIC_MEMBER_VARIABLES: + /* + * The following member variables are public for historical reasons, but + * will be made private in a future major release. Use the accessor + * functions above. + */ + ASN1_Tag type_tag, class_tag; + secure_vector value; + + private: + + friend class BER_Decoder; + + void set_tagging(ASN1_Tag type_tag, ASN1_Tag class_tag); + + uint8_t* mutable_bits(size_t length) + { + value.resize(length); + return value.data(); + } + }; + +/* +* ASN.1 Utility Functions +*/ +class DataSource; + +namespace ASN1 { + +std::vector put_in_sequence(const std::vector& val); +std::vector put_in_sequence(const uint8_t bits[], size_t len); +std::string to_string(const BER_Object& obj); + +/** +* Heuristics tests; is this object possibly BER? +* @param src a data source that will be peeked at but not modified +*/ +bool maybe_BER(DataSource& src); + +} + +/** +* General BER Decoding Error Exception +*/ +class BOTAN_PUBLIC_API(2,0) BER_Decoding_Error : public Decoding_Error + { + public: + explicit BER_Decoding_Error(const std::string&); + }; + +/** +* Exception For Incorrect BER Taggings +*/ +class BOTAN_PUBLIC_API(2,0) BER_Bad_Tag final : public BER_Decoding_Error + { + public: + BER_Bad_Tag(const std::string& msg, ASN1_Tag tag); + BER_Bad_Tag(const std::string& msg, ASN1_Tag tag1, ASN1_Tag tag2); + }; + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/asn1/asn1_oid.cpp b/src/libs/3rdparty/botan/src/lib/asn1/asn1_oid.cpp new file mode 100644 index 0000000000..c94f7c8b54 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/asn1/asn1_oid.cpp @@ -0,0 +1,199 @@ +/* +* ASN.1 OID +* (C) 1999-2007 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include +#include + +namespace Botan { + +/* +* ASN.1 OID Constructor +*/ +OID::OID(const std::string& oid_str) + { + if(!oid_str.empty()) + { + try + { + m_id = parse_asn1_oid(oid_str); + } + catch(...) + { + throw Invalid_OID(oid_str); + } + + if(m_id.size() < 2 || m_id[0] > 2) + throw Invalid_OID(oid_str); + if((m_id[0] == 0 || m_id[0] == 1) && m_id[1] > 39) + throw Invalid_OID(oid_str); + } + } + +/* +* Clear the current OID +*/ +void OID::clear() + { + m_id.clear(); + } + +/* +* Return this OID as a string +*/ +std::string OID::to_string() const + { + std::string oid_str; + for(size_t i = 0; i != m_id.size(); ++i) + { + oid_str += std::to_string(m_id[i]); + if(i != m_id.size() - 1) + oid_str += "."; + } + return oid_str; + } + +/* +* OID equality comparison +*/ +bool OID::operator==(const OID& oid) const + { + if(m_id.size() != oid.m_id.size()) + return false; + for(size_t i = 0; i != m_id.size(); ++i) + if(m_id[i] != oid.m_id[i]) + return false; + return true; + } + +/* +* Append another component to the OID +*/ +OID& OID::operator+=(uint32_t component) + { + m_id.push_back(component); + return (*this); + } + +/* +* Append another component to the OID +*/ +OID operator+(const OID& oid, uint32_t component) + { + OID new_oid(oid); + new_oid += component; + return new_oid; + } + +/* +* OID inequality comparison +*/ +bool operator!=(const OID& a, const OID& b) + { + return !(a == b); + } + +/* +* Compare two OIDs +*/ +bool operator<(const OID& a, const OID& b) + { + const std::vector& oid1 = a.get_id(); + const std::vector& oid2 = b.get_id(); + + if(oid1.size() < oid2.size()) + return true; + if(oid1.size() > oid2.size()) + return false; + for(size_t i = 0; i != oid1.size(); ++i) + { + if(oid1[i] < oid2[i]) + return true; + if(oid1[i] > oid2[i]) + return false; + } + return false; + } + +/* +* DER encode an OBJECT IDENTIFIER +*/ +void OID::encode_into(DER_Encoder& der) const + { + if(m_id.size() < 2) + throw Invalid_Argument("OID::encode_into: OID is invalid"); + + std::vector encoding; + + if(m_id[0] > 2 || m_id[1] >= 40) + throw Encoding_Error("Invalid OID prefix, cannot encode"); + + encoding.push_back(static_cast(40 * m_id[0] + m_id[1])); + + for(size_t i = 2; i != m_id.size(); ++i) + { + if(m_id[i] == 0) + encoding.push_back(0); + else + { + size_t blocks = high_bit(m_id[i]) + 6; + blocks = (blocks - (blocks % 7)) / 7; + + BOTAN_ASSERT(blocks > 0, "Math works"); + + for(size_t j = 0; j != blocks - 1; ++j) + encoding.push_back(0x80 | ((m_id[i] >> 7*(blocks-j-1)) & 0x7F)); + encoding.push_back(m_id[i] & 0x7F); + } + } + der.add_object(OBJECT_ID, UNIVERSAL, encoding); + } + +/* +* Decode a BER encoded OBJECT IDENTIFIER +*/ +void OID::decode_from(BER_Decoder& decoder) + { + BER_Object obj = decoder.get_next_object(); + if(obj.tagging() != OBJECT_ID) + throw BER_Bad_Tag("Error decoding OID, unknown tag", obj.tagging()); + + const size_t length = obj.length(); + const uint8_t* bits = obj.bits(); + + if(length < 2 && !(length == 1 && bits[0] == 0)) + { + throw BER_Decoding_Error("OID encoding is too short"); + } + + clear(); + m_id.push_back(bits[0] / 40); + m_id.push_back(bits[0] % 40); + + size_t i = 0; + while(i != length - 1) + { + uint32_t component = 0; + while(i != length - 1) + { + ++i; + + if(component >> (32-7)) + throw Decoding_Error("OID component overflow"); + + component = (component << 7) + (bits[i] & 0x7F); + + if(!(bits[i] & 0x80)) + break; + } + m_id.push_back(component); + } + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/asn1/asn1_oid.h b/src/libs/3rdparty/botan/src/lib/asn1/asn1_oid.h new file mode 100644 index 0000000000..6198819ad9 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/asn1/asn1_oid.h @@ -0,0 +1,110 @@ +/* +* ASN.1 OID +* (C) 1999-2007 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_ASN1_OID_H_ +#define BOTAN_ASN1_OID_H_ + +#include +#include +#include + +namespace Botan { + +/** +* This class represents ASN.1 object identifiers. +*/ +class BOTAN_PUBLIC_API(2,0) OID final : public ASN1_Object + { + public: + void encode_into(class DER_Encoder&) const override; + void decode_from(class BER_Decoder&) override; + + /** + * Find out whether this OID is empty + * @return true is no OID value is set + */ + bool empty() const { return m_id.empty(); } + + /** + * Find out whether this OID has a value + * @return true is this OID has a value + */ + bool has_value() const { return (m_id.empty() == false); } + + /** + * Get this OID as list (vector) of its components. + * @return vector representing this OID + */ + const std::vector& get_id() const { return m_id; } + + /** + * Get this OID as a string + * @return string representing this OID + */ + std::string as_string() const { return this->to_string(); } + + /** + * Get this OID as a string + * @return string representing this OID + */ + std::string to_string() const; + + /** + * Compare two OIDs. + * @return true if they are equal, false otherwise + */ + bool operator==(const OID&) const; + + /** + * Reset this instance to an empty OID. + */ + void clear(); + + /** + * Add a component to this OID. + * @param new_comp the new component to add to the end of this OID + * @return reference to *this + */ + OID& operator+=(uint32_t new_comp); + + /** + * Construct an OID from a string. + * @param str a string in the form "a.b.c" etc., where a,b,c are numbers + */ + OID(const std::string& str = ""); + + explicit OID(std::initializer_list init) : m_id(init) {} + private: + std::vector m_id; + }; + +/** +* Append another component onto the OID. +* @param oid the OID to add the new component to +* @param new_comp the new component to add +*/ +OID BOTAN_PUBLIC_API(2,0) operator+(const OID& oid, uint32_t new_comp); + +/** +* Compare two OIDs. +* @param a the first OID +* @param b the second OID +* @return true if a is not equal to b +*/ +bool BOTAN_PUBLIC_API(2,0) operator!=(const OID& a, const OID& b); + +/** +* Compare two OIDs. +* @param a the first OID +* @param b the second OID +* @return true if a is lexicographically smaller than b +*/ +bool BOTAN_PUBLIC_API(2,0) operator<(const OID& a, const OID& b); + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/asn1/asn1_print.cpp b/src/libs/3rdparty/botan/src/lib/asn1/asn1_print.cpp new file mode 100644 index 0000000000..1f91782665 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/asn1/asn1_print.cpp @@ -0,0 +1,329 @@ +/* +* (C) 2014,2015,2017 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Botan { + +namespace { + +bool all_printable_chars(const uint8_t bits[], size_t bits_len) + { + for(size_t i = 0; i != bits_len; ++i) + { + int c = bits[i]; + if(c > 127) + return false; + + if((std::isalnum(c) || c == '.' || c == ':' || c == '/' || c == '-') == false) + return false; + } + return true; + } + +/* +* Special hack to handle GeneralName [2] and [6] (DNS name and URI) +*/ +bool possibly_a_general_name(const uint8_t bits[], size_t bits_len) + { + if(bits_len <= 2) + return false; + + if(bits[0] != 0x82 && bits[0] != 0x86) + return false; + + if(bits[1] != bits_len - 2) + return false; + + if(all_printable_chars(bits + 2, bits_len - 2) == false) + return false; + + return true; + } + +} + +std::string ASN1_Formatter::print(const uint8_t in[], size_t len) const + { + std::ostringstream output; + print_to_stream(output, in, len); + return output.str(); + } + +void ASN1_Formatter::print_to_stream(std::ostream& output, + const uint8_t in[], + size_t len) const + { + BER_Decoder dec(in, len); + decode(output, dec, 0); + } + +void ASN1_Formatter::decode(std::ostream& output, + BER_Decoder& decoder, + size_t level) const + { + BER_Object obj = decoder.get_next_object(); + + const bool recurse_deeper = (m_max_depth == 0 || level < m_max_depth); + + while(obj.is_set()) + { + const ASN1_Tag type_tag = obj.type(); + const ASN1_Tag class_tag = obj.get_class(); + const size_t length = obj.length(); + + /* hack to insert the tag+length back in front of the stuff now + that we've gotten the type info */ + std::vector bits; + DER_Encoder(bits).add_object(type_tag, class_tag, obj.bits(), obj.length()); + + BER_Decoder data(bits); + + if(class_tag & CONSTRUCTED) + { + BER_Decoder cons_info(obj.bits(), obj.length()); + + if(recurse_deeper) + { + output << format(type_tag, class_tag, level, length, ""); + decode(output, cons_info, level + 1); // recurse + } + else + { + output << format(type_tag, class_tag, level, length, + format_bin(type_tag, class_tag, bits)); + } + } + else if((class_tag & APPLICATION) || (class_tag & CONTEXT_SPECIFIC)) + { + bool success_parsing_cs = false; + + if(m_print_context_specific) + { + try + { + if(possibly_a_general_name(bits.data(), bits.size())) + { + output << format(type_tag, class_tag, level, level, + std::string(cast_uint8_ptr_to_char(&bits[2]), bits.size() - 2)); + success_parsing_cs = true; + } + else if(recurse_deeper) + { + std::vector inner_bits; + data.decode(inner_bits, type_tag); + + BER_Decoder inner(inner_bits); + std::ostringstream inner_data; + decode(inner_data, inner, level + 1); // recurse + output << inner_data.str(); + success_parsing_cs = true; + } + } + catch(...) + { + } + } + + if(success_parsing_cs == false) + { + output << format(type_tag, class_tag, level, length, + format_bin(type_tag, class_tag, bits)); + } + } + else if(type_tag == OBJECT_ID) + { + OID oid; + data.decode(oid); + + std::string out = OIDS::lookup(oid); + if(out.empty()) + { + out = oid.as_string(); + } + else + { + out += " [" + oid.as_string() + "]"; + } + + output << format(type_tag, class_tag, level, length, out); + } + else if(type_tag == INTEGER || type_tag == ENUMERATED) + { + BigInt number; + + if(type_tag == INTEGER) + { + data.decode(number); + } + else if(type_tag == ENUMERATED) + { + data.decode(number, ENUMERATED, class_tag); + } + + std::vector rep = BigInt::encode(number, BigInt::Binary); + if(rep.empty()) // if zero + rep.resize(1); + + output << format(type_tag, class_tag, level, length, hex_encode(rep)); + } + else if(type_tag == BOOLEAN) + { + bool boolean; + data.decode(boolean); + output << format(type_tag, class_tag, level, length, (boolean ? "true" : "false")); + } + else if(type_tag == NULL_TAG) + { + output << format(type_tag, class_tag, level, length, ""); + } + else if(type_tag == OCTET_STRING || type_tag == BIT_STRING) + { + std::vector decoded_bits; + data.decode(decoded_bits, type_tag); + bool printing_octet_string_worked = false; + + if(recurse_deeper) + { + try + { + BER_Decoder inner(decoded_bits); + + std::ostringstream inner_data; + decode(inner_data, inner, level + 1); // recurse + + output << format(type_tag, class_tag, level, length, ""); + output << inner_data.str(); + printing_octet_string_worked = true; + } + catch(...) + { + } + } + + if(!printing_octet_string_worked) + { + output << format(type_tag, class_tag, level, length, + format_bin(type_tag, class_tag, decoded_bits)); + } + } + else if(ASN1_String::is_string_type(type_tag)) + { + ASN1_String str; + data.decode(str); + output << format(type_tag, class_tag, level, length, str.value()); + } + else if(type_tag == UTC_TIME || type_tag == GENERALIZED_TIME) + { + X509_Time time; + data.decode(time); + output << format(type_tag, class_tag, level, length, time.readable_string()); + } + else + { + output << "Unknown ASN.1 tag class=" << static_cast(class_tag) + << " type=" << static_cast(type_tag) << "\n"; + } + + obj = decoder.get_next_object(); + } + } + +namespace { + +std::string format_type(ASN1_Tag type_tag, ASN1_Tag class_tag) + { + if(class_tag == UNIVERSAL) + return asn1_tag_to_string(type_tag); + + if(class_tag == CONSTRUCTED && (type_tag == SEQUENCE || type_tag == SET)) + return asn1_tag_to_string(type_tag); + + std::string name; + + if(class_tag & CONSTRUCTED) + name += "cons "; + + name += "[" + std::to_string(type_tag) + "]"; + + if(class_tag & APPLICATION) + { + name += " appl"; + } + if(class_tag & CONTEXT_SPECIFIC) + { + name += " context"; + } + + return name; + } + +} + +std::string ASN1_Pretty_Printer::format(ASN1_Tag type_tag, + ASN1_Tag class_tag, + size_t level, + size_t length, + const std::string& value) const + { + bool should_skip = false; + + if(value.length() > m_print_limit) + { + should_skip = true; + } + + if((type_tag == OCTET_STRING || type_tag == BIT_STRING) && + value.length() > m_print_binary_limit) + { + should_skip = true; + } + + level += m_initial_level; + + std::ostringstream oss; + + oss << " d=" << std::setw(2) << level + << ", l=" << std::setw(4) << length << ":" + << std::string(level + 1, ' ') << format_type(type_tag, class_tag); + + if(value != "" && !should_skip) + { + const size_t current_pos = static_cast(oss.tellp()); + const size_t spaces_to_align = + (current_pos >= m_value_column) ? 1 : (m_value_column - current_pos); + + oss << std::string(spaces_to_align, ' ') << value; + } + + oss << "\n"; + + return oss.str(); + } + +std::string ASN1_Pretty_Printer::format_bin(ASN1_Tag /*type_tag*/, + ASN1_Tag /*class_tag*/, + const std::vector& vec) const + { + if(all_printable_chars(vec.data(), vec.size())) + { + return std::string(cast_uint8_ptr_to_char(vec.data()), vec.size()); + } + else + return hex_encode(vec); + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/asn1/asn1_print.h b/src/libs/3rdparty/botan/src/lib/asn1/asn1_print.h new file mode 100644 index 0000000000..a6bc6b15f2 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/asn1/asn1_print.h @@ -0,0 +1,125 @@ +/* +* (C) 2014,2015,2017 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_ASN1_PRINT_H_ +#define BOTAN_ASN1_PRINT_H_ + +#include +#include +#include +#include + +namespace Botan { + +class BER_Decoder; + +/** +* Format ASN.1 data and call a virtual to format +*/ +class BOTAN_PUBLIC_API(2,4) ASN1_Formatter + { + public: + virtual ~ASN1_Formatter() = default; + + /** + * @param print_context_specific if true, try to parse nested context specific data. + * @param max_depth do not recurse more than this many times. If zero, recursion + * is unbounded. + */ + ASN1_Formatter(bool print_context_specific, size_t max_depth) : + m_print_context_specific(print_context_specific), + m_max_depth(max_depth) + {} + + void print_to_stream(std::ostream& out, + const uint8_t in[], + size_t len) const; + + std::string print(const uint8_t in[], size_t len) const; + + template + std::string print(const std::vector& vec) const + { + return print(vec.data(), vec.size()); + } + + protected: + /** + * This is called for each element + */ + virtual std::string format(ASN1_Tag type_tag, + ASN1_Tag class_tag, + size_t level, + size_t length, + const std::string& value) const = 0; + + /** + * This is called to format binary elements that we don't know how to + * convert to a string The result will be passed as value to format; the + * tags are included as a hint to aid decoding. + */ + virtual std::string format_bin(ASN1_Tag type_tag, + ASN1_Tag class_tag, + const std::vector& vec) const = 0; + + private: + void decode(std::ostream& output, + BER_Decoder& decoder, + size_t level) const; + + const bool m_print_context_specific; + const size_t m_max_depth; + }; + +/** +* Format ASN.1 data into human readable output. The exact form of the output for +* any particular input is not guaranteed and may change from release to release. +*/ +class BOTAN_PUBLIC_API(2,4) ASN1_Pretty_Printer final : public ASN1_Formatter + { + public: + /** + * @param print_limit strings larger than this are not printed + * @param print_binary_limit binary strings larger than this are not printed + * @param print_context_specific if true, try to parse nested context specific data. + * @param initial_level the initial depth (0 or 1 are the only reasonable values) + * @param value_column ASN.1 values are lined up at this column in output + * @param max_depth do not recurse more than this many times. If zero, recursion + * is unbounded. + */ + ASN1_Pretty_Printer(size_t print_limit = 4096, + size_t print_binary_limit = 2048, + bool print_context_specific = true, + size_t initial_level = 0, + size_t value_column = 60, + size_t max_depth = 64) : + ASN1_Formatter(print_context_specific, max_depth), + m_print_limit(print_limit), + m_print_binary_limit(print_binary_limit), + m_initial_level(initial_level), + m_value_column(value_column) + {} + + private: + std::string format(ASN1_Tag type_tag, + ASN1_Tag class_tag, + size_t level, + size_t length, + const std::string& value) const override; + + std::string format_bin(ASN1_Tag type_tag, + ASN1_Tag class_tag, + const std::vector& vec) const override; + + const size_t m_print_limit; + const size_t m_print_binary_limit; + const size_t m_initial_level; + const size_t m_value_column; + }; + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/asn1/asn1_str.cpp b/src/libs/3rdparty/botan/src/lib/asn1/asn1_str.cpp new file mode 100644 index 0000000000..416e4f0ac5 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/asn1/asn1_str.cpp @@ -0,0 +1,153 @@ +/* +* Simple ASN.1 String Types +* (C) 1999-2007 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include + +namespace Botan { + +namespace { + +/* +* Choose an encoding for the string +*/ +ASN1_Tag choose_encoding(const std::string& str) + { + static const uint8_t IS_PRINTABLE[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, + 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 }; + + for(size_t i = 0; i != str.size(); ++i) + { + if(!IS_PRINTABLE[static_cast(str[i])]) + { + return UTF8_STRING; + } + } + return PRINTABLE_STRING; + } + +void assert_is_string_type(ASN1_Tag tag) + { + if(!ASN1_String::is_string_type(tag)) + { + throw Invalid_Argument("ASN1_String: Unknown string type " + + std::to_string(tag)); + } + } + +} + +//static +bool ASN1_String::is_string_type(ASN1_Tag tag) + { + return (tag == NUMERIC_STRING || + tag == PRINTABLE_STRING || + tag == VISIBLE_STRING || + tag == T61_STRING || + tag == IA5_STRING || + tag == UTF8_STRING || + tag == BMP_STRING || + tag == UNIVERSAL_STRING); + } + + +/* +* Create an ASN1_String +*/ +ASN1_String::ASN1_String(const std::string& str, ASN1_Tag t) : m_utf8_str(str), m_tag(t) + { + if(m_tag == DIRECTORY_STRING) + { + m_tag = choose_encoding(m_utf8_str); + } + + assert_is_string_type(m_tag); + } + +/* +* Create an ASN1_String +*/ +ASN1_String::ASN1_String(const std::string& str) : + m_utf8_str(str), + m_tag(choose_encoding(m_utf8_str)) + {} + +/* +* Return this string in ISO 8859-1 encoding +*/ +std::string ASN1_String::iso_8859() const + { + return utf8_to_latin1(m_utf8_str); + } + +/* +* DER encode an ASN1_String +*/ +void ASN1_String::encode_into(DER_Encoder& encoder) const + { + if(m_data.empty()) + { + encoder.add_object(tagging(), UNIVERSAL, m_utf8_str); + } + else + { + // If this string was decoded, reserialize using original encoding + encoder.add_object(tagging(), UNIVERSAL, m_data.data(), m_data.size()); + } + } + +/* +* Decode a BER encoded ASN1_String +*/ +void ASN1_String::decode_from(BER_Decoder& source) + { + BER_Object obj = source.get_next_object(); + + assert_is_string_type(obj.type()); + + m_tag = obj.type(); + m_data.assign(obj.bits(), obj.bits() + obj.length()); + + if(m_tag == BMP_STRING) + { + m_utf8_str = ucs2_to_utf8(m_data.data(), m_data.size()); + } + else if(m_tag == UNIVERSAL_STRING) + { + m_utf8_str = ucs4_to_utf8(m_data.data(), m_data.size()); + } + else + { + // All other supported string types are UTF-8 or some subset thereof + m_utf8_str = ASN1::to_string(obj); + } + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/asn1/asn1_str.h b/src/libs/3rdparty/botan/src/lib/asn1/asn1_str.h new file mode 100644 index 0000000000..41dbd005c5 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/asn1/asn1_str.h @@ -0,0 +1,55 @@ +/* +* ASN.1 string type +* (C) 1999-2010 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_ASN1_STRING_H_ +#define BOTAN_ASN1_STRING_H_ + +#include + +namespace Botan { + +/** +* ASN.1 string type +* This class normalizes all inputs to a UTF-8 std::string +*/ +class BOTAN_PUBLIC_API(2,0) ASN1_String final : public ASN1_Object + { + public: + void encode_into(class DER_Encoder&) const override; + void decode_from(class BER_Decoder&) override; + + ASN1_Tag tagging() const { return m_tag; } + + const std::string& value() const { return m_utf8_str; } + + size_t size() const { return value().size(); } + + bool empty() const { return m_utf8_str.empty(); } + + std::string BOTAN_DEPRECATED("Use value() to get UTF-8 string instead") + iso_8859() const; + + /** + * Return true iff this is a tag for a known string type we can handle. + * This ignores string types that are not supported, eg teletexString + */ + static bool is_string_type(ASN1_Tag tag); + + bool operator==(const ASN1_String& other) const + { return value() == other.value(); } + + explicit ASN1_String(const std::string& utf8 = ""); + ASN1_String(const std::string& utf8, ASN1_Tag tag); + private: + std::vector m_data; + std::string m_utf8_str; + ASN1_Tag m_tag; + }; + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/asn1/asn1_time.cpp b/src/libs/3rdparty/botan/src/lib/asn1/asn1_time.cpp new file mode 100644 index 0000000000..43f94af6aa --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/asn1/asn1_time.cpp @@ -0,0 +1,283 @@ +/* +* X.509 Time Types +* (C) 1999-2007 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Botan { + +X509_Time::X509_Time(const std::chrono::system_clock::time_point& time) + { + calendar_point cal = calendar_value(time); + + m_year = cal.get_year(); + m_month = cal.get_month(); + m_day = cal.get_day(); + m_hour = cal.get_hour(); + m_minute = cal.get_minutes(); + m_second = cal.get_seconds(); + + m_tag = (m_year >= 2050) ? GENERALIZED_TIME : UTC_TIME; + } + +X509_Time::X509_Time(const std::string& t_spec, ASN1_Tag tag) + { + set_to(t_spec, tag); + } + +void X509_Time::encode_into(DER_Encoder& der) const + { + BOTAN_ARG_CHECK(m_tag == UTC_TIME || m_tag == GENERALIZED_TIME, + "X509_Time: Bad encoding tag"); + + der.add_object(m_tag, UNIVERSAL, to_string()); + } + +void X509_Time::decode_from(BER_Decoder& source) + { + BER_Object ber_time = source.get_next_object(); + + set_to(ASN1::to_string(ber_time), ber_time.type()); + } + +std::string X509_Time::to_string() const + { + if(time_is_set() == false) + throw Invalid_State("X509_Time::as_string: No time set"); + + uint32_t full_year = m_year; + + if(m_tag == UTC_TIME) + { + if(m_year < 1950 || m_year >= 2050) + throw Encoding_Error("X509_Time: The time " + readable_string() + + " cannot be encoded as a UTCTime"); + + full_year = (m_year >= 2000) ? (m_year - 2000) : (m_year - 1900); + } + + const uint64_t YEAR_FACTOR = 10000000000ULL; + const uint64_t MON_FACTOR = 100000000; + const uint64_t DAY_FACTOR = 1000000; + const uint64_t HOUR_FACTOR = 10000; + const uint64_t MIN_FACTOR = 100; + + const uint64_t int_repr = + YEAR_FACTOR * full_year + + MON_FACTOR * m_month + + DAY_FACTOR * m_day + + HOUR_FACTOR * m_hour + + MIN_FACTOR * m_minute + + m_second; + + std::string repr = std::to_string(int_repr) + "Z"; + + uint32_t desired_size = (m_tag == UTC_TIME) ? 13 : 15; + + while(repr.size() < desired_size) + repr = "0" + repr; + + return repr; + } + +std::string X509_Time::readable_string() const + { + if(time_is_set() == false) + throw Invalid_State("X509_Time::readable_string: No time set"); + + // desired format: "%04d/%02d/%02d %02d:%02d:%02d UTC" + std::stringstream output; + output << std::setfill('0') + << std::setw(4) << m_year << "/" + << std::setw(2) << m_month << "/" + << std::setw(2) << m_day + << " " + << std::setw(2) << m_hour << ":" + << std::setw(2) << m_minute << ":" + << std::setw(2) << m_second + << " UTC"; + + return output.str(); + } + +bool X509_Time::time_is_set() const + { + return (m_year != 0); + } + +int32_t X509_Time::cmp(const X509_Time& other) const + { + if(time_is_set() == false) + throw Invalid_State("X509_Time::cmp: No time set"); + + const int32_t EARLIER = -1, LATER = 1, SAME_TIME = 0; + + if(m_year < other.m_year) return EARLIER; + if(m_year > other.m_year) return LATER; + if(m_month < other.m_month) return EARLIER; + if(m_month > other.m_month) return LATER; + if(m_day < other.m_day) return EARLIER; + if(m_day > other.m_day) return LATER; + if(m_hour < other.m_hour) return EARLIER; + if(m_hour > other.m_hour) return LATER; + if(m_minute < other.m_minute) return EARLIER; + if(m_minute > other.m_minute) return LATER; + if(m_second < other.m_second) return EARLIER; + if(m_second > other.m_second) return LATER; + + return SAME_TIME; + } + +void X509_Time::set_to(const std::string& t_spec, ASN1_Tag spec_tag) + { + if(spec_tag == UTC_OR_GENERALIZED_TIME) + { + try + { + set_to(t_spec, GENERALIZED_TIME); + return; + } + catch(Invalid_Argument&) {} // Not a generalized time. Continue + + try + { + set_to(t_spec, UTC_TIME); + return; + } + catch(Invalid_Argument&) {} // Not a UTC time. Continue + + throw Invalid_Argument("Time string could not be parsed as GeneralizedTime or UTCTime."); + } + + BOTAN_ASSERT(spec_tag == UTC_TIME || spec_tag == GENERALIZED_TIME, "Invalid tag."); + + BOTAN_ARG_CHECK(t_spec.size() > 0, "Time string must not be empty."); + + BOTAN_ARG_CHECK(t_spec.back() == 'Z', "Botan does not support times with timezones other than Z"); + + if(spec_tag == GENERALIZED_TIME) + { + BOTAN_ARG_CHECK(t_spec.size() == 15, "Invalid GeneralizedTime string"); + } + else if(spec_tag == UTC_TIME) + { + BOTAN_ARG_CHECK(t_spec.size() == 13, "Invalid UTCTime string"); + } + + const size_t YEAR_SIZE = (spec_tag == UTC_TIME) ? 2 : 4; + + std::vector params; + std::string current; + + for(size_t j = 0; j != YEAR_SIZE; ++j) + current += t_spec[j]; + params.push_back(current); + current.clear(); + + for(size_t j = YEAR_SIZE; j != t_spec.size() - 1; ++j) + { + current += t_spec[j]; + if(current.size() == 2) + { + params.push_back(current); + current.clear(); + } + } + + m_year = to_u32bit(params[0]); + m_month = to_u32bit(params[1]); + m_day = to_u32bit(params[2]); + m_hour = to_u32bit(params[3]); + m_minute = to_u32bit(params[4]); + m_second = (params.size() == 6) ? to_u32bit(params[5]) : 0; + m_tag = spec_tag; + + if(spec_tag == UTC_TIME) + { + if(m_year >= 50) m_year += 1900; + else m_year += 2000; + } + + if(!passes_sanity_check()) + throw Invalid_Argument("Time " + t_spec + " does not seem to be valid"); + } + +/* +* Do a general sanity check on the time +*/ +bool X509_Time::passes_sanity_check() const + { + if(m_year < 1950 || m_year > 2200) + return false; + if(m_month == 0 || m_month > 12) + return false; + + const uint32_t days_in_month[12] = { 31, 28+1, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; + + if(m_day == 0 || m_day > days_in_month[m_month-1]) + return false; + + if(m_month == 2 && m_day == 29) + { + if(m_year % 4 != 0) + return false; // not a leap year + + if(m_year % 100 == 0 && m_year % 400 != 0) + return false; + } + + if(m_hour >= 24 || m_minute >= 60 || m_second > 60) + return false; + + if (m_tag == UTC_TIME) + { + /* + UTCTime limits the value of components such that leap seconds + are not covered. See "UNIVERSAL 23" in "Information technology + Abstract Syntax Notation One (ASN.1): Specification of basic notation" + + http://www.itu.int/ITU-T/studygroups/com17/languages/ + */ + if (m_hour > 23 || m_minute > 59 || m_second > 59) + { + return false; + } + } + + return true; + } + +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(); + } + +/* +* Compare two X509_Times for in various ways +*/ +bool operator==(const X509_Time& t1, const X509_Time& t2) + { return (t1.cmp(t2) == 0); } +bool operator!=(const X509_Time& t1, const X509_Time& t2) + { return (t1.cmp(t2) != 0); } + +bool operator<=(const X509_Time& t1, const X509_Time& t2) + { return (t1.cmp(t2) <= 0); } +bool operator>=(const X509_Time& t1, const X509_Time& t2) + { return (t1.cmp(t2) >= 0); } + +bool operator<(const X509_Time& t1, const X509_Time& t2) + { return (t1.cmp(t2) < 0); } +bool operator>(const X509_Time& t1, const X509_Time& t2) + { return (t1.cmp(t2) > 0); } + +} diff --git a/src/libs/3rdparty/botan/src/lib/asn1/asn1_time.h b/src/libs/3rdparty/botan/src/lib/asn1/asn1_time.h new file mode 100644 index 0000000000..717c58a7d9 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/asn1/asn1_time.h @@ -0,0 +1,79 @@ +/* +* ASN.1 Time Representation +* (C) 1999-2007,2012 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_ASN1_TIME_H_ +#define BOTAN_ASN1_TIME_H_ + +#include +#include + +namespace Botan { + +/** +* X.509 Time +*/ +class BOTAN_PUBLIC_API(2,0) X509_Time final : public ASN1_Object + { + public: + /// DER encode a X509_Time + void encode_into(DER_Encoder&) const override; + + // Decode a BER encoded X509_Time + void decode_from(BER_Decoder&) override; + + /// Return an internal string representation of the time + std::string to_string() const; + + /// Returns a human friendly string replesentation of no particular formatting + std::string readable_string() const; + + /// Return if the time has been set somehow + bool time_is_set() const; + + /// Compare this time against another + int32_t cmp(const X509_Time& other) const; + + /// Create an invalid X509_Time + X509_Time() = default; + + /// Create a X509_Time from a time point + explicit X509_Time(const std::chrono::system_clock::time_point& time); + + /// Create an X509_Time from string + X509_Time(const std::string& t_spec, ASN1_Tag tag); + + /// Returns a STL timepoint object + std::chrono::system_clock::time_point to_std_timepoint() const; + + private: + void set_to(const std::string& t_spec, ASN1_Tag); + bool passes_sanity_check() const; + + uint32_t m_year = 0; + uint32_t m_month = 0; + uint32_t m_day = 0; + uint32_t m_hour = 0; + uint32_t m_minute = 0; + uint32_t m_second = 0; + ASN1_Tag m_tag = NO_OBJECT; + }; + +/* +* Comparison Operations +*/ +bool BOTAN_PUBLIC_API(2,0) operator==(const X509_Time&, const X509_Time&); +bool BOTAN_PUBLIC_API(2,0) operator!=(const X509_Time&, const X509_Time&); +bool BOTAN_PUBLIC_API(2,0) operator<=(const X509_Time&, const X509_Time&); +bool BOTAN_PUBLIC_API(2,0) operator>=(const X509_Time&, const X509_Time&); +bool BOTAN_PUBLIC_API(2,0) operator<(const X509_Time&, const X509_Time&); +bool BOTAN_PUBLIC_API(2,0) operator>(const X509_Time&, const X509_Time&); + +typedef X509_Time ASN1_Time; + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/asn1/ber_dec.cpp b/src/libs/3rdparty/botan/src/lib/asn1/ber_dec.cpp new file mode 100644 index 0000000000..c5af2f9338 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/asn1/ber_dec.cpp @@ -0,0 +1,549 @@ +/* +* BER Decoder +* (C) 1999-2008,2015,2017,2018 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include + +namespace Botan { + +namespace { + +/* +* This value is somewhat arbitrary. OpenSSL allows up to 128 nested +* indefinite length sequences. If you increase this, also increase the +* limit in the test in test_asn1.cpp +*/ +const size_t ALLOWED_EOC_NESTINGS = 16; + +/* +* BER decode an ASN.1 type tag +*/ +size_t decode_tag(DataSource* ber, ASN1_Tag& type_tag, ASN1_Tag& class_tag) + { + uint8_t b; + if(!ber->read_byte(b)) + { + class_tag = type_tag = NO_OBJECT; + return 0; + } + + if((b & 0x1F) != 0x1F) + { + type_tag = ASN1_Tag(b & 0x1F); + class_tag = ASN1_Tag(b & 0xE0); + return 1; + } + + size_t tag_bytes = 1; + class_tag = ASN1_Tag(b & 0xE0); + + size_t tag_buf = 0; + while(true) + { + if(!ber->read_byte(b)) + throw BER_Decoding_Error("Long-form tag truncated"); + if(tag_buf & 0xFF000000) + throw BER_Decoding_Error("Long-form tag overflowed 32 bits"); + ++tag_bytes; + tag_buf = (tag_buf << 7) | (b & 0x7F); + if((b & 0x80) == 0) break; + } + type_tag = ASN1_Tag(tag_buf); + return tag_bytes; + } + +/* +* Find the EOC marker +*/ +size_t find_eoc(DataSource* src, size_t allow_indef); + +/* +* BER decode an ASN.1 length field +*/ +size_t decode_length(DataSource* ber, size_t& field_size, size_t allow_indef) + { + uint8_t b; + if(!ber->read_byte(b)) + throw BER_Decoding_Error("Length field not found"); + field_size = 1; + if((b & 0x80) == 0) + return b; + + field_size += (b & 0x7F); + if(field_size > 5) + throw BER_Decoding_Error("Length field is too large"); + + if(field_size == 1) + { + if(allow_indef == 0) + { + throw BER_Decoding_Error("Nested EOC markers too deep, rejecting to avoid stack exhaustion"); + } + else + { + return find_eoc(ber, allow_indef - 1); + } + } + + size_t length = 0; + + for(size_t i = 0; i != field_size - 1; ++i) + { + if(get_byte(0, length) != 0) + throw BER_Decoding_Error("Field length overflow"); + if(!ber->read_byte(b)) + throw BER_Decoding_Error("Corrupted length field"); + length = (length << 8) | b; + } + return length; + } + +/* +* Find the EOC marker +*/ +size_t find_eoc(DataSource* ber, size_t allow_indef) + { + secure_vector buffer(BOTAN_DEFAULT_BUFFER_SIZE), data; + + while(true) + { + const size_t got = ber->peek(buffer.data(), buffer.size(), data.size()); + if(got == 0) + break; + + data += std::make_pair(buffer.data(), got); + } + + DataSource_Memory source(data); + data.clear(); + + size_t length = 0; + while(true) + { + ASN1_Tag type_tag, class_tag; + size_t tag_size = decode_tag(&source, type_tag, class_tag); + if(type_tag == NO_OBJECT) + break; + + size_t length_size = 0; + size_t item_size = decode_length(&source, length_size, allow_indef); + source.discard_next(item_size); + + length = BOTAN_CHECKED_ADD(length, item_size); + length = BOTAN_CHECKED_ADD(length, tag_size); + length = BOTAN_CHECKED_ADD(length, length_size); + + if(type_tag == EOC && class_tag == UNIVERSAL) + break; + } + return length; + } + +class DataSource_BERObject final : public DataSource + { + public: + size_t read(uint8_t out[], size_t length) override + { + BOTAN_ASSERT_NOMSG(m_offset <= m_obj.length()); + const size_t got = std::min(m_obj.length() - m_offset, length); + copy_mem(out, m_obj.bits() + m_offset, got); + m_offset += got; + return got; + } + + size_t peek(uint8_t out[], size_t length, size_t peek_offset) const override + { + BOTAN_ASSERT_NOMSG(m_offset <= m_obj.length()); + const size_t bytes_left = m_obj.length() - m_offset; + + if(peek_offset >= bytes_left) + return 0; + + const size_t got = std::min(bytes_left - peek_offset, length); + copy_mem(out, m_obj.bits() + peek_offset, got); + return got; + } + + bool check_available(size_t n) override + { + BOTAN_ASSERT_NOMSG(m_offset <= m_obj.length()); + return (n <= (m_obj.length() - m_offset)); + } + + bool end_of_data() const override + { + return get_bytes_read() == m_obj.length(); + } + + size_t get_bytes_read() const override { return m_offset; } + + explicit DataSource_BERObject(BER_Object&& obj) : m_obj(std::move(obj)), m_offset(0) {} + + private: + BER_Object m_obj; + size_t m_offset; + }; + +} + +/* +* Check if more objects are there +*/ +bool BER_Decoder::more_items() const + { + if(m_source->end_of_data() && !m_pushed.is_set()) + return false; + return true; + } + +/* +* Verify that no bytes remain in the source +*/ +BER_Decoder& BER_Decoder::verify_end() + { + return verify_end("BER_Decoder::verify_end called, but data remains"); + } + +/* +* Verify that no bytes remain in the source +*/ +BER_Decoder& BER_Decoder::verify_end(const std::string& err) + { + if(!m_source->end_of_data() || m_pushed.is_set()) + throw Decoding_Error(err); + return (*this); + } + +/* +* Discard all the bytes remaining in the source +*/ +BER_Decoder& BER_Decoder::discard_remaining() + { + uint8_t buf; + while(m_source->read_byte(buf)) + {} + return (*this); + } + +/* +* Return the BER encoding of the next object +*/ +BER_Object BER_Decoder::get_next_object() + { + BER_Object next; + + if(m_pushed.is_set()) + { + std::swap(next, m_pushed); + return next; + } + + for(;;) + { + ASN1_Tag type_tag, class_tag; + decode_tag(m_source, type_tag, class_tag); + next.set_tagging(type_tag, class_tag); + if(next.is_set() == false) // no more objects + return next; + + size_t field_size; + const size_t length = decode_length(m_source, field_size, ALLOWED_EOC_NESTINGS); + if(!m_source->check_available(length)) + throw BER_Decoding_Error("Value truncated"); + + uint8_t* out = next.mutable_bits(length); + if(m_source->read(out, length) != length) + throw BER_Decoding_Error("Value truncated"); + + if(next.tagging() == EOC) + continue; + else + break; + } + + return next; + } + +/* +* Push a object back into the stream +*/ +void BER_Decoder::push_back(const BER_Object& obj) + { + if(m_pushed.is_set()) + throw Invalid_State("BER_Decoder: Only one push back is allowed"); + m_pushed = obj; + } + +void BER_Decoder::push_back(BER_Object&& obj) + { + if(m_pushed.is_set()) + throw Invalid_State("BER_Decoder: Only one push back is allowed"); + m_pushed = std::move(obj); + } + +BER_Decoder BER_Decoder::start_cons(ASN1_Tag type_tag, ASN1_Tag class_tag) + { + BER_Object obj = get_next_object(); + obj.assert_is_a(type_tag, ASN1_Tag(class_tag | CONSTRUCTED)); + return BER_Decoder(std::move(obj), this); + } + +/* +* Finish decoding a CONSTRUCTED type +*/ +BER_Decoder& BER_Decoder::end_cons() + { + if(!m_parent) + throw Invalid_State("BER_Decoder::end_cons called with null parent"); + if(!m_source->end_of_data()) + throw Decoding_Error("BER_Decoder::end_cons called with data left"); + return (*m_parent); + } + +BER_Decoder::BER_Decoder(BER_Object&& obj, BER_Decoder* parent) + { + m_data_src.reset(new DataSource_BERObject(std::move(obj))); + m_source = m_data_src.get(); + m_parent = parent; + } + +/* +* BER_Decoder Constructor +*/ +BER_Decoder::BER_Decoder(DataSource& src) + { + m_source = &src; + } + +/* +* BER_Decoder Constructor + */ +BER_Decoder::BER_Decoder(const uint8_t data[], size_t length) + { + m_data_src.reset(new DataSource_Memory(data, length)); + m_source = m_data_src.get(); + } + +/* +* BER_Decoder Constructor +*/ +BER_Decoder::BER_Decoder(const secure_vector& data) + { + m_data_src.reset(new DataSource_Memory(data)); + m_source = m_data_src.get(); + } + +/* +* BER_Decoder Constructor +*/ +BER_Decoder::BER_Decoder(const std::vector& data) + { + m_data_src.reset(new DataSource_Memory(data.data(), data.size())); + m_source = m_data_src.get(); + } + +/* +* BER_Decoder Copy Constructor +*/ +BER_Decoder::BER_Decoder(const BER_Decoder& other) + { + m_source = other.m_source; + + // take ownership + std::swap(m_data_src, other.m_data_src); + m_parent = other.m_parent; + } + +/* +* Request for an object to decode itself +*/ +BER_Decoder& BER_Decoder::decode(ASN1_Object& obj, + ASN1_Tag, ASN1_Tag) + { + obj.decode_from(*this); + return (*this); + } + +/* +* Decode a BER encoded NULL +*/ +BER_Decoder& BER_Decoder::decode_null() + { + BER_Object obj = get_next_object(); + obj.assert_is_a(NULL_TAG, UNIVERSAL); + if(obj.length() > 0) + throw BER_Decoding_Error("NULL object had nonzero size"); + return (*this); + } + +BER_Decoder& BER_Decoder::decode_octet_string_bigint(BigInt& out) + { + secure_vector out_vec; + decode(out_vec, OCTET_STRING); + out = BigInt::decode(out_vec.data(), out_vec.size()); + return (*this); + } + +/* +* Decode a BER encoded BOOLEAN +*/ +BER_Decoder& BER_Decoder::decode(bool& out, + ASN1_Tag type_tag, ASN1_Tag class_tag) + { + BER_Object obj = get_next_object(); + obj.assert_is_a(type_tag, class_tag); + + if(obj.length() != 1) + throw BER_Decoding_Error("BER boolean value had invalid size"); + + out = (obj.bits()[0]) ? true : false; + return (*this); + } + +/* +* Decode a small BER encoded INTEGER +*/ +BER_Decoder& BER_Decoder::decode(size_t& out, + ASN1_Tag type_tag, + ASN1_Tag class_tag) + { + BigInt integer; + decode(integer, type_tag, class_tag); + + if(integer.is_negative()) + throw BER_Decoding_Error("Decoded small integer value was negative"); + + if(integer.bits() > 32) + throw BER_Decoding_Error("Decoded integer value larger than expected"); + + out = 0; + for(size_t i = 0; i != 4; ++i) + out = (out << 8) | integer.byte_at(3-i); + + return (*this); + } + +/* +* Decode a small BER encoded INTEGER +*/ +uint64_t BER_Decoder::decode_constrained_integer(ASN1_Tag type_tag, + ASN1_Tag class_tag, + size_t T_bytes) + { + if(T_bytes > 8) + throw BER_Decoding_Error("Can't decode small integer over 8 bytes"); + + BigInt integer; + decode(integer, type_tag, class_tag); + + if(integer.bits() > 8*T_bytes) + throw BER_Decoding_Error("Decoded integer value larger than expected"); + + uint64_t out = 0; + for(size_t i = 0; i != 8; ++i) + out = (out << 8) | integer.byte_at(7-i); + + return out; + } + +/* +* Decode a BER encoded INTEGER +*/ +BER_Decoder& BER_Decoder::decode(BigInt& out, + ASN1_Tag type_tag, + ASN1_Tag class_tag) + { + BER_Object obj = get_next_object(); + obj.assert_is_a(type_tag, class_tag); + + if(obj.length() == 0) + { + out = 0; + } + else + { + const bool negative = (obj.bits()[0] & 0x80) ? true : false; + + if(negative) + { + secure_vector vec(obj.bits(), obj.bits() + obj.length()); + for(size_t i = obj.length(); i > 0; --i) + if(vec[i-1]--) + break; + for(size_t i = 0; i != obj.length(); ++i) + vec[i] = ~vec[i]; + out = BigInt(vec.data(), vec.size()); + out.flip_sign(); + } + else + { + out = BigInt(obj.bits(), obj.length()); + } + } + + return (*this); + } + +namespace { + +template +void asn1_decode_binary_string(std::vector& buffer, + const BER_Object& obj, + ASN1_Tag real_type, + ASN1_Tag type_tag, + ASN1_Tag class_tag) + { + obj.assert_is_a(type_tag, class_tag); + + if(real_type == OCTET_STRING) + { + buffer.assign(obj.bits(), obj.bits() + obj.length()); + } + else + { + if(obj.length() == 0) + throw BER_Decoding_Error("Invalid BIT STRING"); + if(obj.bits()[0] >= 8) + throw BER_Decoding_Error("Bad number of unused bits in BIT STRING"); + + buffer.resize(obj.length() - 1); + + if(obj.length() > 1) + copy_mem(buffer.data(), obj.bits() + 1, obj.length() - 1); + } + } + +} + +/* +* BER decode a BIT STRING or OCTET STRING +*/ +BER_Decoder& BER_Decoder::decode(secure_vector& buffer, + ASN1_Tag real_type, + ASN1_Tag type_tag, ASN1_Tag class_tag) + { + if(real_type != OCTET_STRING && real_type != BIT_STRING) + throw BER_Bad_Tag("Bad tag for {BIT,OCTET} STRING", real_type); + + asn1_decode_binary_string(buffer, get_next_object(), real_type, type_tag, class_tag); + return (*this); + } + +BER_Decoder& BER_Decoder::decode(std::vector& buffer, + ASN1_Tag real_type, + ASN1_Tag type_tag, ASN1_Tag class_tag) + { + if(real_type != OCTET_STRING && real_type != BIT_STRING) + throw BER_Bad_Tag("Bad tag for {BIT,OCTET} STRING", real_type); + + asn1_decode_binary_string(buffer, get_next_object(), real_type, type_tag, class_tag); + return (*this); + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/asn1/ber_dec.h b/src/libs/3rdparty/botan/src/lib/asn1/ber_dec.h new file mode 100644 index 0000000000..0f2fb46074 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/asn1/ber_dec.h @@ -0,0 +1,418 @@ +/* +* BER Decoder +* (C) 1999-2010,2018 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_BER_DECODER_H_ +#define BOTAN_BER_DECODER_H_ + +#include +#include + +namespace Botan { + +class BigInt; + +/** +* BER Decoding Object +*/ +class BOTAN_PUBLIC_API(2,0) BER_Decoder final + { + public: + /** + * Set up to BER decode the data in buf of length len + */ + BER_Decoder(const uint8_t buf[], size_t len); + + /** + * Set up to BER decode the data in vec + */ + explicit BER_Decoder(const secure_vector& vec); + + /** + * Set up to BER decode the data in vec + */ + explicit BER_Decoder(const std::vector& vec); + + /** + * Set up to BER decode the data in src + */ + explicit BER_Decoder(DataSource& src); + + /** + * Set up to BER decode the data in obj + */ + BER_Decoder(const BER_Object& obj) : + BER_Decoder(obj.bits(), obj.length()) {} + + /** + * Set up to BER decode the data in obj + */ + BER_Decoder(BER_Object&& obj) : + BER_Decoder(std::move(obj), nullptr) {} + + BER_Decoder(const BER_Decoder& other); + + BER_Decoder& operator=(const BER_Decoder&) = delete; + + /** + * Get the next object in the data stream. + * If EOF, returns an object with type NO_OBJECT. + */ + BER_Object get_next_object(); + + BER_Decoder& get_next(BER_Object& ber) + { + ber = get_next_object(); + return (*this); + } + + /** + * Push an object back onto the stream. Throws if another + * object was previously pushed and has not been subsequently + * read out. + */ + void push_back(const BER_Object& obj); + + /** + * Push an object back onto the stream. Throws if another + * object was previously pushed and has not been subsequently + * read out. + */ + void push_back(BER_Object&& obj); + + /** + * Return true if there is at least one more item remaining + */ + bool more_items() const; + + /** + * Verify the stream is concluded, throws otherwise. + * Returns (*this) + */ + BER_Decoder& verify_end(); + + /** + * Verify the stream is concluded, throws otherwise. + * Returns (*this) + */ + BER_Decoder& verify_end(const std::string& err_msg); + + /** + * Discard any data that remains unread + * Returns (*this) + */ + BER_Decoder& discard_remaining(); + + /** + * Start decoding a constructed data (sequence or set) + */ + BER_Decoder start_cons(ASN1_Tag type_tag, ASN1_Tag class_tag = UNIVERSAL); + + /** + * Finish decoding a constructed data, throws if any data remains. + * Returns the parent of *this (ie the object on which start_cons was called). + */ + BER_Decoder& end_cons(); + + /** + * Get next object and copy value to POD type + * Asserts value length is equal to POD type sizeof. + * Asserts Type tag and optional Class tag according to parameters. + * Copy value to POD type (struct, union, C-style array, std::array, etc.). + * @param out POD type reference where to copy object value + * @param type_tag ASN1_Tag enum to assert type on object read + * @param class_tag ASN1_Tag enum to assert class on object read (default: CONTEXT_SPECIFIC) + * @return this reference + */ + template + BER_Decoder& get_next_value(T &out, + ASN1_Tag type_tag, + ASN1_Tag class_tag = CONTEXT_SPECIFIC) + { + static_assert(std::is_pod::value, "Type must be POD"); + + BER_Object obj = get_next_object(); + obj.assert_is_a(type_tag, class_tag); + + if (obj.length() != sizeof(T)) + throw BER_Decoding_Error( + "Size mismatch. Object value size is " + + std::to_string(obj.length()) + + "; Output type size is " + + std::to_string(sizeof(T))); + + copy_mem(reinterpret_cast(&out), obj.bits(), obj.length()); + + return (*this); + } + + /* + * Save all the bytes remaining in the source + */ + template + BER_Decoder& raw_bytes(std::vector& out) + { + out.clear(); + uint8_t buf; + while(m_source->read_byte(buf)) + out.push_back(buf); + return (*this); + } + + BER_Decoder& decode_null(); + + /** + * Decode a BER encoded BOOLEAN + */ + BER_Decoder& decode(bool& out) + { + return decode(out, BOOLEAN, UNIVERSAL); + } + + /* + * Decode a small BER encoded INTEGER + */ + BER_Decoder& decode(size_t& out) + { + return decode(out, INTEGER, UNIVERSAL); + } + + /* + * Decode a BER encoded INTEGER + */ + BER_Decoder& decode(BigInt& out) + { + return decode(out, INTEGER, UNIVERSAL); + } + + std::vector get_next_octet_string() + { + std::vector out_vec; + decode(out_vec, OCTET_STRING); + return out_vec; + } + + /* + * BER decode a BIT STRING or OCTET STRING + */ + template + BER_Decoder& decode(std::vector& out, ASN1_Tag real_type) + { + return decode(out, real_type, real_type, UNIVERSAL); + } + + BER_Decoder& decode(bool& v, + ASN1_Tag type_tag, + ASN1_Tag class_tag = CONTEXT_SPECIFIC); + + BER_Decoder& decode(size_t& v, + ASN1_Tag type_tag, + ASN1_Tag class_tag = CONTEXT_SPECIFIC); + + BER_Decoder& decode(BigInt& v, + ASN1_Tag type_tag, + ASN1_Tag class_tag = CONTEXT_SPECIFIC); + + BER_Decoder& decode(std::vector& v, + ASN1_Tag real_type, + ASN1_Tag type_tag, + ASN1_Tag class_tag = CONTEXT_SPECIFIC); + + BER_Decoder& decode(secure_vector& v, + ASN1_Tag real_type, + ASN1_Tag type_tag, + ASN1_Tag class_tag = CONTEXT_SPECIFIC); + + BER_Decoder& decode(class ASN1_Object& obj, + ASN1_Tag type_tag = NO_OBJECT, + ASN1_Tag class_tag = NO_OBJECT); + + /** + * Decode an integer value which is typed as an octet string + */ + BER_Decoder& decode_octet_string_bigint(BigInt& b); + + uint64_t decode_constrained_integer(ASN1_Tag type_tag, + ASN1_Tag class_tag, + size_t T_bytes); + + template BER_Decoder& decode_integer_type(T& out) + { + return decode_integer_type(out, INTEGER, UNIVERSAL); + } + + template + BER_Decoder& decode_integer_type(T& out, + ASN1_Tag type_tag, + ASN1_Tag class_tag = CONTEXT_SPECIFIC) + { + out = static_cast(decode_constrained_integer(type_tag, class_tag, sizeof(out))); + return (*this); + } + + template + BER_Decoder& decode_optional(T& out, + ASN1_Tag type_tag, + ASN1_Tag class_tag, + const T& default_value = T()); + + template + BER_Decoder& decode_optional_implicit( + T& out, + ASN1_Tag type_tag, + ASN1_Tag class_tag, + ASN1_Tag real_type, + ASN1_Tag real_class, + const T& default_value = T()); + + template + BER_Decoder& decode_list(std::vector& out, + ASN1_Tag type_tag = SEQUENCE, + ASN1_Tag class_tag = UNIVERSAL); + + template + BER_Decoder& decode_and_check(const T& expected, + const std::string& error_msg) + { + T actual; + decode(actual); + + if(actual != expected) + throw Decoding_Error(error_msg); + + return (*this); + } + + /* + * Decode an OPTIONAL string type + */ + template + BER_Decoder& decode_optional_string(std::vector& out, + ASN1_Tag real_type, + uint16_t type_no, + ASN1_Tag class_tag = CONTEXT_SPECIFIC) + { + BER_Object obj = get_next_object(); + + ASN1_Tag type_tag = static_cast(type_no); + + if(obj.is_a(type_tag, class_tag)) + { + if((class_tag & CONSTRUCTED) && (class_tag & CONTEXT_SPECIFIC)) + { + BER_Decoder(std::move(obj)).decode(out, real_type).verify_end(); + } + else + { + push_back(std::move(obj)); + decode(out, real_type, type_tag, class_tag); + } + } + else + { + out.clear(); + push_back(std::move(obj)); + } + + return (*this); + } + + private: + BER_Decoder(BER_Object&& obj, BER_Decoder* parent); + + BER_Decoder* m_parent = nullptr; + BER_Object m_pushed; + // either m_data_src.get() or an unowned pointer + DataSource* m_source; + mutable std::unique_ptr m_data_src; + }; + +/* +* Decode an OPTIONAL or DEFAULT element +*/ +template +BER_Decoder& BER_Decoder::decode_optional(T& out, + ASN1_Tag type_tag, + ASN1_Tag class_tag, + const T& default_value) + { + BER_Object obj = get_next_object(); + + if(obj.is_a(type_tag, class_tag)) + { + if((class_tag & CONSTRUCTED) && (class_tag & CONTEXT_SPECIFIC)) + { + BER_Decoder(std::move(obj)).decode(out).verify_end(); + } + else + { + push_back(std::move(obj)); + decode(out, type_tag, class_tag); + } + } + else + { + out = default_value; + push_back(std::move(obj)); + } + + return (*this); + } + +/* +* Decode an OPTIONAL or DEFAULT element +*/ +template +BER_Decoder& BER_Decoder::decode_optional_implicit( + T& out, + ASN1_Tag type_tag, + ASN1_Tag class_tag, + ASN1_Tag real_type, + ASN1_Tag real_class, + const T& default_value) + { + BER_Object obj = get_next_object(); + + if(obj.is_a(type_tag, class_tag)) + { + obj.set_tagging(real_type, real_class); + push_back(std::move(obj)); + decode(out, real_type, real_class); + } + else + { + // Not what we wanted, push it back on the stream + out = default_value; + push_back(std::move(obj)); + } + + return (*this); + } +/* +* Decode a list of homogenously typed values +*/ +template +BER_Decoder& BER_Decoder::decode_list(std::vector& vec, + ASN1_Tag type_tag, + ASN1_Tag class_tag) + { + BER_Decoder list = start_cons(type_tag, class_tag); + + while(list.more_items()) + { + T value; + list.decode(value); + vec.push_back(std::move(value)); + } + + list.end_cons(); + + return (*this); + } + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/asn1/der_enc.cpp b/src/libs/3rdparty/botan/src/lib/asn1/der_enc.cpp new file mode 100644 index 0000000000..99b833d27d --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/asn1/der_enc.cpp @@ -0,0 +1,405 @@ +/* +* DER Encoder +* (C) 1999-2007,2018 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include +#include +#include + +namespace Botan { + +namespace { + +/* +* DER encode an ASN.1 type tag +*/ +void encode_tag(std::vector& encoded_tag, + ASN1_Tag type_tag, ASN1_Tag class_tag) + { + if((class_tag | 0xE0) != 0xE0) + throw Encoding_Error("DER_Encoder: Invalid class tag " + + std::to_string(class_tag)); + + if(type_tag <= 30) + { + encoded_tag.push_back(static_cast(type_tag | class_tag)); + } + else + { + size_t blocks = high_bit(type_tag) + 6; + blocks = (blocks - (blocks % 7)) / 7; + + BOTAN_ASSERT_NOMSG(blocks > 0); + + encoded_tag.push_back(static_cast(class_tag | 0x1F)); + for(size_t i = 0; i != blocks - 1; ++i) + encoded_tag.push_back(0x80 | ((type_tag >> 7*(blocks-i-1)) & 0x7F)); + encoded_tag.push_back(type_tag & 0x7F); + } + } + +/* +* DER encode an ASN.1 length field +*/ +void encode_length(std::vector& encoded_length, size_t length) + { + if(length <= 127) + { + encoded_length.push_back(static_cast(length)); + } + else + { + const size_t bytes_needed = significant_bytes(length); + + encoded_length.push_back(static_cast(0x80 | bytes_needed)); + + for(size_t i = sizeof(length) - bytes_needed; i < sizeof(length); ++i) + encoded_length.push_back(get_byte(i, length)); + } + } + +} + +DER_Encoder::DER_Encoder(secure_vector& vec) + { + m_append_output = [&vec](const uint8_t b[], size_t l) + { + vec.insert(vec.end(), b, b + l); + }; + } + +DER_Encoder::DER_Encoder(std::vector& vec) + { + m_append_output = [&vec](const uint8_t b[], size_t l) + { + vec.insert(vec.end(), b, b + l); + }; + } + +/* +* Push the encoded SEQUENCE/SET to the encoder stream +*/ +void DER_Encoder::DER_Sequence::push_contents(DER_Encoder& der) + { + const ASN1_Tag real_class_tag = ASN1_Tag(m_class_tag | CONSTRUCTED); + + if(m_type_tag == SET) + { + std::sort(m_set_contents.begin(), m_set_contents.end()); + for(size_t i = 0; i != m_set_contents.size(); ++i) + m_contents += m_set_contents[i]; + m_set_contents.clear(); + } + + der.add_object(m_type_tag, real_class_tag, m_contents.data(), m_contents.size()); + m_contents.clear(); + } + +/* +* Add an encoded value to the SEQUENCE/SET +*/ +void DER_Encoder::DER_Sequence::add_bytes(const uint8_t data[], size_t length) + { + if(m_type_tag == SET) + m_set_contents.push_back(secure_vector(data, data + length)); + else + m_contents += std::make_pair(data, length); + } + +void DER_Encoder::DER_Sequence::add_bytes(const uint8_t hdr[], size_t hdr_len, + const uint8_t val[], size_t val_len) + { + if(m_type_tag == SET) + { + secure_vector m; + m.reserve(hdr_len + val_len); + m += std::make_pair(hdr, hdr_len); + m += std::make_pair(val, val_len); + m_set_contents.push_back(std::move(m)); + } + else + { + m_contents += std::make_pair(hdr, hdr_len); + m_contents += std::make_pair(val, val_len); + } + } + +/* +* Return the type and class taggings +*/ +ASN1_Tag DER_Encoder::DER_Sequence::tag_of() const + { + return ASN1_Tag(m_type_tag | m_class_tag); + } + +/* +* DER_Sequence Constructor +*/ +DER_Encoder::DER_Sequence::DER_Sequence(ASN1_Tag t1, ASN1_Tag t2) : + m_type_tag(t1), m_class_tag(t2) + { + } + +/* +* Return the encoded contents +*/ +secure_vector DER_Encoder::get_contents() + { + if(m_subsequences.size() != 0) + throw Invalid_State("DER_Encoder: Sequence hasn't been marked done"); + + if(m_append_output) + throw Invalid_State("DER_Encoder Cannot get contents when using output vector"); + + secure_vector output; + std::swap(output, m_default_outbuf); + return output; + } + +std::vector DER_Encoder::get_contents_unlocked() + { + if(m_subsequences.size() != 0) + throw Invalid_State("DER_Encoder: Sequence hasn't been marked done"); + + if(m_append_output) + throw Invalid_State("DER_Encoder Cannot get contents when using output vector"); + + std::vector output(m_default_outbuf.begin(), m_default_outbuf.end()); + m_default_outbuf.clear(); + return output; + } + +/* +* Start a new ASN.1 SEQUENCE/SET/EXPLICIT +*/ +DER_Encoder& DER_Encoder::start_cons(ASN1_Tag type_tag, + ASN1_Tag class_tag) + { + m_subsequences.push_back(DER_Sequence(type_tag, class_tag)); + return (*this); + } + +/* +* Finish the current ASN.1 SEQUENCE/SET/EXPLICIT +*/ +DER_Encoder& DER_Encoder::end_cons() + { + if(m_subsequences.empty()) + throw Invalid_State("DER_Encoder::end_cons: No such sequence"); + + DER_Sequence last_seq = std::move(m_subsequences[m_subsequences.size()-1]); + m_subsequences.pop_back(); + last_seq.push_contents(*this); + + return (*this); + } + +/* +* Start a new ASN.1 EXPLICIT encoding +*/ +DER_Encoder& DER_Encoder::start_explicit(uint16_t type_no) + { + ASN1_Tag type_tag = static_cast(type_no); + + // This would confuse DER_Sequence + if(type_tag == SET) + throw Internal_Error("DER_Encoder.start_explicit(SET) not supported"); + + return start_cons(type_tag, CONTEXT_SPECIFIC); + } + +/* +* Finish the current ASN.1 EXPLICIT encoding +*/ +DER_Encoder& DER_Encoder::end_explicit() + { + return end_cons(); + } + +/* +* Write raw bytes into the stream +*/ +DER_Encoder& DER_Encoder::raw_bytes(const uint8_t bytes[], size_t length) + { + if(m_subsequences.size()) + { + m_subsequences[m_subsequences.size()-1].add_bytes(bytes, length); + } + else if(m_append_output) + { + m_append_output(bytes, length); + } + else + { + m_default_outbuf += std::make_pair(bytes, length); + } + + return (*this); + } + +/* +* Write the encoding of the byte(s) +*/ +DER_Encoder& DER_Encoder::add_object(ASN1_Tag type_tag, ASN1_Tag class_tag, + const uint8_t rep[], size_t length) + { + std::vector hdr; + encode_tag(hdr, type_tag, class_tag); + encode_length(hdr, length); + + if(m_subsequences.size()) + { + m_subsequences[m_subsequences.size()-1].add_bytes(hdr.data(), hdr.size(), rep, length); + } + else if(m_append_output) + { + m_append_output(hdr.data(), hdr.size()); + m_append_output(rep, length); + } + else + { + m_default_outbuf += hdr; + m_default_outbuf += std::make_pair(rep, length); + } + + return (*this); + } + +/* +* Encode a NULL object +*/ +DER_Encoder& DER_Encoder::encode_null() + { + return add_object(NULL_TAG, UNIVERSAL, nullptr, 0); + } + +/* +* DER encode a BOOLEAN +*/ +DER_Encoder& DER_Encoder::encode(bool is_true) + { + return encode(is_true, BOOLEAN, UNIVERSAL); + } + +/* +* DER encode a small INTEGER +*/ +DER_Encoder& DER_Encoder::encode(size_t n) + { + return encode(BigInt(n), INTEGER, UNIVERSAL); + } + +/* +* DER encode a small INTEGER +*/ +DER_Encoder& DER_Encoder::encode(const BigInt& n) + { + return encode(n, INTEGER, UNIVERSAL); + } + +/* +* Encode this object +*/ +DER_Encoder& DER_Encoder::encode(const uint8_t bytes[], size_t length, + ASN1_Tag real_type) + { + return encode(bytes, length, real_type, real_type, UNIVERSAL); + } + +/* +* DER encode a BOOLEAN +*/ +DER_Encoder& DER_Encoder::encode(bool is_true, + ASN1_Tag type_tag, ASN1_Tag class_tag) + { + uint8_t val = is_true ? 0xFF : 0x00; + return add_object(type_tag, class_tag, &val, 1); + } + +/* +* DER encode a small INTEGER +*/ +DER_Encoder& DER_Encoder::encode(size_t n, + ASN1_Tag type_tag, ASN1_Tag class_tag) + { + return encode(BigInt(n), type_tag, class_tag); + } + +/* +* DER encode an INTEGER +*/ +DER_Encoder& DER_Encoder::encode(const BigInt& n, + ASN1_Tag type_tag, ASN1_Tag class_tag) + { + if(n == 0) + return add_object(type_tag, class_tag, 0); + + const size_t extra_zero = (n.bits() % 8 == 0) ? 1 : 0; + secure_vector contents(extra_zero + n.bytes()); + BigInt::encode(&contents[extra_zero], n); + if(n < 0) + { + for(size_t i = 0; i != contents.size(); ++i) + contents[i] = ~contents[i]; + for(size_t i = contents.size(); i > 0; --i) + if(++contents[i-1]) + break; + } + + return add_object(type_tag, class_tag, contents); + } + +/* +* DER encode an OCTET STRING or BIT STRING +*/ +DER_Encoder& DER_Encoder::encode(const uint8_t bytes[], size_t length, + ASN1_Tag real_type, + ASN1_Tag type_tag, ASN1_Tag class_tag) + { + if(real_type != OCTET_STRING && real_type != BIT_STRING) + throw Invalid_Argument("DER_Encoder: Invalid tag for byte/bit string"); + + if(real_type == BIT_STRING) + { + secure_vector encoded; + encoded.push_back(0); + encoded += std::make_pair(bytes, length); + return add_object(type_tag, class_tag, encoded); + } + else + return add_object(type_tag, class_tag, bytes, length); + } + +DER_Encoder& DER_Encoder::encode(const ASN1_Object& obj) + { + obj.encode_into(*this); + return (*this); + } + +/* +* Write the encoding of the byte(s) +*/ +DER_Encoder& DER_Encoder::add_object(ASN1_Tag type_tag, ASN1_Tag class_tag, + const std::string& rep_str) + { + const uint8_t* rep = cast_char_ptr_to_uint8(rep_str.data()); + const size_t rep_len = rep_str.size(); + return add_object(type_tag, class_tag, rep, rep_len); + } + +/* +* Write the encoding of the byte +*/ +DER_Encoder& DER_Encoder::add_object(ASN1_Tag type_tag, + ASN1_Tag class_tag, uint8_t rep) + { + return add_object(type_tag, class_tag, &rep, 1); + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/asn1/der_enc.h b/src/libs/3rdparty/botan/src/lib/asn1/der_enc.h new file mode 100644 index 0000000000..135a70d074 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/asn1/der_enc.h @@ -0,0 +1,221 @@ +/* +* DER Encoder +* (C) 1999-2007,2018 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_DER_ENCODER_H_ +#define BOTAN_DER_ENCODER_H_ + +#include +#include +#include + +namespace Botan { + +class BigInt; +class ASN1_Object; + +/** +* General DER Encoding Object +*/ +class BOTAN_PUBLIC_API(2,0) DER_Encoder final + { + public: + typedef std::function append_fn; + + /** + * DER encode, writing to an internal buffer + * Use get_contents or get_contents_unlocked to read the results + * after all encoding is completed. + */ + DER_Encoder() = default; + + /** + * DER encode, writing to @param vec + * If this constructor is used, get_contents* may not be called. + */ + DER_Encoder(secure_vector& vec); + + /** + * DER encode, writing to @param vec + * If this constructor is used, get_contents* may not be called. + */ + DER_Encoder(std::vector& vec); + + /** + * DER encode, calling append to write output + * If this constructor is used, get_contents* may not be called. + */ + DER_Encoder(append_fn append) : m_append_output(append) {} + + secure_vector get_contents(); + + std::vector get_contents_unlocked(); + + DER_Encoder& start_cons(ASN1_Tag type_tag, + ASN1_Tag class_tag = UNIVERSAL); + DER_Encoder& end_cons(); + + DER_Encoder& start_explicit(uint16_t type_tag); + DER_Encoder& end_explicit(); + + /** + * Insert raw bytes directly into the output stream + */ + DER_Encoder& raw_bytes(const uint8_t val[], size_t len); + + template + DER_Encoder& raw_bytes(const std::vector& val) + { + return raw_bytes(val.data(), val.size()); + } + + DER_Encoder& encode_null(); + DER_Encoder& encode(bool b); + DER_Encoder& encode(size_t s); + DER_Encoder& encode(const BigInt& n); + DER_Encoder& encode(const uint8_t val[], size_t len, ASN1_Tag real_type); + + template + DER_Encoder& encode(const std::vector& vec, ASN1_Tag real_type) + { + return encode(vec.data(), vec.size(), real_type); + } + + DER_Encoder& encode(bool b, + ASN1_Tag type_tag, + ASN1_Tag class_tag = CONTEXT_SPECIFIC); + + DER_Encoder& encode(size_t s, + ASN1_Tag type_tag, + ASN1_Tag class_tag = CONTEXT_SPECIFIC); + + DER_Encoder& encode(const BigInt& n, + ASN1_Tag type_tag, + ASN1_Tag class_tag = CONTEXT_SPECIFIC); + + DER_Encoder& encode(const uint8_t v[], size_t len, + ASN1_Tag real_type, + ASN1_Tag type_tag, + ASN1_Tag class_tag = CONTEXT_SPECIFIC); + + template + DER_Encoder& encode(const std::vector& bytes, + ASN1_Tag real_type, + ASN1_Tag type_tag, ASN1_Tag class_tag) + { + return encode(bytes.data(), bytes.size(), + real_type, type_tag, class_tag); + } + + template + DER_Encoder& encode_optional(const T& value, const T& default_value) + { + if(value != default_value) + encode(value); + return (*this); + } + + template + DER_Encoder& encode_list(const std::vector& values) + { + for(size_t i = 0; i != values.size(); ++i) + encode(values[i]); + return (*this); + } + + /* + * Request for an object to encode itself to this stream + */ + DER_Encoder& encode(const ASN1_Object& obj); + + /* + * Conditionally write some values to the stream + */ + DER_Encoder& encode_if(bool pred, DER_Encoder& enc) + { + if(pred) + return raw_bytes(enc.get_contents()); + return (*this); + } + + DER_Encoder& encode_if(bool pred, const ASN1_Object& obj) + { + if(pred) + encode(obj); + return (*this); + } + + DER_Encoder& add_object(ASN1_Tag type_tag, ASN1_Tag class_tag, + const uint8_t rep[], size_t length); + + DER_Encoder& add_object(ASN1_Tag type_tag, ASN1_Tag class_tag, + const std::vector& rep) + { + return add_object(type_tag, class_tag, rep.data(), rep.size()); + } + + DER_Encoder& add_object(ASN1_Tag type_tag, ASN1_Tag class_tag, + const secure_vector& rep) + { + return add_object(type_tag, class_tag, rep.data(), rep.size()); + } + + DER_Encoder& add_object(ASN1_Tag type_tag, ASN1_Tag class_tag, + const std::string& str); + + DER_Encoder& add_object(ASN1_Tag type_tag, ASN1_Tag class_tag, + uint8_t val); + + private: + class DER_Sequence final + { + public: + ASN1_Tag tag_of() const; + + void push_contents(DER_Encoder& der); + + void add_bytes(const uint8_t val[], size_t len); + + void add_bytes(const uint8_t hdr[], size_t hdr_len, + const uint8_t val[], size_t val_len); + + DER_Sequence(ASN1_Tag, ASN1_Tag); + + DER_Sequence(DER_Sequence&& seq) + { + std::swap(m_type_tag, seq.m_type_tag); + std::swap(m_class_tag, seq.m_class_tag); + std::swap(m_contents, seq.m_contents); + std::swap(m_set_contents, seq.m_set_contents); + } + + DER_Sequence& operator=(DER_Sequence&& seq) + { + std::swap(m_type_tag, seq.m_type_tag); + std::swap(m_class_tag, seq.m_class_tag); + std::swap(m_contents, seq.m_contents); + std::swap(m_set_contents, seq.m_set_contents); + return (*this); + } + + DER_Sequence(const DER_Sequence& seq) = default; + + DER_Sequence& operator=(const DER_Sequence& seq) = default; + + private: + ASN1_Tag m_type_tag, m_class_tag; + secure_vector m_contents; + std::vector< secure_vector > m_set_contents; + }; + + append_fn m_append_output; + secure_vector m_default_outbuf; + std::vector m_subsequences; + }; + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/asn1/info.txt b/src/libs/3rdparty/botan/src/lib/asn1/info.txt new file mode 100644 index 0000000000..4772e1ca70 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/asn1/info.txt @@ -0,0 +1,7 @@ + +ASN1 -> 20171109 + + + +bigint + diff --git a/src/libs/3rdparty/botan/src/lib/asn1/oid_maps.cpp b/src/libs/3rdparty/botan/src/lib/asn1/oid_maps.cpp new file mode 100644 index 0000000000..138661a809 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/asn1/oid_maps.cpp @@ -0,0 +1,447 @@ +/* +* OID maps +* +* This file was automatically generated by ./src/scripts/oids.py on 2018-07-01 +* +* All manual edits to this file will be lost. Edit the script +* then regenerate this source file. +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include + +namespace Botan { + +std::unordered_map OIDS::load_oid2str_map() + { + return std::unordered_map{ + { "0.3.4401.5.3.1.9.26", "Camellia-192/GCM" }, + { "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.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.2", "SM2_Kex" }, + { "1.2.156.10197.1.301.3", "SM2_Enc" }, + { "1.2.156.10197.1.401", "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" }, + { "1.2.392.200011.61.1.1.1.3", "Camellia-192/CBC" }, + { "1.2.392.200011.61.1.1.1.4", "Camellia-256/CBC" }, + { "1.2.410.200004.1.100.4.3", "ECKCDSA/EMSA1(SHA-1)" }, + { "1.2.410.200004.1.100.4.4", "ECKCDSA/EMSA1(SHA-224)" }, + { "1.2.410.200004.1.100.4.5", "ECKCDSA/EMSA1(SHA-256)" }, + { "1.2.410.200004.1.4", "SEED/CBC" }, + { "1.2.643.2.2.19", "GOST-34.10" }, + { "1.2.643.2.2.3", "GOST-34.10/EMSA1(GOST-R-34.11-94)" }, + { "1.2.643.2.2.35.1", "gost_256A" }, + { "1.2.643.2.2.36.0", "gost_256A" }, + { "1.2.643.7.1.1.2.2", "Streebog-256" }, + { "1.2.643.7.1.1.2.3", "Streebog-512" }, + { "1.2.840.10040.4.1", "DSA" }, + { "1.2.840.10040.4.3", "DSA/EMSA1(SHA-160)" }, + { "1.2.840.10045.2.1", "ECDSA" }, + { "1.2.840.10045.3.1.1", "secp192r1" }, + { "1.2.840.10045.3.1.2", "x962_p192v2" }, + { "1.2.840.10045.3.1.3", "x962_p192v3" }, + { "1.2.840.10045.3.1.4", "x962_p239v1" }, + { "1.2.840.10045.3.1.5", "x962_p239v2" }, + { "1.2.840.10045.3.1.6", "x962_p239v3" }, + { "1.2.840.10045.3.1.7", "secp256r1" }, + { "1.2.840.10045.4.1", "ECDSA/EMSA1(SHA-160)" }, + { "1.2.840.10045.4.3.1", "ECDSA/EMSA1(SHA-224)" }, + { "1.2.840.10045.4.3.2", "ECDSA/EMSA1(SHA-256)" }, + { "1.2.840.10045.4.3.3", "ECDSA/EMSA1(SHA-384)" }, + { "1.2.840.10045.4.3.4", "ECDSA/EMSA1(SHA-512)" }, + { "1.2.840.10046.2.1", "DH" }, + { "1.2.840.113533.7.66.10", "CAST-128/CBC" }, + { "1.2.840.113533.7.66.15", "KeyWrap.CAST-128" }, + { "1.2.840.113549.1.1.1", "RSA" }, + { "1.2.840.113549.1.1.10", "RSA/EMSA4" }, + { "1.2.840.113549.1.1.11", "RSA/EMSA3(SHA-256)" }, + { "1.2.840.113549.1.1.12", "RSA/EMSA3(SHA-384)" }, + { "1.2.840.113549.1.1.13", "RSA/EMSA3(SHA-512)" }, + { "1.2.840.113549.1.1.14", "RSA/EMSA3(SHA-224)" }, + { "1.2.840.113549.1.1.16", "RSA/EMSA3(SHA-512-256)" }, + { "1.2.840.113549.1.1.4", "RSA/EMSA3(MD5)" }, + { "1.2.840.113549.1.1.5", "RSA/EMSA3(SHA-160)" }, + { "1.2.840.113549.1.1.7", "RSA/OAEP" }, + { "1.2.840.113549.1.1.8", "MGF1" }, + { "1.2.840.113549.1.5.12", "PKCS5.PBKDF2" }, + { "1.2.840.113549.1.5.13", "PBE-PKCS5v20" }, + { "1.2.840.113549.1.9.1", "PKCS9.EmailAddress" }, + { "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" }, + { "1.2.840.113549.1.9.4", "PKCS9.MessageDigest" }, + { "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.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" }, + { "1.3.132.0.10", "secp256k1" }, + { "1.3.132.0.30", "secp160r2" }, + { "1.3.132.0.31", "secp192k1" }, + { "1.3.132.0.32", "secp224k1" }, + { "1.3.132.0.33", "secp224r1" }, + { "1.3.132.0.34", "secp384r1" }, + { "1.3.132.0.35", "secp521r1" }, + { "1.3.132.0.8", "secp160r1" }, + { "1.3.132.0.9", "secp160k1" }, + { "1.3.132.1.12", "ECDH" }, + { "1.3.14.3.2.26", "SHA-160" }, + { "1.3.14.3.2.7", "DES/CBC" }, + { "1.3.36.3.2.1", "RIPEMD-160" }, + { "1.3.36.3.3.1.2", "RSA/EMSA3(RIPEMD-160)" }, + { "1.3.36.3.3.2.5.2.1", "ECGDSA" }, + { "1.3.36.3.3.2.5.4.1", "ECGDSA/EMSA1(RIPEMD-160)" }, + { "1.3.36.3.3.2.5.4.2", "ECGDSA/EMSA1(SHA-160)" }, + { "1.3.36.3.3.2.5.4.3", "ECGDSA/EMSA1(SHA-224)" }, + { "1.3.36.3.3.2.5.4.4", "ECGDSA/EMSA1(SHA-256)" }, + { "1.3.36.3.3.2.5.4.5", "ECGDSA/EMSA1(SHA-384)" }, + { "1.3.36.3.3.2.5.4.6", "ECGDSA/EMSA1(SHA-512)" }, + { "1.3.36.3.3.2.8.1.1.1", "brainpool160r1" }, + { "1.3.36.3.3.2.8.1.1.11", "brainpool384r1" }, + { "1.3.36.3.3.2.8.1.1.13", "brainpool512r1" }, + { "1.3.36.3.3.2.8.1.1.3", "brainpool192r1" }, + { "1.3.36.3.3.2.8.1.1.5", "brainpool224r1" }, + { "1.3.36.3.3.2.8.1.1.7", "brainpool256r1" }, + { "1.3.36.3.3.2.8.1.1.9", "brainpool320r1" }, + { "1.3.6.1.4.1.11591.12.2", "Tiger(24,3)" }, + { "1.3.6.1.4.1.11591.15.1", "OpenPGP.Ed25519" }, + { "1.3.6.1.4.1.11591.4.11", "Scrypt" }, + { "1.3.6.1.4.1.25258.1.3", "McEliece" }, + { "1.3.6.1.4.1.25258.1.5", "XMSS" }, + { "1.3.6.1.4.1.25258.1.6.1", "GOST-34.10/EMSA1(SHA-256)" }, + { "1.3.6.1.4.1.25258.3.1", "Serpent/CBC" }, + { "1.3.6.1.4.1.25258.3.101", "Serpent/GCM" }, + { "1.3.6.1.4.1.25258.3.102", "Twofish/GCM" }, + { "1.3.6.1.4.1.25258.3.2", "Threefish-512/CBC" }, + { "1.3.6.1.4.1.25258.3.2.1", "AES-128/OCB" }, + { "1.3.6.1.4.1.25258.3.2.2", "AES-192/OCB" }, + { "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.3", "Twofish/CBC" }, + { "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.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" }, + { "1.3.6.1.5.5.7.3.2", "PKIX.ClientAuth" }, + { "1.3.6.1.5.5.7.3.3", "PKIX.CodeSigning" }, + { "1.3.6.1.5.5.7.3.4", "PKIX.EmailProtection" }, + { "1.3.6.1.5.5.7.3.5", "PKIX.IPsecEndSystem" }, + { "1.3.6.1.5.5.7.3.6", "PKIX.IPsecTunnel" }, + { "1.3.6.1.5.5.7.3.7", "PKIX.IPsecUser" }, + { "1.3.6.1.5.5.7.3.8", "PKIX.TimeStamping" }, + { "1.3.6.1.5.5.7.3.9", "PKIX.OCSPSigning" }, + { "1.3.6.1.5.5.7.48.1", "PKIX.OCSP" }, + { "1.3.6.1.5.5.7.48.1.1", "PKIX.OCSP.BasicResponse" }, + { "1.3.6.1.5.5.7.48.2", "PKIX.CertificateAuthorityIssuers" }, + { "1.3.6.1.5.5.7.8.5", "PKIX.XMPPAddr" }, + { "2.16.840.1.101.3.4.1.2", "AES-128/CBC" }, + { "2.16.840.1.101.3.4.1.22", "AES-192/CBC" }, + { "2.16.840.1.101.3.4.1.25", "KeyWrap.AES-192" }, + { "2.16.840.1.101.3.4.1.26", "AES-192/GCM" }, + { "2.16.840.1.101.3.4.1.27", "AES-192/CCM" }, + { "2.16.840.1.101.3.4.1.42", "AES-256/CBC" }, + { "2.16.840.1.101.3.4.1.45", "KeyWrap.AES-256" }, + { "2.16.840.1.101.3.4.1.46", "AES-256/GCM" }, + { "2.16.840.1.101.3.4.1.47", "AES-256/CCM" }, + { "2.16.840.1.101.3.4.1.5", "KeyWrap.AES-128" }, + { "2.16.840.1.101.3.4.1.6", "AES-128/GCM" }, + { "2.16.840.1.101.3.4.1.7", "AES-128/CCM" }, + { "2.16.840.1.101.3.4.2.1", "SHA-256" }, + { "2.16.840.1.101.3.4.2.10", "SHA-3(512)" }, + { "2.16.840.1.101.3.4.2.11", "SHAKE-128" }, + { "2.16.840.1.101.3.4.2.12", "SHAKE-256" }, + { "2.16.840.1.101.3.4.2.2", "SHA-384" }, + { "2.16.840.1.101.3.4.2.3", "SHA-512" }, + { "2.16.840.1.101.3.4.2.4", "SHA-224" }, + { "2.16.840.1.101.3.4.2.6", "SHA-512-256" }, + { "2.16.840.1.101.3.4.2.7", "SHA-3(224)" }, + { "2.16.840.1.101.3.4.2.8", "SHA-3(256)" }, + { "2.16.840.1.101.3.4.2.9", "SHA-3(384)" }, + { "2.16.840.1.101.3.4.3.1", "DSA/EMSA1(SHA-224)" }, + { "2.16.840.1.101.3.4.3.10", "ECDSA/EMSA1(SHA-3(256))" }, + { "2.16.840.1.101.3.4.3.11", "ECDSA/EMSA1(SHA-3(384))" }, + { "2.16.840.1.101.3.4.3.12", "ECDSA/EMSA1(SHA-3(512))" }, + { "2.16.840.1.101.3.4.3.13", "RSA/EMSA3(SHA-3(224))" }, + { "2.16.840.1.101.3.4.3.14", "RSA/EMSA3(SHA-3(256))" }, + { "2.16.840.1.101.3.4.3.15", "RSA/EMSA3(SHA-3(384))" }, + { "2.16.840.1.101.3.4.3.16", "RSA/EMSA3(SHA-3(512))" }, + { "2.16.840.1.101.3.4.3.2", "DSA/EMSA1(SHA-256)" }, + { "2.16.840.1.101.3.4.3.3", "DSA/EMSA1(SHA-384)" }, + { "2.16.840.1.101.3.4.3.4", "DSA/EMSA1(SHA-512)" }, + { "2.16.840.1.101.3.4.3.5", "DSA/EMSA1(SHA-3(224))" }, + { "2.16.840.1.101.3.4.3.6", "DSA/EMSA1(SHA-3(256))" }, + { "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.5.29.14", "X509v3.SubjectKeyIdentifier" }, + { "2.5.29.15", "X509v3.KeyUsage" }, + { "2.5.29.17", "X509v3.SubjectAlternativeName" }, + { "2.5.29.18", "X509v3.IssuerAlternativeName" }, + { "2.5.29.19", "X509v3.BasicConstraints" }, + { "2.5.29.20", "X509v3.CRLNumber" }, + { "2.5.29.21", "X509v3.ReasonCode" }, + { "2.5.29.23", "X509v3.HoldInstructionCode" }, + { "2.5.29.24", "X509v3.InvalidityDate" }, + { "2.5.29.28", "X509v3.CRLIssuingDistributionPoint" }, + { "2.5.29.30", "X509v3.NameConstraints" }, + { "2.5.29.31", "X509v3.CRLDistributionPoints" }, + { "2.5.29.32", "X509v3.CertificatePolicies" }, + { "2.5.29.32.0", "X509v3.AnyPolicy" }, + { "2.5.29.35", "X509v3.AuthorityKeyIdentifier" }, + { "2.5.29.36", "X509v3.PolicyConstraints" }, + { "2.5.29.37", "X509v3.ExtendedKeyUsage" }, + { "2.5.4.10", "X520.Organization" }, + { "2.5.4.11", "X520.OrganizationalUnit" }, + { "2.5.4.12", "X520.Title" }, + { "2.5.4.3", "X520.CommonName" }, + { "2.5.4.4", "X520.Surname" }, + { "2.5.4.42", "X520.GivenName" }, + { "2.5.4.43", "X520.Initials" }, + { "2.5.4.44", "X520.GenerationalQualifier" }, + { "2.5.4.46", "X520.DNQualifier" }, + { "2.5.4.5", "X520.SerialNumber" }, + { "2.5.4.6", "X520.Country" }, + { "2.5.4.65", "X520.Pseudonym" }, + { "2.5.4.7", "X520.Locality" }, + { "2.5.4.8", "X520.State" }, + { "2.5.8.1.1", "RSA" } + }; + } + +std::unordered_map OIDS::load_str2oid_map() + { + return std::unordered_map{ + { "AES-128/CBC", OID({2,16,840,1,101,3,4,1,2}) }, + { "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-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-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}) }, + { "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-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-256/CBC", OID({1,2,392,200011,61,1,1,1,4}) }, + { "Camellia-256/GCM", OID({0,3,4401,5,3,1,9,46}) }, + { "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}) }, + { "DES/CBC", OID({1,3,14,3,2,7}) }, + { "DH", OID({1,2,840,10046,2,1}) }, + { "DSA", OID({1,2,840,10040,4,1}) }, + { "DSA/EMSA1(SHA-160)", OID({1,2,840,10040,4,3}) }, + { "DSA/EMSA1(SHA-224)", OID({2,16,840,1,101,3,4,3,1}) }, + { "DSA/EMSA1(SHA-256)", OID({2,16,840,1,101,3,4,3,2}) }, + { "DSA/EMSA1(SHA-3(224))", OID({2,16,840,1,101,3,4,3,5}) }, + { "DSA/EMSA1(SHA-3(256))", OID({2,16,840,1,101,3,4,3,6}) }, + { "DSA/EMSA1(SHA-3(384))", OID({2,16,840,1,101,3,4,3,7}) }, + { "DSA/EMSA1(SHA-3(512))", OID({2,16,840,1,101,3,4,3,8}) }, + { "DSA/EMSA1(SHA-384)", OID({2,16,840,1,101,3,4,3,3}) }, + { "DSA/EMSA1(SHA-512)", OID({2,16,840,1,101,3,4,3,4}) }, + { "ECDH", OID({1,3,132,1,12}) }, + { "ECDSA", OID({1,2,840,10045,2,1}) }, + { "ECDSA/EMSA1(SHA-160)", OID({1,2,840,10045,4,1}) }, + { "ECDSA/EMSA1(SHA-224)", OID({1,2,840,10045,4,3,1}) }, + { "ECDSA/EMSA1(SHA-256)", OID({1,2,840,10045,4,3,2}) }, + { "ECDSA/EMSA1(SHA-3(224))", OID({2,16,840,1,101,3,4,3,9}) }, + { "ECDSA/EMSA1(SHA-3(256))", OID({2,16,840,1,101,3,4,3,10}) }, + { "ECDSA/EMSA1(SHA-3(384))", OID({2,16,840,1,101,3,4,3,11}) }, + { "ECDSA/EMSA1(SHA-3(512))", OID({2,16,840,1,101,3,4,3,12}) }, + { "ECDSA/EMSA1(SHA-384)", OID({1,2,840,10045,4,3,3}) }, + { "ECDSA/EMSA1(SHA-512)", OID({1,2,840,10045,4,3,4}) }, + { "ECGDSA", OID({1,3,36,3,3,2,5,2,1}) }, + { "ECGDSA/EMSA1(RIPEMD-160)", OID({1,3,36,3,3,2,5,4,1}) }, + { "ECGDSA/EMSA1(SHA-160)", OID({1,3,36,3,3,2,5,4,2}) }, + { "ECGDSA/EMSA1(SHA-224)", OID({1,3,36,3,3,2,5,4,3}) }, + { "ECGDSA/EMSA1(SHA-256)", OID({1,3,36,3,3,2,5,4,4}) }, + { "ECGDSA/EMSA1(SHA-384)", OID({1,3,36,3,3,2,5,4,5}) }, + { "ECGDSA/EMSA1(SHA-512)", OID({1,3,36,3,3,2,5,4,6}) }, + { "ECKCDSA", OID({1,0,14888,3,0,5}) }, + { "ECKCDSA/EMSA1(SHA-1)", OID({1,2,410,200004,1,100,4,3}) }, + { "ECKCDSA/EMSA1(SHA-224)", OID({1,2,410,200004,1,100,4,4}) }, + { "ECKCDSA/EMSA1(SHA-256)", OID({1,2,410,200004,1,100,4,5}) }, + { "Ed25519", OID({1,3,101,112}) }, + { "ElGamal", OID({1,3,6,1,4,1,3029,1,2,1}) }, + { "GOST-34.10", OID({1,2,643,2,2,19}) }, + { "GOST-34.10/EMSA1(GOST-R-34.11-94)", OID({1,2,643,2,2,3}) }, + { "GOST-34.10/EMSA1(SHA-256)", OID({1,3,6,1,4,1,25258,1,6,1}) }, + { "HMAC(SHA-160)", OID({1,2,840,113549,2,7}) }, + { "HMAC(SHA-224)", OID({1,2,840,113549,2,8}) }, + { "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}) }, + { "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}) }, + { "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}) }, + { "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}) }, + { "PKCS9.EmailAddress", OID({1,2,840,113549,1,9,1}) }, + { "PKCS9.ExtensionRequest", OID({1,2,840,113549,1,9,14}) }, + { "PKCS9.MessageDigest", OID({1,2,840,113549,1,9,4}) }, + { "PKCS9.UnstructuredName", OID({1,2,840,113549,1,9,2}) }, + { "PKIX.AuthorityInformationAccess", OID({1,3,6,1,5,5,7,1,1}) }, + { "PKIX.CertificateAuthorityIssuers", OID({1,3,6,1,5,5,7,48,2}) }, + { "PKIX.ClientAuth", OID({1,3,6,1,5,5,7,3,2}) }, + { "PKIX.CodeSigning", OID({1,3,6,1,5,5,7,3,3}) }, + { "PKIX.EmailProtection", OID({1,3,6,1,5,5,7,3,4}) }, + { "PKIX.IPsecEndSystem", OID({1,3,6,1,5,5,7,3,5}) }, + { "PKIX.IPsecTunnel", OID({1,3,6,1,5,5,7,3,6}) }, + { "PKIX.IPsecUser", OID({1,3,6,1,5,5,7,3,7}) }, + { "PKIX.OCSP", OID({1,3,6,1,5,5,7,48,1}) }, + { "PKIX.OCSP.BasicResponse", OID({1,3,6,1,5,5,7,48,1,1}) }, + { "PKIX.OCSPSigning", OID({1,3,6,1,5,5,7,3,9}) }, + { "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}) }, + { "RSA/EMSA3(RIPEMD-160)", OID({1,3,36,3,3,1,2}) }, + { "RSA/EMSA3(SHA-160)", OID({1,2,840,113549,1,1,5}) }, + { "RSA/EMSA3(SHA-224)", OID({1,2,840,113549,1,1,14}) }, + { "RSA/EMSA3(SHA-256)", OID({1,2,840,113549,1,1,11}) }, + { "RSA/EMSA3(SHA-3(224))", OID({2,16,840,1,101,3,4,3,13}) }, + { "RSA/EMSA3(SHA-3(256))", OID({2,16,840,1,101,3,4,3,14}) }, + { "RSA/EMSA3(SHA-3(384))", OID({2,16,840,1,101,3,4,3,15}) }, + { "RSA/EMSA3(SHA-3(512))", OID({2,16,840,1,101,3,4,3,16}) }, + { "RSA/EMSA3(SHA-384)", OID({1,2,840,113549,1,1,12}) }, + { "RSA/EMSA3(SHA-512)", OID({1,2,840,113549,1,1,13}) }, + { "RSA/EMSA3(SHA-512-256)", OID({1,2,840,113549,1,1,16}) }, + { "RSA/EMSA3(SM3)", OID({1,2,156,10197,1,504}) }, + { "RSA/EMSA4", OID({1,2,840,113549,1,1,10}) }, + { "RSA/OAEP", OID({1,2,840,113549,1,1,7}) }, + { "SEED/CBC", OID({1,2,410,200004,1,4}) }, + { "SHA-160", OID({1,3,14,3,2,26}) }, + { "SHA-224", OID({2,16,840,1,101,3,4,2,4}) }, + { "SHA-256", OID({2,16,840,1,101,3,4,2,1}) }, + { "SHA-3(224)", OID({2,16,840,1,101,3,4,2,7}) }, + { "SHA-3(256)", OID({2,16,840,1,101,3,4,2,8}) }, + { "SHA-3(384)", OID({2,16,840,1,101,3,4,2,9}) }, + { "SHA-3(512)", OID({2,16,840,1,101,3,4,2,10}) }, + { "SHA-384", OID({2,16,840,1,101,3,4,2,2}) }, + { "SHA-512", OID({2,16,840,1,101,3,4,2,3}) }, + { "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_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}) }, + { "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}) }, + { "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}) }, + { "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}) }, + { "Tiger(24,3)", OID({1,3,6,1,4,1,11591,12,2}) }, + { "TripleDES/CBC", OID({1,2,840,113549,3,7}) }, + { "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}) }, + { "X509v3.AnyPolicy", OID({2,5,29,32,0}) }, + { "X509v3.AuthorityKeyIdentifier", OID({2,5,29,35}) }, + { "X509v3.BasicConstraints", OID({2,5,29,19}) }, + { "X509v3.CRLDistributionPoints", OID({2,5,29,31}) }, + { "X509v3.CRLIssuingDistributionPoint", OID({2,5,29,28}) }, + { "X509v3.CRLNumber", OID({2,5,29,20}) }, + { "X509v3.CertificatePolicies", OID({2,5,29,32}) }, + { "X509v3.ExtendedKeyUsage", OID({2,5,29,37}) }, + { "X509v3.HoldInstructionCode", OID({2,5,29,23}) }, + { "X509v3.InvalidityDate", OID({2,5,29,24}) }, + { "X509v3.IssuerAlternativeName", OID({2,5,29,18}) }, + { "X509v3.KeyUsage", OID({2,5,29,15}) }, + { "X509v3.NameConstraints", OID({2,5,29,30}) }, + { "X509v3.PolicyConstraints", OID({2,5,29,36}) }, + { "X509v3.ReasonCode", OID({2,5,29,21}) }, + { "X509v3.SubjectAlternativeName", OID({2,5,29,17}) }, + { "X509v3.SubjectKeyIdentifier", OID({2,5,29,14}) }, + { "X520.CommonName", OID({2,5,4,3}) }, + { "X520.Country", OID({2,5,4,6}) }, + { "X520.DNQualifier", OID({2,5,4,46}) }, + { "X520.GenerationalQualifier", OID({2,5,4,44}) }, + { "X520.GivenName", OID({2,5,4,42}) }, + { "X520.Initials", OID({2,5,4,43}) }, + { "X520.Locality", OID({2,5,4,7}) }, + { "X520.Organization", OID({2,5,4,10}) }, + { "X520.OrganizationalUnit", OID({2,5,4,11}) }, + { "X520.Pseudonym", OID({2,5,4,65}) }, + { "X520.SerialNumber", OID({2,5,4,5}) }, + { "X520.State", OID({2,5,4,8}) }, + { "X520.Surname", OID({2,5,4,4}) }, + { "X520.Title", OID({2,5,4,12}) }, + { "XMSS", OID({1,3,6,1,4,1,25258,1,5}) }, + { "brainpool160r1", OID({1,3,36,3,3,2,8,1,1,1}) }, + { "brainpool192r1", OID({1,3,36,3,3,2,8,1,1,3}) }, + { "brainpool224r1", OID({1,3,36,3,3,2,8,1,1,5}) }, + { "brainpool256r1", OID({1,3,36,3,3,2,8,1,1,7}) }, + { "brainpool320r1", OID({1,3,36,3,3,2,8,1,1,9}) }, + { "brainpool384r1", OID({1,3,36,3,3,2,8,1,1,11}) }, + { "brainpool512r1", OID({1,3,36,3,3,2,8,1,1,13}) }, + { "frp256v1", OID({1,2,250,1,223,101,256,1}) }, + { "gost_256A", OID({1,2,643,2,2,35,1}) }, + { "secp160k1", OID({1,3,132,0,9}) }, + { "secp160r1", OID({1,3,132,0,8}) }, + { "secp160r2", OID({1,3,132,0,30}) }, + { "secp192k1", OID({1,3,132,0,31}) }, + { "secp192r1", OID({1,2,840,10045,3,1,1}) }, + { "secp224k1", OID({1,3,132,0,32}) }, + { "secp224r1", OID({1,3,132,0,33}) }, + { "secp256k1", OID({1,3,132,0,10}) }, + { "secp256r1", OID({1,2,840,10045,3,1,7}) }, + { "secp384r1", OID({1,3,132,0,34}) }, + { "secp521r1", OID({1,3,132,0,35}) }, + { "sm2p256v1", OID({1,2,156,10197,1,301}) }, + { "x962_p192v2", OID({1,2,840,10045,3,1,2}) }, + { "x962_p192v3", OID({1,2,840,10045,3,1,3}) }, + { "x962_p239v1", OID({1,2,840,10045,3,1,4}) }, + { "x962_p239v2", OID({1,2,840,10045,3,1,5}) }, + { "x962_p239v3", OID({1,2,840,10045,3,1,6}) } + }; + } + +} + diff --git a/src/libs/3rdparty/botan/src/lib/asn1/oids.cpp b/src/libs/3rdparty/botan/src/lib/asn1/oids.cpp new file mode 100644 index 0000000000..59ce08b357 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/asn1/oids.cpp @@ -0,0 +1,135 @@ +/* +* OID Registry +* (C) 1999-2008,2013 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include + +namespace Botan { + +namespace OIDS { + +namespace { + +class OID_Map + { + public: + void add_oid(const OID& oid, const std::string& str) + { + add_str2oid(oid, str); + add_oid2str(oid, str); + } + + void add_str2oid(const OID& oid, const std::string& str) + { + lock_guard_type lock(m_mutex); + auto i = m_str2oid.find(str); + if(i == m_str2oid.end()) + m_str2oid.insert(std::make_pair(str, oid.as_string())); + } + + void add_oid2str(const OID& oid, const std::string& str) + { + const std::string oid_str = oid.as_string(); + lock_guard_type lock(m_mutex); + auto i = m_oid2str.find(oid_str); + if(i == m_oid2str.end()) + m_oid2str.insert(std::make_pair(oid_str, str)); + } + + std::string lookup(const OID& oid) + { + const std::string oid_str = oid.as_string(); + + lock_guard_type lock(m_mutex); + + auto i = m_oid2str.find(oid_str); + if(i != m_oid2str.end()) + return i->second; + + return ""; + } + + OID lookup(const std::string& str) + { + lock_guard_type lock(m_mutex); + auto i = m_str2oid.find(str); + if(i != m_str2oid.end()) + return i->second; + + return OID(); + } + + bool have_oid(const std::string& str) + { + lock_guard_type lock(m_mutex); + return m_str2oid.find(str) != m_str2oid.end(); + } + + static OID_Map& global_registry() + { + static OID_Map g_map; + return g_map; + } + + private: + + OID_Map() + { + m_str2oid = load_str2oid_map(); + m_oid2str = load_oid2str_map(); + } + + mutex_type m_mutex; + std::unordered_map m_str2oid; + std::unordered_map m_oid2str; + }; + +} + +void add_oid(const OID& oid, const std::string& name) + { + OID_Map::global_registry().add_oid(oid, name); + } + +void add_oidstr(const char* oidstr, const char* name) + { + add_oid(OID(oidstr), name); + } + +void add_oid2str(const OID& oid, const std::string& name) + { + OID_Map::global_registry().add_oid2str(oid, name); + } + +void add_str2oid(const OID& oid, const std::string& name) + { + OID_Map::global_registry().add_str2oid(oid, name); + } + +std::string lookup(const OID& oid) + { + return OID_Map::global_registry().lookup(oid); + } + +OID lookup(const std::string& name) + { + return OID_Map::global_registry().lookup(name); + } + +bool have_oid(const std::string& name) + { + return OID_Map::global_registry().have_oid(name); + } + +bool name_of(const OID& oid, const std::string& name) + { + return (oid == lookup(name)); + } + +} + +} diff --git a/src/libs/3rdparty/botan/src/lib/asn1/oids.h b/src/libs/3rdparty/botan/src/lib/asn1/oids.h new file mode 100644 index 0000000000..7b87b5eafe --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/asn1/oids.h @@ -0,0 +1,76 @@ +/* +* OID Registry +* (C) 1999-2007 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_OIDS_H_ +#define BOTAN_OIDS_H_ + +#include +#include + +namespace Botan { + +namespace OIDS { + +/** +* Register an OID to string mapping. +* @param oid the oid to register +* @param name the name to be associated with the oid +*/ +BOTAN_UNSTABLE_API void add_oid(const OID& oid, const std::string& name); + +BOTAN_UNSTABLE_API void add_oid2str(const OID& oid, const std::string& name); +BOTAN_UNSTABLE_API void add_str2oid(const OID& oid, const std::string& name); + +BOTAN_UNSTABLE_API void add_oidstr(const char* oidstr, const char* name); + +std::unordered_map load_oid2str_map(); +std::unordered_map load_str2oid_map(); + +/** +* Resolve an OID +* @param oid the OID to look up +* @return name associated with this OID +*/ +BOTAN_PUBLIC_API(2,0) std::string lookup(const OID& oid); + +/** +* Find the OID to a name. The lookup will be performed in the +* general OID section of the configuration. +* @param name the name to resolve +* @return OID associated with the specified name +*/ +BOTAN_PUBLIC_API(2,0) OID lookup(const std::string& name); + +inline std::string oid2str(const OID& oid) + { + return lookup(oid); + } + +inline OID str2oid(const std::string& name) + { + return lookup(name); + } + +/** +* See if an OID exists in the internal table. +* @param oid the oid to check for +* @return true if the oid is registered +*/ +BOTAN_UNSTABLE_API bool have_oid(const std::string& oid); + +/** +* Tests whether the specified OID stands for the specified name. +* @param oid the OID to check +* @param name the name to check +* @return true if the specified OID stands for the specified name +*/ +BOTAN_UNSTABLE_API bool name_of(const OID& oid, const std::string& name); +} + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/base/botan.h b/src/libs/3rdparty/botan/src/lib/base/botan.h new file mode 100644 index 0000000000..26bfa75a79 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/base/botan.h @@ -0,0 +1,45 @@ +/* +* A vague catch all include file for Botan +* (C) 1999-2007 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_BOTAN_H_ +#define BOTAN_BOTAN_H_ + +/* +* There is no real reason for this header to exist beyond historical +* reasons. The application should instead include the specific header +* files that define the interfaces it intends to use. +* +* This header file will be removed in Botan 3.x +*/ + +#if defined(__GNUC__) + #warning "botan/botan.h is deprecated" +#elif defined(_MSC_VER) + #pragma message ("botan/botan.h is deprecated") +#endif + +#include +#include +#include +#include +#include +#include + +#if defined(BOTAN_HAS_AUTO_SEEDING_RNG) + #include +#endif + +#if defined(BOTAN_HAS_FILTERS) + #include +#endif + +#if defined(BOTAN_HAS_PUBLIC_KEY_CRYPTO) + #include + #include +#endif + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/base/buf_comp.h b/src/libs/3rdparty/botan/src/lib/base/buf_comp.h new file mode 100644 index 0000000000..a6cc84ba35 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/base/buf_comp.h @@ -0,0 +1,184 @@ +/* +* Buffered Computation +* (C) 1999-2007 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_BUFFERED_COMPUTATION_H_ +#define BOTAN_BUFFERED_COMPUTATION_H_ + +#include +#include +#include + +namespace Botan { + +/** +* This class represents any kind of computation which uses an internal +* state, such as hash functions or MACs +*/ +class BOTAN_PUBLIC_API(2,0) Buffered_Computation + { + public: + /** + * @return length of the output of this function in bytes + */ + virtual size_t output_length() const = 0; + + /** + * Add new input to process. + * @param in the input to process as a byte array + * @param length of param in in bytes + */ + void update(const uint8_t in[], size_t length) { add_data(in, length); } + + /** + * Add new input to process. + * @param in the input to process as a secure_vector + */ + void update(const secure_vector& in) + { + add_data(in.data(), in.size()); + } + + /** + * Add new input to process. + * @param in the input to process as a std::vector + */ + void update(const std::vector& in) + { + add_data(in.data(), in.size()); + } + + /** + * Add an integer in big-endian order + * @param in the value + */ + template void update_be(const T in) + { + for(size_t i = 0; i != sizeof(T); ++i) + { + uint8_t b = get_byte(i, in); + add_data(&b, 1); + } + } + + /** + * Add new input to process. + * @param str the input to process as a std::string. Will be interpreted + * as a byte array based on the strings encoding. + */ + void update(const std::string& str) + { + add_data(cast_char_ptr_to_uint8(str.data()), str.size()); + } + + /** + * Process a single byte. + * @param in the byte to process + */ + void update(uint8_t in) { add_data(&in, 1); } + + /** + * Complete the computation and retrieve the + * final result. + * @param out The byte array to be filled with the result. + * Must be of length output_length() + */ + void final(uint8_t out[]) { final_result(out); } + + /** + * Complete the computation and retrieve the + * final result. + * @return secure_vector holding the result + */ + secure_vector final() + { + secure_vector output(output_length()); + final_result(output.data()); + return output; + } + + std::vector final_stdvec() + { + std::vector output(output_length()); + final_result(output.data()); + return output; + } + + template + void final(std::vector& out) + { + out.resize(output_length()); + final_result(out.data()); + } + + /** + * Update and finalize computation. Does the same as calling update() + * and final() consecutively. + * @param in the input to process as a byte array + * @param length the length of the byte array + * @result the result of the call to final() + */ + secure_vector process(const uint8_t in[], size_t length) + { + add_data(in, length); + return final(); + } + + /** + * Update and finalize computation. Does the same as calling update() + * and final() consecutively. + * @param in the input to process + * @result the result of the call to final() + */ + secure_vector process(const secure_vector& in) + { + add_data(in.data(), in.size()); + return final(); + } + + /** + * Update and finalize computation. Does the same as calling update() + * and final() consecutively. + * @param in the input to process + * @result the result of the call to final() + */ + secure_vector process(const std::vector& in) + { + add_data(in.data(), in.size()); + return final(); + } + + /** + * Update and finalize computation. Does the same as calling update() + * and final() consecutively. + * @param in the input to process as a string + * @result the result of the call to final() + */ + secure_vector process(const std::string& in) + { + update(in); + return final(); + } + + virtual ~Buffered_Computation() = default; + private: + /** + * Add more data to the computation + * @param input is an input buffer + * @param length is the length of input in bytes + */ + virtual void add_data(const uint8_t input[], size_t length) = 0; + + /** + * Write the final output to out + * @param out is an output buffer of output_length() + */ + virtual void final_result(uint8_t out[]) = 0; + }; + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/base/info.txt b/src/libs/3rdparty/botan/src/lib/base/info.txt new file mode 100644 index 0000000000..fd3f7b8905 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/base/info.txt @@ -0,0 +1,17 @@ + +botan.h +buf_comp.h +init.h +key_spec.h +lookup.h +secmem.h +scan_name.h +sym_algo.h +symkey.h + + + +hex +rng +utils + diff --git a/src/libs/3rdparty/botan/src/lib/base/init.h b/src/libs/3rdparty/botan/src/lib/base/init.h new file mode 100644 index 0000000000..ba014d8e1d --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/base/init.h @@ -0,0 +1,33 @@ +/* +* Library Initialization +* (C) 1999-2008,2015 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_LIBRARY_INITIALIZER_H_ +#define BOTAN_LIBRARY_INITIALIZER_H_ + +#include +#include + +namespace Botan { + +/* +* Previously botan had state whose lifetime had to be explicitly +* managed by the application. As of 1.11.14 this is no longer the +* case, and this class is no longer needed and kept only for backwards +* compatibility. +*/ +class BOTAN_PUBLIC_API(2,0) BOTAN_DEPRECATED("LibraryInitializer is no longer required") LibraryInitializer final + { + public: + explicit LibraryInitializer(const std::string& /*ignored*/ = "") { } + + static void initialize(const std::string& /*ignored*/ = "") {} + static void deinitialize() {} + }; + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/base/key_spec.h b/src/libs/3rdparty/botan/src/lib/base/key_spec.h new file mode 100644 index 0000000000..6db20a9b63 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/base/key_spec.h @@ -0,0 +1,100 @@ +/* +* Symmetric Key Length Specification +* (C) 2010 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_KEY_LEN_SPECIFICATION_H_ +#define BOTAN_KEY_LEN_SPECIFICATION_H_ + +#include + +namespace Botan { + +/** +* Represents the length requirements on an algorithm key +*/ +class BOTAN_PUBLIC_API(2,0) Key_Length_Specification final + { + public: + /** + * Constructor for fixed length keys + * @param keylen the supported key length + */ + explicit Key_Length_Specification(size_t keylen) : + m_min_keylen(keylen), + m_max_keylen(keylen), + m_keylen_mod(1) + { + } + + /** + * Constructor for variable length keys + * @param min_k the smallest supported key length + * @param max_k the largest supported key length + * @param k_mod the number of bytes the key must be a multiple of + */ + Key_Length_Specification(size_t min_k, + size_t max_k, + size_t k_mod = 1) : + m_min_keylen(min_k), + m_max_keylen(max_k ? max_k : min_k), + m_keylen_mod(k_mod) + { + } + + /** + * @param length is a key length in bytes + * @return true iff this length is a valid length for this algo + */ + bool valid_keylength(size_t length) const + { + return ((length >= m_min_keylen) && + (length <= m_max_keylen) && + (length % m_keylen_mod == 0)); + } + + /** + * @return minimum key length in bytes + */ + size_t minimum_keylength() const + { + return m_min_keylen; + } + + /** + * @return maximum key length in bytes + */ + size_t maximum_keylength() const + { + return m_max_keylen; + } + + /** + * @return key length multiple in bytes + */ + size_t keylength_multiple() const + { + return m_keylen_mod; + } + + /* + * Multiplies all length requirements with the given factor + * @param n the multiplication factor + * @return a key length specification multiplied by the factor + */ + Key_Length_Specification multiple(size_t n) const + { + return Key_Length_Specification(n * m_min_keylen, + n * m_max_keylen, + n * m_keylen_mod); + } + + private: + size_t m_min_keylen, m_max_keylen, m_keylen_mod; + }; + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/base/lookup.h b/src/libs/3rdparty/botan/src/lib/base/lookup.h new file mode 100644 index 0000000000..1cfa7d3c9c --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/base/lookup.h @@ -0,0 +1,177 @@ +/* +* Algorithm Lookup +* (C) 1999-2007,2015 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_LOOKUP_H_ +#define BOTAN_LOOKUP_H_ + +#include +#include +#include +#include +#include + +#if defined(BOTAN_HAS_BLOCK_CIPHER) + #include +#endif + +#if defined(BOTAN_HAS_STREAM_CIPHER) + #include +#endif + +#if defined(BOTAN_HAS_HASH) + #include +#endif + +#if defined(BOTAN_HAS_MAC) + #include +#endif + +namespace Botan { + +/* +* As of 1.11.26 this header is deprecated. Instead use the calls T::create and +* T::providers (as demonstrated in the implementation below). +*/ + +/* +* Get an algorithm object +* NOTE: these functions create and return new objects, letting the +* caller assume ownership of them +*/ + +#if defined(BOTAN_HAS_BLOCK_CIPHER) + +/** +* Block cipher factory method. +* +* @param algo_spec the name of the desired block cipher +* @param provider the provider to use +* @return pointer to the block cipher object +*/ +BOTAN_DEPRECATED("Use BlockCipher::create") +inline BlockCipher* get_block_cipher(const std::string& algo_spec, + const std::string& provider = "") + { + return BlockCipher::create(algo_spec, provider).release(); + } + +BOTAN_DEPRECATED("Use BlockCipher::create_or_throw") +inline std::unique_ptr make_block_cipher(const std::string& algo_spec, + const std::string& provider = "") + { + return BlockCipher::create_or_throw(algo_spec, provider); + } + +BOTAN_DEPRECATED("Use BlockCipher::providers") +inline std::vector get_block_cipher_providers(const std::string& algo_spec) + { + return BlockCipher::providers(algo_spec); + } + +#endif + +#if defined(BOTAN_HAS_STREAM_CIPHER) + +/** +* Stream cipher factory method. +* +* @param algo_spec the name of the desired stream cipher +* @param provider the provider to use +* @return pointer to the stream cipher object +*/ +BOTAN_DEPRECATED("Use StreamCipher::create") +inline StreamCipher* get_stream_cipher(const std::string& algo_spec, + const std::string& provider = "") + { + return StreamCipher::create(algo_spec, provider).release(); + } + +BOTAN_DEPRECATED("Use StreamCipher::create_or_throw") +inline std::unique_ptr make_stream_cipher(const std::string& algo_spec, + const std::string& provider = "") + { + return StreamCipher::create_or_throw(algo_spec, provider); + } + +BOTAN_DEPRECATED("Use StreamCipher::providers") +inline std::vector get_stream_cipher_providers(const std::string& algo_spec) + { + return StreamCipher::providers(algo_spec); + } + +#endif + +#if defined(BOTAN_HAS_HASH) + +/** +* Hash function factory method. +* +* @param algo_spec the name of the desired hash function +* @param provider the provider to use +* @return pointer to the hash function object +*/ +BOTAN_DEPRECATED("Use HashFunction::create") +inline HashFunction* get_hash_function(const std::string& algo_spec, + const std::string& provider = "") + { + return HashFunction::create(algo_spec, provider).release(); + } + +BOTAN_DEPRECATED("Use HashFunction::create_or_throw") +inline std::unique_ptr make_hash_function(const std::string& algo_spec, + const std::string& provider = "") + { + return HashFunction::create_or_throw(algo_spec, provider); + } + +BOTAN_DEPRECATED("Use HashFunction::create") +inline HashFunction* get_hash(const std::string& algo_spec, + const std::string& provider = "") + { + return HashFunction::create(algo_spec, provider).release(); + } + +BOTAN_DEPRECATED("Use HashFunction::providers") +inline std::vector get_hash_function_providers(const std::string& algo_spec) + { + return HashFunction::providers(algo_spec); + } + +#endif + +#if defined(BOTAN_HAS_MAC) +/** +* MAC factory method. +* +* @param algo_spec the name of the desired MAC +* @param provider the provider to use +* @return pointer to the MAC object +*/ +BOTAN_DEPRECATED("MessageAuthenticationCode::create") +inline MessageAuthenticationCode* get_mac(const std::string& algo_spec, + const std::string& provider = "") + { + return MessageAuthenticationCode::create(algo_spec, provider).release(); + } + +BOTAN_DEPRECATED("MessageAuthenticationCode::create_or_throw") +inline std::unique_ptr make_message_auth(const std::string& algo_spec, + const std::string& provider = "") + { + return MessageAuthenticationCode::create(algo_spec, provider); + } + +BOTAN_DEPRECATED("MessageAuthenticationCode::providers") +inline std::vector get_mac_providers(const std::string& algo_spec) + { + return MessageAuthenticationCode::providers(algo_spec); + } +#endif + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/base/scan_name.cpp b/src/libs/3rdparty/botan/src/lib/base/scan_name.cpp new file mode 100644 index 0000000000..70c6e7f25c --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/base/scan_name.cpp @@ -0,0 +1,144 @@ +/* +* SCAN Name Abstraction +* (C) 2008-2009,2015 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include + +namespace Botan { + +namespace { + +std::string make_arg( + const std::vector >& name, size_t start) + { + std::string output = name[start].second; + size_t level = name[start].first; + + size_t paren_depth = 0; + + for(size_t i = start + 1; i != name.size(); ++i) + { + if(name[i].first <= name[start].first) + break; + + if(name[i].first > level) + { + output += "(" + name[i].second; + ++paren_depth; + } + else if(name[i].first < level) + { + output += ")," + name[i].second; + --paren_depth; + } + else + { + if(output[output.size() - 1] != '(') + output += ","; + output += name[i].second; + } + + level = name[i].first; + } + + for(size_t i = 0; i != paren_depth; ++i) + output += ")"; + + return output; + } + +} + +SCAN_Name::SCAN_Name(const char* algo_spec) : SCAN_Name(std::string(algo_spec)) + { + } + +SCAN_Name::SCAN_Name(std::string algo_spec) : m_orig_algo_spec(algo_spec), m_alg_name(), m_args(), m_mode_info() + { + std::vector > name; + size_t level = 0; + std::pair accum = std::make_pair(level, ""); + + const std::string decoding_error = "Bad SCAN name '" + algo_spec + "': "; + + for(size_t i = 0; i != algo_spec.size(); ++i) + { + char c = algo_spec[i]; + + if(c == '/' || c == ',' || c == '(' || c == ')') + { + if(c == '(') + ++level; + else if(c == ')') + { + if(level == 0) + throw Decoding_Error(decoding_error + "Mismatched parens"); + --level; + } + + if(c == '/' && level > 0) + accum.second.push_back(c); + else + { + if(accum.second != "") + name.push_back(accum); + accum = std::make_pair(level, ""); + } + } + else + accum.second.push_back(c); + } + + if(accum.second != "") + name.push_back(accum); + + if(level != 0) + throw Decoding_Error(decoding_error + "Missing close paren"); + + if(name.size() == 0) + throw Decoding_Error(decoding_error + "Empty name"); + + m_alg_name = name[0].second; + + bool in_modes = false; + + for(size_t i = 1; i != name.size(); ++i) + { + if(name[i].first == 0) + { + m_mode_info.push_back(make_arg(name, i)); + in_modes = true; + } + else if(name[i].first == 1 && !in_modes) + m_args.push_back(make_arg(name, i)); + } + } + +std::string SCAN_Name::arg(size_t i) const + { + if(i >= arg_count()) + throw Invalid_Argument("SCAN_Name::arg " + std::to_string(i) + + " out of range for '" + as_string() + "'"); + return m_args[i]; + } + +std::string SCAN_Name::arg(size_t i, const std::string& def_value) const + { + if(i >= arg_count()) + return def_value; + return m_args[i]; + } + +size_t SCAN_Name::arg_as_integer(size_t i, size_t def_value) const + { + if(i >= arg_count()) + return def_value; + return to_u32bit(m_args[i]); + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/base/scan_name.h b/src/libs/3rdparty/botan/src/lib/base/scan_name.h new file mode 100644 index 0000000000..8aa45f50f0 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/base/scan_name.h @@ -0,0 +1,117 @@ +/* +* SCAN Name Abstraction +* (C) 2008,2015 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_SCAN_NAME_H_ +#define BOTAN_SCAN_NAME_H_ + +#include +#include +#include + +namespace Botan { + +/** +A class encapsulating a SCAN name (similar to JCE conventions) +http://www.users.zetnet.co.uk/hopwood/crypto/scan/ +*/ +class BOTAN_PUBLIC_API(2,0) SCAN_Name final + { + public: + /** + * Create a SCAN_Name + * @param algo_spec A SCAN-format name + */ + explicit SCAN_Name(const char* algo_spec); + + /** + * Create a SCAN_Name + * @param algo_spec A SCAN-format name + */ + explicit SCAN_Name(std::string algo_spec); + + /** + * @return original input string + */ + const std::string& as_string() const { return m_orig_algo_spec; } + + /** + * @return algorithm name + */ + const std::string& algo_name() const { return m_alg_name; } + + /** + * @return number of arguments + */ + size_t arg_count() const { return m_args.size(); } + + /** + * @param lower is the lower bound + * @param upper is the upper bound + * @return if the number of arguments is between lower and upper + */ + bool arg_count_between(size_t lower, size_t upper) const + { return ((arg_count() >= lower) && (arg_count() <= upper)); } + + /** + * @param i which argument + * @return ith argument + */ + std::string arg(size_t i) const; + + /** + * @param i which argument + * @param def_value the default value + * @return ith argument or the default value + */ + std::string arg(size_t i, const std::string& def_value) const; + + /** + * @param i which argument + * @param def_value the default value + * @return ith argument as an integer, or the default value + */ + size_t arg_as_integer(size_t i, size_t def_value) const; + + /** + * @return cipher mode (if any) + */ + std::string cipher_mode() const + { return (m_mode_info.size() >= 1) ? m_mode_info[0] : ""; } + + /** + * @return cipher mode padding (if any) + */ + std::string cipher_mode_pad() const + { return (m_mode_info.size() >= 2) ? m_mode_info[1] : ""; } + + private: + std::string m_orig_algo_spec; + std::string m_alg_name; + std::vector m_args; + std::vector m_mode_info; + }; + +// This is unrelated but it is convenient to stash it here +template +std::vector probe_providers_of(const std::string& algo_spec, + const std::vector& possible) + { + std::vector providers; + for(auto&& prov : possible) + { + std::unique_ptr o(T::create(algo_spec, prov)); + if(o) + { + providers.push_back(prov); // available + } + } + return providers; + } + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/base/secmem.h b/src/libs/3rdparty/botan/src/lib/base/secmem.h new file mode 100644 index 0000000000..12ea55a3b6 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/base/secmem.h @@ -0,0 +1,202 @@ +/* +* Secure Memory Buffers +* (C) 1999-2007,2012 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_SECURE_MEMORY_BUFFERS_H_ +#define BOTAN_SECURE_MEMORY_BUFFERS_H_ + +#include // IWYU pragma: export +#include // IWYU pragma: export +#include // IWYU pragma: export +#include +#include +#include + +namespace Botan { + +template +class secure_allocator + { + public: + /* + * Assert exists to prevent someone from doing something that will + * probably crash anyway (like secure_vector where ~non_POD_t + * deletes a member pointer which was zeroed before it ran). + * MSVC in debug mode uses non-integral proxy types in container types + * like std::vector, thus we disable the check there. + */ +#if !defined(_ITERATOR_DEBUG_LEVEL) || _ITERATOR_DEBUG_LEVEL == 0 + static_assert(std::is_integral::value, "secure_allocator supports only integer types"); +#endif + + typedef T value_type; + typedef std::size_t size_type; + +#ifdef BOTAN_BUILD_COMPILER_IS_MSVC_2013 + secure_allocator() = default; + secure_allocator(const secure_allocator&) = default; + secure_allocator& operator=(const secure_allocator&) = default; + ~secure_allocator() = default; + + template + struct rebind + { + typedef secure_allocator other; + }; + + void construct(value_type* mem, const value_type& value) + { + std::_Construct(mem, value); + } + + void destroy(value_type* mem) + { + std::_Destroy(mem); + } +#else + secure_allocator() BOTAN_NOEXCEPT = default; + secure_allocator(const secure_allocator&) BOTAN_NOEXCEPT = default; + secure_allocator& operator=(const secure_allocator&) BOTAN_NOEXCEPT = default; + ~secure_allocator() BOTAN_NOEXCEPT = default; +#endif + + template + secure_allocator(const secure_allocator&) BOTAN_NOEXCEPT {} + + T* allocate(std::size_t n) + { + return static_cast(allocate_memory(n, sizeof(T))); + } + + void deallocate(T* p, std::size_t n) + { + deallocate_memory(p, n, sizeof(T)); + } + }; + +template inline bool +operator==(const secure_allocator&, const secure_allocator&) + { return true; } + +template inline bool +operator!=(const secure_allocator&, const secure_allocator&) + { return false; } + +template using secure_vector = std::vector>; +template using secure_deque = std::deque>; + +// For better compatability with 1.10 API +template using SecureVector = secure_vector; + +template +std::vector unlock(const secure_vector& in) + { + std::vector out(in.size()); + copy_mem(out.data(), in.data(), in.size()); + return out; + } + +template +size_t buffer_insert(std::vector& buf, + size_t buf_offset, + const T input[], + size_t input_length) + { + BOTAN_ASSERT_NOMSG(buf_offset <= buf.size()); + const size_t to_copy = std::min(input_length, buf.size() - buf_offset); + if(to_copy > 0) + { + copy_mem(&buf[buf_offset], input, to_copy); + } + return to_copy; + } + +template +size_t buffer_insert(std::vector& buf, + size_t buf_offset, + const std::vector& input) + { + BOTAN_ASSERT_NOMSG(buf_offset <= buf.size()); + const size_t to_copy = std::min(input.size(), buf.size() - buf_offset); + if(to_copy > 0) + { + copy_mem(&buf[buf_offset], input.data(), to_copy); + } + return to_copy; + } + +template +std::vector& +operator+=(std::vector& out, + const std::vector& in) + { + const size_t copy_offset = out.size(); + out.resize(out.size() + in.size()); + if(in.size() > 0) + { + copy_mem(&out[copy_offset], in.data(), in.size()); + } + return out; + } + +template +std::vector& operator+=(std::vector& out, T in) + { + out.push_back(in); + return out; + } + +template +std::vector& operator+=(std::vector& out, + const std::pair& in) + { + const size_t copy_offset = out.size(); + out.resize(out.size() + in.second); + if(in.second > 0) + { + copy_mem(&out[copy_offset], in.first, in.second); + } + return out; + } + +template +std::vector& operator+=(std::vector& out, + const std::pair& in) + { + const size_t copy_offset = out.size(); + out.resize(out.size() + in.second); + if(in.second > 0) + { + copy_mem(&out[copy_offset], in.first, in.second); + } + return out; + } + +/** +* Zeroise the values; length remains unchanged +* @param vec the vector to zeroise +*/ +template +void zeroise(std::vector& vec) + { + clear_mem(vec.data(), vec.size()); + } + +/** +* Zeroise the values then free the memory +* @param vec the vector to zeroise and free +*/ +template +void zap(std::vector& vec) + { + zeroise(vec); + vec.clear(); + vec.shrink_to_fit(); + } + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/base/sym_algo.cpp b/src/libs/3rdparty/botan/src/lib/base/sym_algo.cpp new file mode 100644 index 0000000000..fff4afbd14 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/base/sym_algo.cpp @@ -0,0 +1,24 @@ +/* +* (C) 2018 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include + +namespace Botan { + +void SymmetricAlgorithm::throw_key_not_set_error() const + { + throw Key_Not_Set(name()); + } + +void SymmetricAlgorithm::set_key(const uint8_t key[], size_t length) + { + if(!valid_keylength(length)) + throw Invalid_Key_Length(name(), length); + key_schedule(key, length); + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/base/sym_algo.h b/src/libs/3rdparty/botan/src/lib/base/sym_algo.h new file mode 100644 index 0000000000..e69d4f81eb --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/base/sym_algo.h @@ -0,0 +1,108 @@ +/* +* Symmetric Algorithm Base Class +* (C) 1999-2007 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_SYMMETRIC_ALGORITHM_H_ +#define BOTAN_SYMMETRIC_ALGORITHM_H_ + +#include +#include +#include + +namespace Botan { + +/** +* This class represents a symmetric algorithm object. +*/ +class BOTAN_PUBLIC_API(2,0) SymmetricAlgorithm + { + public: + virtual ~SymmetricAlgorithm() = default; + + /** + * Reset the state. + */ + virtual void clear() = 0; + + /** + * @return object describing limits on key size + */ + virtual Key_Length_Specification key_spec() const = 0; + + /** + * @return minimum allowed key length + */ + size_t maximum_keylength() const + { + return key_spec().maximum_keylength(); + } + + /** + * @return maximum allowed key length + */ + size_t minimum_keylength() const + { + return key_spec().minimum_keylength(); + } + + /** + * 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 object. + * @param key the SymmetricKey to be set. + */ + void set_key(const SymmetricKey& key) + { + set_key(key.begin(), key.length()); + } + + template + void set_key(const std::vector& key) + { + set_key(key.data(), key.size()); + } + + /** + * Set the symmetric key of this object. + * @param key the to be set as a byte array. + * @param length in bytes of key param + */ + void set_key(const uint8_t key[], size_t length); + + /** + * @return the algorithm name + */ + virtual std::string name() const = 0; + + protected: + void verify_key_set(bool cond) const + { + if(cond == false) + throw_key_not_set_error(); + } + + private: + void throw_key_not_set_error() const; + + /** + * Run the key schedule + * @param key the key + * @param length of key + */ + virtual void key_schedule(const uint8_t key[], size_t length) = 0; + }; + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/base/symkey.cpp b/src/libs/3rdparty/botan/src/lib/base/symkey.cpp new file mode 100644 index 0000000000..a012773ff3 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/base/symkey.cpp @@ -0,0 +1,131 @@ +/* +* OctetString +* (C) 1999-2007 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include + +namespace Botan { + +/* +* Create an OctetString from RNG output +*/ +OctetString::OctetString(RandomNumberGenerator& rng, + size_t len) + { + m_data = rng.random_vec(len); + } + +/* +* Create an OctetString from a hex string +*/ +OctetString::OctetString(const std::string& hex_string) + { + m_data.resize(1 + hex_string.length() / 2); + m_data.resize(hex_decode(m_data.data(), hex_string)); + } + +/* +* Create an OctetString from a byte string +*/ +OctetString::OctetString(const uint8_t in[], size_t n) + { + m_data.assign(in, in + n); + } + +/* +* Set the parity of each key byte to odd +*/ +void OctetString::set_odd_parity() + { + const uint8_t ODD_PARITY[256] = { + 0x01, 0x01, 0x02, 0x02, 0x04, 0x04, 0x07, 0x07, 0x08, 0x08, 0x0B, 0x0B, + 0x0D, 0x0D, 0x0E, 0x0E, 0x10, 0x10, 0x13, 0x13, 0x15, 0x15, 0x16, 0x16, + 0x19, 0x19, 0x1A, 0x1A, 0x1C, 0x1C, 0x1F, 0x1F, 0x20, 0x20, 0x23, 0x23, + 0x25, 0x25, 0x26, 0x26, 0x29, 0x29, 0x2A, 0x2A, 0x2C, 0x2C, 0x2F, 0x2F, + 0x31, 0x31, 0x32, 0x32, 0x34, 0x34, 0x37, 0x37, 0x38, 0x38, 0x3B, 0x3B, + 0x3D, 0x3D, 0x3E, 0x3E, 0x40, 0x40, 0x43, 0x43, 0x45, 0x45, 0x46, 0x46, + 0x49, 0x49, 0x4A, 0x4A, 0x4C, 0x4C, 0x4F, 0x4F, 0x51, 0x51, 0x52, 0x52, + 0x54, 0x54, 0x57, 0x57, 0x58, 0x58, 0x5B, 0x5B, 0x5D, 0x5D, 0x5E, 0x5E, + 0x61, 0x61, 0x62, 0x62, 0x64, 0x64, 0x67, 0x67, 0x68, 0x68, 0x6B, 0x6B, + 0x6D, 0x6D, 0x6E, 0x6E, 0x70, 0x70, 0x73, 0x73, 0x75, 0x75, 0x76, 0x76, + 0x79, 0x79, 0x7A, 0x7A, 0x7C, 0x7C, 0x7F, 0x7F, 0x80, 0x80, 0x83, 0x83, + 0x85, 0x85, 0x86, 0x86, 0x89, 0x89, 0x8A, 0x8A, 0x8C, 0x8C, 0x8F, 0x8F, + 0x91, 0x91, 0x92, 0x92, 0x94, 0x94, 0x97, 0x97, 0x98, 0x98, 0x9B, 0x9B, + 0x9D, 0x9D, 0x9E, 0x9E, 0xA1, 0xA1, 0xA2, 0xA2, 0xA4, 0xA4, 0xA7, 0xA7, + 0xA8, 0xA8, 0xAB, 0xAB, 0xAD, 0xAD, 0xAE, 0xAE, 0xB0, 0xB0, 0xB3, 0xB3, + 0xB5, 0xB5, 0xB6, 0xB6, 0xB9, 0xB9, 0xBA, 0xBA, 0xBC, 0xBC, 0xBF, 0xBF, + 0xC1, 0xC1, 0xC2, 0xC2, 0xC4, 0xC4, 0xC7, 0xC7, 0xC8, 0xC8, 0xCB, 0xCB, + 0xCD, 0xCD, 0xCE, 0xCE, 0xD0, 0xD0, 0xD3, 0xD3, 0xD5, 0xD5, 0xD6, 0xD6, + 0xD9, 0xD9, 0xDA, 0xDA, 0xDC, 0xDC, 0xDF, 0xDF, 0xE0, 0xE0, 0xE3, 0xE3, + 0xE5, 0xE5, 0xE6, 0xE6, 0xE9, 0xE9, 0xEA, 0xEA, 0xEC, 0xEC, 0xEF, 0xEF, + 0xF1, 0xF1, 0xF2, 0xF2, 0xF4, 0xF4, 0xF7, 0xF7, 0xF8, 0xF8, 0xFB, 0xFB, + 0xFD, 0xFD, 0xFE, 0xFE }; + + for(size_t j = 0; j != m_data.size(); ++j) + m_data[j] = ODD_PARITY[m_data[j]]; + } + +/* +* Hex encode an OctetString +*/ +std::string OctetString::as_string() const + { + return hex_encode(m_data.data(), m_data.size()); + } + +/* +* XOR Operation for OctetStrings +*/ +OctetString& OctetString::operator^=(const OctetString& k) + { + if(&k == this) { zeroise(m_data); return (*this); } + xor_buf(m_data.data(), k.begin(), std::min(length(), k.length())); + return (*this); + } + +/* +* Equality Operation for OctetStrings +*/ +bool operator==(const OctetString& s1, const OctetString& s2) + { + return (s1.bits_of() == s2.bits_of()); + } + +/* +* Unequality Operation for OctetStrings +*/ +bool operator!=(const OctetString& s1, const OctetString& s2) + { + return !(s1 == s2); + } + +/* +* Append Operation for OctetStrings +*/ +OctetString operator+(const OctetString& k1, const OctetString& k2) + { + secure_vector out; + out += k1.bits_of(); + out += k2.bits_of(); + return OctetString(out); + } + +/* +* XOR Operation for OctetStrings +*/ +OctetString operator^(const OctetString& k1, const OctetString& k2) + { + secure_vector out(std::max(k1.length(), k2.length())); + + copy_mem(out.data(), k1.begin(), k1.length()); + xor_buf(out.data(), k2.begin(), k2.length()); + return OctetString(out); + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/base/symkey.h b/src/libs/3rdparty/botan/src/lib/base/symkey.h new file mode 100644 index 0000000000..a010cc4664 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/base/symkey.h @@ -0,0 +1,145 @@ +/* +* OctetString +* (C) 1999-2007 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_SYMKEY_H_ +#define BOTAN_SYMKEY_H_ + +#include +#include + +namespace Botan { + +/** +* Octet String +*/ +class BOTAN_PUBLIC_API(2,0) OctetString final + { + public: + /** + * @return size of this octet string in bytes + */ + size_t length() const { return m_data.size(); } + size_t size() const { return m_data.size(); } + + /** + * @return this object as a secure_vector + */ + secure_vector bits_of() const { return m_data; } + + /** + * @return start of this string + */ + const uint8_t* begin() const { return m_data.data(); } + + /** + * @return end of this string + */ + const uint8_t* end() const { return begin() + m_data.size(); } + + /** + * @return this encoded as hex + */ + std::string as_string() const; + + /** + * XOR the contents of another octet string into this one + * @param other octet string + * @return reference to this + */ + OctetString& operator^=(const OctetString& other); + + /** + * Force to have odd parity + */ + void set_odd_parity(); + + /** + * Create a new OctetString + * @param str is a hex encoded string + */ + explicit OctetString(const std::string& str = ""); + + /** + * Create a new random OctetString + * @param rng is a random number generator + * @param len is the desired length in bytes + */ + OctetString(class RandomNumberGenerator& rng, size_t len); + + /** + * Create a new OctetString + * @param in is an array + * @param len is the length of in in bytes + */ + OctetString(const uint8_t in[], size_t len); + + /** + * Create a new OctetString + * @param in a bytestring + */ + OctetString(const secure_vector& in) : m_data(in) {} + + /** + * Create a new OctetString + * @param in a bytestring + */ + OctetString(const std::vector& in) : m_data(in.begin(), in.end()) {} + + private: + secure_vector m_data; + }; + +/** +* Compare two strings +* @param x an octet string +* @param y an octet string +* @return if x is equal to y +*/ +BOTAN_PUBLIC_API(2,0) bool operator==(const OctetString& x, + const OctetString& y); + +/** +* Compare two strings +* @param x an octet string +* @param y an octet string +* @return if x is not equal to y +*/ +BOTAN_PUBLIC_API(2,0) bool operator!=(const OctetString& x, + const OctetString& y); + +/** +* Concatenate two strings +* @param x an octet string +* @param y an octet string +* @return x concatenated with y +*/ +BOTAN_PUBLIC_API(2,0) OctetString operator+(const OctetString& x, + const OctetString& y); + +/** +* XOR two strings +* @param x an octet string +* @param y an octet string +* @return x XORed with y +*/ +BOTAN_PUBLIC_API(2,0) OctetString operator^(const OctetString& x, + const OctetString& y); + + +/** +* Alternate name for octet string showing intent to use as a key +*/ +using SymmetricKey = OctetString; + +/** +* Alternate name for octet string showing intent to use as an IV +*/ +using InitializationVector = OctetString; + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/block/aes/aes.cpp b/src/libs/3rdparty/botan/src/lib/block/aes/aes.cpp new file mode 100644 index 0000000000..403945cc91 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/block/aes/aes.cpp @@ -0,0 +1,750 @@ +/* +* AES +* (C) 1999-2010,2015,2017 Jack Lloyd +* +* Based on the public domain reference implementation by Paulo Baretto +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include + +/* +* This implementation is based on table lookups which are known to be +* vulnerable to timing and cache based side channel attacks. Some +* 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. +* +* - 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. +* +* - Each cache line of the lookup tables is accessed at the beginning +* of each call to encrypt or decrypt. (See the Z variable below) +* +* If available SSSE3 or AES-NI are used instead of this version, as both +* are faster and immune to side channel attacks. +* +* Some AES cache timing papers for reference: +* +* "Software mitigations to hedge AES against cache-based software side +* channel vulnerabilities" https://eprint.iacr.org/2006/052.pdf +* +* "Cache Games - Bringing Access-Based Cache Attacks on AES to Practice" +* http://www.ieee-security.org/TC/SP2011/PAPERS/2011/paper031.pdf +* +* "Cache-Collision Timing Attacks Against AES" Bonneau, Mironov +* http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.88.4753 +*/ + +namespace Botan { + +namespace { + +BOTAN_ALIGNAS(64) +const uint8_t SE[256] = { + 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, + 0xFE, 0xD7, 0xAB, 0x76, 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, + 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, 0xB7, 0xFD, 0x93, 0x26, + 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, + 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, + 0xEB, 0x27, 0xB2, 0x75, 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, + 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, 0x53, 0xD1, 0x00, 0xED, + 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, + 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, + 0x50, 0x3C, 0x9F, 0xA8, 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, + 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, 0xCD, 0x0C, 0x13, 0xEC, + 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73, + 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, + 0xDE, 0x5E, 0x0B, 0xDB, 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, + 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, 0xE7, 0xC8, 0x37, 0x6D, + 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08, + 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, + 0x4B, 0xBD, 0x8B, 0x8A, 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, + 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, 0xE1, 0xF8, 0x98, 0x11, + 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF, + 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, + 0xB0, 0x54, 0xBB, 0x16 }; + +BOTAN_ALIGNAS(64) +const uint8_t SD[256] = { + 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, + 0x81, 0xF3, 0xD7, 0xFB, 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, + 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB, 0x54, 0x7B, 0x94, 0x32, + 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E, + 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, + 0x6D, 0x8B, 0xD1, 0x25, 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, + 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92, 0x6C, 0x70, 0x48, 0x50, + 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84, + 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, + 0xB8, 0xB3, 0x45, 0x06, 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, + 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B, 0x3A, 0x91, 0x11, 0x41, + 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73, + 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, + 0x1C, 0x75, 0xDF, 0x6E, 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, + 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B, 0xFC, 0x56, 0x3E, 0x4B, + 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4, + 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, + 0x27, 0x80, 0xEC, 0x5F, 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, + 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF, 0xA0, 0xE0, 0x3B, 0x4D, + 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61, + 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, + 0x55, 0x21, 0x0C, 0x7D }; + +inline uint8_t xtime(uint8_t s) { return static_cast(s << 1) ^ ((s >> 7) * 0x1B); } +inline uint8_t xtime4(uint8_t s) { return xtime(xtime(s)); } +inline uint8_t xtime8(uint8_t s) { return xtime(xtime(xtime(s))); } + +inline uint8_t xtime3(uint8_t s) { return xtime(s) ^ s; } +inline uint8_t xtime9(uint8_t s) { return xtime8(s) ^ s; } +inline uint8_t xtime11(uint8_t s) { return xtime8(s) ^ xtime(s) ^ s; } +inline uint8_t xtime13(uint8_t s) { return xtime8(s) ^ xtime4(s) ^ s; } +inline uint8_t xtime14(uint8_t s) { return xtime8(s) ^ xtime4(s) ^ xtime(s); } + +inline uint32_t SE_word(uint32_t x) + { + return make_uint32(SE[get_byte(0, x)], + SE[get_byte(1, x)], + SE[get_byte(2, x)], + SE[get_byte(3, x)]); + } + +const uint32_t* AES_TE() + { + class TE_Table final + { + public: + TE_Table() + { + uint32_t* p = reinterpret_cast(&data); + for(size_t i = 0; i != 256; ++i) + { + const uint8_t s = SE[i]; + p[i] = make_uint32(xtime(s), s, s, xtime3(s)); + } + } + + const uint32_t* ptr() const + { + return reinterpret_cast(&data); + } + private: + std::aligned_storage<256*sizeof(uint32_t), 64>::type data; + }; + + static TE_Table table; + return table.ptr(); + } + +const uint32_t* AES_TD() + { + class TD_Table final + { + public: + TD_Table() + { + uint32_t* p = reinterpret_cast(&data); + for(size_t i = 0; i != 256; ++i) + { + const uint8_t s = SD[i]; + p[i] = make_uint32(xtime14(s), xtime9(s), xtime13(s), xtime11(s)); + } + } + + const uint32_t* ptr() const + { + return reinterpret_cast(&data); + } + private: + std::aligned_storage<256*sizeof(uint32_t), 64>::type data; + }; + + static TD_Table table; + return table.ptr(); + } + +#define AES_T(T, K, V0, V1, V2, V3) \ + (K ^ T[get_byte(0, V0)] ^ \ + rotr< 8>(T[get_byte(1, V1)]) ^ \ + rotr<16>(T[get_byte(2, V2)]) ^ \ + rotr<24>(T[get_byte(3, V3)])) + +/* +* AES Encryption +*/ +void aes_encrypt_n(const uint8_t in[], uint8_t out[], + size_t blocks, + const secure_vector& EK, + const secure_vector& ME) + { + 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 + volatile uint32_t Z = 0; + for(size_t i = 0; i < 256; i += cache_line_size / sizeof(uint32_t)) + { + Z |= TE[i]; + } + Z &= TE[82]; // this is zero, which hopefully the compiler cannot deduce + + for(size_t i = 0; i < blocks; ++i) + { + uint32_t T0, T1, T2, T3; + load_be(in + 16*i, T0, T1, T2, T3); + + T0 ^= EK[0]; + T1 ^= EK[1]; + T2 ^= EK[2]; + T3 ^= EK[3]; + + T0 ^= Z; + + uint32_t B0 = AES_T(TE, EK[4], T0, T1, T2, T3); + uint32_t B1 = AES_T(TE, EK[5], T1, T2, T3, T0); + uint32_t B2 = AES_T(TE, EK[6], T2, T3, T0, T1); + uint32_t B3 = AES_T(TE, EK[7], T3, T0, T1, T2); + + for(size_t r = 2*4; r < EK.size(); r += 2*4) + { + T0 = AES_T(TE, EK[r ], B0, B1, B2, B3); + T1 = AES_T(TE, EK[r+1], B1, B2, B3, B0); + T2 = AES_T(TE, EK[r+2], B2, B3, B0, B1); + T3 = AES_T(TE, EK[r+3], B3, B0, B1, B2); + + B0 = AES_T(TE, EK[r+4], T0, T1, T2, T3); + B1 = AES_T(TE, EK[r+5], T1, T2, T3, T0); + B2 = AES_T(TE, EK[r+6], T2, T3, T0, T1); + B3 = AES_T(TE, EK[r+7], T3, T0, T1, T2); + } + + /* + * Use TE[x] >> 8 instead of SE[] so encryption only references a single + * lookup table. + */ + out[16*i+ 0] = static_cast(TE[get_byte(0, B0)] >> 8) ^ ME[0]; + out[16*i+ 1] = static_cast(TE[get_byte(1, B1)] >> 8) ^ ME[1]; + out[16*i+ 2] = static_cast(TE[get_byte(2, B2)] >> 8) ^ ME[2]; + out[16*i+ 3] = static_cast(TE[get_byte(3, B3)] >> 8) ^ ME[3]; + out[16*i+ 4] = static_cast(TE[get_byte(0, B1)] >> 8) ^ ME[4]; + out[16*i+ 5] = static_cast(TE[get_byte(1, B2)] >> 8) ^ ME[5]; + out[16*i+ 6] = static_cast(TE[get_byte(2, B3)] >> 8) ^ ME[6]; + out[16*i+ 7] = static_cast(TE[get_byte(3, B0)] >> 8) ^ ME[7]; + out[16*i+ 8] = static_cast(TE[get_byte(0, B2)] >> 8) ^ ME[8]; + out[16*i+ 9] = static_cast(TE[get_byte(1, B3)] >> 8) ^ ME[9]; + out[16*i+10] = static_cast(TE[get_byte(2, B0)] >> 8) ^ ME[10]; + out[16*i+11] = static_cast(TE[get_byte(3, B1)] >> 8) ^ ME[11]; + out[16*i+12] = static_cast(TE[get_byte(0, B3)] >> 8) ^ ME[12]; + out[16*i+13] = static_cast(TE[get_byte(1, B0)] >> 8) ^ ME[13]; + out[16*i+14] = static_cast(TE[get_byte(2, B1)] >> 8) ^ ME[14]; + out[16*i+15] = static_cast(TE[get_byte(3, B2)] >> 8) ^ ME[15]; + } + } + +/* +* AES Decryption +*/ +void aes_decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks, + const secure_vector& DK, + const secure_vector& MD) + { + BOTAN_ASSERT(DK.size() && MD.size() == 16, "Key was set"); + + const size_t cache_line_size = CPUID::cache_line_size(); + const uint32_t* TD = AES_TD(); + + volatile uint32_t Z = 0; + for(size_t i = 0; i < 256; i += cache_line_size / sizeof(uint32_t)) + { + Z |= TD[i]; + } + Z &= TD[99]; // this is zero, which hopefully the compiler cannot deduce + + for(size_t i = 0; i != blocks; ++i) + { + uint32_t T0 = load_be(in, 0) ^ DK[0]; + uint32_t T1 = load_be(in, 1) ^ DK[1]; + uint32_t T2 = load_be(in, 2) ^ DK[2]; + uint32_t T3 = load_be(in, 3) ^ DK[3]; + + T0 ^= Z; + + uint32_t B0 = AES_T(TD, DK[4], T0, T3, T2, T1); + uint32_t B1 = AES_T(TD, DK[5], T1, T0, T3, T2); + uint32_t B2 = AES_T(TD, DK[6], T2, T1, T0, T3); + uint32_t B3 = AES_T(TD, DK[7], T3, T2, T1, T0); + + for(size_t r = 2*4; r < DK.size(); r += 2*4) + { + T0 = AES_T(TD, DK[r ], B0, B3, B2, B1); + T1 = AES_T(TD, DK[r+1], B1, B0, B3, B2); + T2 = AES_T(TD, DK[r+2], B2, B1, B0, B3); + T3 = AES_T(TD, DK[r+3], B3, B2, B1, B0); + + B0 = AES_T(TD, DK[r+4], T0, T3, T2, T1); + B1 = AES_T(TD, DK[r+5], T1, T0, T3, T2); + B2 = AES_T(TD, DK[r+6], T2, T1, T0, T3); + B3 = AES_T(TD, DK[r+7], T3, T2, T1, T0); + } + + out[ 0] = SD[get_byte(0, B0)] ^ MD[0]; + out[ 1] = SD[get_byte(1, B3)] ^ MD[1]; + out[ 2] = SD[get_byte(2, B2)] ^ MD[2]; + out[ 3] = SD[get_byte(3, B1)] ^ MD[3]; + out[ 4] = SD[get_byte(0, B1)] ^ MD[4]; + out[ 5] = SD[get_byte(1, B0)] ^ MD[5]; + out[ 6] = SD[get_byte(2, B3)] ^ MD[6]; + out[ 7] = SD[get_byte(3, B2)] ^ MD[7]; + out[ 8] = SD[get_byte(0, B2)] ^ MD[8]; + out[ 9] = SD[get_byte(1, B1)] ^ MD[9]; + out[10] = SD[get_byte(2, B0)] ^ MD[10]; + out[11] = SD[get_byte(3, B3)] ^ MD[11]; + out[12] = SD[get_byte(0, B3)] ^ MD[12]; + out[13] = SD[get_byte(1, B2)] ^ MD[13]; + out[14] = SD[get_byte(2, B1)] ^ MD[14]; + out[15] = SD[get_byte(3, B0)] ^ MD[15]; + + in += 16; + out += 16; + } + } + +void aes_key_schedule(const uint8_t key[], size_t length, + secure_vector& EK, + secure_vector& DK, + secure_vector& ME, + secure_vector& MD) + { + static const uint32_t RC[10] = { + 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, + 0x20000000, 0x40000000, 0x80000000, 0x1B000000, 0x36000000 }; + + const size_t rounds = (length / 4) + 6; + + secure_vector XEK(length + 32), XDK(length + 32); + + const size_t X = length / 4; + + // Can't happen, but make static analyzers happy + BOTAN_ARG_CHECK(X == 4 || X == 6 || X == 8, "Invalid AES key size"); + + for(size_t i = 0; i != X; ++i) + XEK[i] = load_be(key, i); + + for(size_t i = X; i < 4*(rounds+1); i += X) + { + XEK[i] = XEK[i-X] ^ RC[(i-X)/X] ^ SE_word(rotl<8>(XEK[i-1])); + + for(size_t j = 1; j != X; ++j) + { + XEK[i+j] = XEK[i+j-X]; + + if(X == 8 && j == 4) + XEK[i+j] ^= SE_word(XEK[i+j-1]); + else + XEK[i+j] ^= XEK[i+j-1]; + } + } + + for(size_t i = 0; i != 4*(rounds+1); i += 4) + { + XDK[i ] = XEK[4*rounds-i ]; + XDK[i+1] = XEK[4*rounds-i+1]; + XDK[i+2] = XEK[4*rounds-i+2]; + XDK[i+3] = XEK[4*rounds-i+3]; + } + + 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]); + } + + ME.resize(16); + MD.resize(16); + + for(size_t i = 0; i != 4; ++i) + { + store_be(XEK[i+4*rounds], &ME[4*i]); + store_be(XEK[i], &MD[4*i]); + } + + EK.resize(length + 24); + DK.resize(length + 24); + copy_mem(EK.data(), XEK.data(), EK.size()); + copy_mem(DK.data(), XDK.data(), DK.size()); + +#if defined(BOTAN_HAS_AES_ARMV8) + if(CPUID::has_arm_aes()) + { + // ARM needs the subkeys to be byte reversed + + for(size_t i = 0; i != EK.size(); ++i) + EK[i] = reverse_bytes(EK[i]); + for(size_t i = 0; i != DK.size(); ++i) + DK[i] = reverse_bytes(DK[i]); + } +#endif + + } + +#undef AES_T + +size_t aes_parallelism() + { +#if defined(BOTAN_HAS_AES_NI) + if(CPUID::has_aes_ni()) + { + return 4; + } +#endif + + return 1; + } + +const char* aes_provider() + { +#if defined(BOTAN_HAS_AES_NI) + if(CPUID::has_aes_ni()) + { + return "aesni"; + } +#endif + +#if defined(BOTAN_HAS_AES_SSSE3) + if(CPUID::has_ssse3()) + { + return "ssse3"; + } +#endif + +#if defined(BOTAN_HAS_AES_POWER8) + if(CPUID::has_ppc_crypto()) + { + return "power8"; + } +#endif + +#if defined(BOTAN_HAS_AES_ARMV8) + if(CPUID::has_arm_aes()) + { + return "armv8"; + } +#endif + + return "base"; + } + +} + +std::string AES_128::provider() const { return aes_provider(); } +std::string AES_192::provider() const { return aes_provider(); } +std::string AES_256::provider() const { return aes_provider(); } + +size_t AES_128::parallelism() const { return aes_parallelism(); } +size_t AES_192::parallelism() const { return aes_parallelism(); } +size_t AES_256::parallelism() const { return aes_parallelism(); } + +void AES_128::encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const + { + verify_key_set(m_EK.empty() == false); + +#if defined(BOTAN_HAS_AES_NI) + if(CPUID::has_aes_ni()) + { + return aesni_encrypt_n(in, out, blocks); + } +#endif + +#if defined(BOTAN_HAS_AES_SSSE3) + if(CPUID::has_ssse3()) + { + return ssse3_encrypt_n(in, out, blocks); + } +#endif + +#if defined(BOTAN_HAS_AES_ARMV8) + if(CPUID::has_arm_aes()) + { + return armv8_encrypt_n(in, out, blocks); + } +#endif + +#if defined(BOTAN_HAS_AES_POWER8) + if(CPUID::has_ppc_crypto()) + { + return power8_encrypt_n(in, out, blocks); + } +#endif + + aes_encrypt_n(in, out, blocks, m_EK, m_ME); + } + +void AES_128::decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const + { + verify_key_set(m_DK.empty() == false); + +#if defined(BOTAN_HAS_AES_NI) + if(CPUID::has_aes_ni()) + { + return aesni_decrypt_n(in, out, blocks); + } +#endif + +#if defined(BOTAN_HAS_AES_SSSE3) + if(CPUID::has_ssse3()) + { + return ssse3_decrypt_n(in, out, blocks); + } +#endif + +#if defined(BOTAN_HAS_AES_ARMV8) + if(CPUID::has_arm_aes()) + { + return armv8_decrypt_n(in, out, blocks); + } +#endif + +#if defined(BOTAN_HAS_AES_POWER8) + if(CPUID::has_ppc_crypto()) + { + return power8_decrypt_n(in, out, blocks); + } +#endif + + aes_decrypt_n(in, out, blocks, m_DK, m_MD); + } + +void AES_128::key_schedule(const uint8_t key[], size_t length) + { +#if defined(BOTAN_HAS_AES_NI) + if(CPUID::has_aes_ni()) + { + return aesni_key_schedule(key, length); + } +#endif + +#if defined(BOTAN_HAS_AES_SSSE3) + if(CPUID::has_ssse3()) + { + return ssse3_key_schedule(key, length); + } +#endif + + aes_key_schedule(key, length, m_EK, m_DK, m_ME, m_MD); + } + +void AES_128::clear() + { + zap(m_EK); + zap(m_DK); + zap(m_ME); + zap(m_MD); + } + +void AES_192::encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const + { + verify_key_set(m_EK.empty() == false); + +#if defined(BOTAN_HAS_AES_NI) + if(CPUID::has_aes_ni()) + { + return aesni_encrypt_n(in, out, blocks); + } +#endif + +#if defined(BOTAN_HAS_AES_SSSE3) + if(CPUID::has_ssse3()) + { + return ssse3_encrypt_n(in, out, blocks); + } +#endif + +#if defined(BOTAN_HAS_AES_ARMV8) + if(CPUID::has_arm_aes()) + { + return armv8_encrypt_n(in, out, blocks); + } +#endif + +#if defined(BOTAN_HAS_AES_POWER8) + if(CPUID::has_ppc_crypto()) + { + return power8_encrypt_n(in, out, blocks); + } +#endif + + aes_encrypt_n(in, out, blocks, m_EK, m_ME); + } + +void AES_192::decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const + { + verify_key_set(m_DK.empty() == false); + +#if defined(BOTAN_HAS_AES_NI) + if(CPUID::has_aes_ni()) + { + return aesni_decrypt_n(in, out, blocks); + } +#endif + +#if defined(BOTAN_HAS_AES_SSSE3) + if(CPUID::has_ssse3()) + { + return ssse3_decrypt_n(in, out, blocks); + } +#endif + +#if defined(BOTAN_HAS_AES_ARMV8) + if(CPUID::has_arm_aes()) + { + return armv8_decrypt_n(in, out, blocks); + } +#endif + +#if defined(BOTAN_HAS_AES_POWER8) + if(CPUID::has_ppc_crypto()) + { + return power8_decrypt_n(in, out, blocks); + } +#endif + + aes_decrypt_n(in, out, blocks, m_DK, m_MD); + } + +void AES_192::key_schedule(const uint8_t key[], size_t length) + { +#if defined(BOTAN_HAS_AES_NI) + if(CPUID::has_aes_ni()) + { + return aesni_key_schedule(key, length); + } +#endif + +#if defined(BOTAN_HAS_AES_SSSE3) + if(CPUID::has_ssse3()) + { + return ssse3_key_schedule(key, length); + } +#endif + + aes_key_schedule(key, length, m_EK, m_DK, m_ME, m_MD); + } + +void AES_192::clear() + { + zap(m_EK); + zap(m_DK); + zap(m_ME); + zap(m_MD); + } + +void AES_256::encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const + { + verify_key_set(m_EK.empty() == false); + +#if defined(BOTAN_HAS_AES_NI) + if(CPUID::has_aes_ni()) + { + return aesni_encrypt_n(in, out, blocks); + } +#endif + +#if defined(BOTAN_HAS_AES_SSSE3) + if(CPUID::has_ssse3()) + { + return ssse3_encrypt_n(in, out, blocks); + } +#endif + +#if defined(BOTAN_HAS_AES_ARMV8) + if(CPUID::has_arm_aes()) + { + return armv8_encrypt_n(in, out, blocks); + } +#endif + +#if defined(BOTAN_HAS_AES_POWER8) + if(CPUID::has_ppc_crypto()) + { + return power8_encrypt_n(in, out, blocks); + } +#endif + + aes_encrypt_n(in, out, blocks, m_EK, m_ME); + } + +void AES_256::decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const + { + verify_key_set(m_DK.empty() == false); + +#if defined(BOTAN_HAS_AES_NI) + if(CPUID::has_aes_ni()) + { + return aesni_decrypt_n(in, out, blocks); + } +#endif + +#if defined(BOTAN_HAS_AES_SSSE3) + if(CPUID::has_ssse3()) + { + return ssse3_decrypt_n(in, out, blocks); + } +#endif + +#if defined(BOTAN_HAS_AES_ARMV8) + if(CPUID::has_arm_aes()) + { + return armv8_decrypt_n(in, out, blocks); + } +#endif + +#if defined(BOTAN_HAS_AES_POWER8) + if(CPUID::has_ppc_crypto()) + { + return power8_decrypt_n(in, out, blocks); + } +#endif + + aes_decrypt_n(in, out, blocks, m_DK, m_MD); + } + +void AES_256::key_schedule(const uint8_t key[], size_t length) + { +#if defined(BOTAN_HAS_AES_NI) + if(CPUID::has_aes_ni()) + { + return aesni_key_schedule(key, length); + } +#endif + +#if defined(BOTAN_HAS_AES_SSSE3) + if(CPUID::has_ssse3()) + { + return ssse3_key_schedule(key, length); + } +#endif + + aes_key_schedule(key, length, m_EK, m_DK, m_ME, m_MD); + } + +void AES_256::clear() + { + zap(m_EK); + zap(m_DK); + zap(m_ME); + zap(m_MD); + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/block/aes/aes.h b/src/libs/3rdparty/botan/src/lib/block/aes/aes.h new file mode 100644 index 0000000000..294cdcad37 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/block/aes/aes.h @@ -0,0 +1,153 @@ +/* +* AES +* (C) 1999-2010 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_AES_H_ +#define BOTAN_AES_H_ + +#include + +namespace Botan { + +/** +* AES-128 +*/ +class BOTAN_PUBLIC_API(2,0) AES_128 final : public Block_Cipher_Fixed_Params<16, 16> + { + public: + void encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override; + void decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override; + + void clear() override; + + std::string provider() const override; + std::string name() const override { return "AES-128"; } + BlockCipher* clone() const override { return new AES_128; } + size_t parallelism() const override; + + private: + void key_schedule(const uint8_t key[], size_t length) override; + +#if defined(BOTAN_HAS_AES_SSSE3) + void ssse3_encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const; + void ssse3_decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const; + void ssse3_key_schedule(const uint8_t key[], size_t length); +#endif + +#if defined(BOTAN_HAS_AES_NI) + void aesni_encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const; + void aesni_decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const; + void aesni_key_schedule(const uint8_t key[], size_t length); +#endif + +#if defined(BOTAN_HAS_AES_ARMV8) + void armv8_encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const; + void armv8_decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const; +#endif + +#if defined(BOTAN_HAS_AES_POWER8) + void power8_encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const; + void power8_decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const; +#endif + + secure_vector m_EK, m_DK; + secure_vector m_ME, m_MD; + }; + +/** +* AES-192 +*/ +class BOTAN_PUBLIC_API(2,0) AES_192 final : public Block_Cipher_Fixed_Params<16, 24> + { + public: + void encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override; + void decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override; + + void clear() override; + + std::string provider() const override; + std::string name() const override { return "AES-192"; } + BlockCipher* clone() const override { return new AES_192; } + size_t parallelism() const override; + + private: +#if defined(BOTAN_HAS_AES_SSSE3) + void ssse3_encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const; + void ssse3_decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const; + void ssse3_key_schedule(const uint8_t key[], size_t length); +#endif + +#if defined(BOTAN_HAS_AES_NI) + void aesni_encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const; + void aesni_decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const; + void aesni_key_schedule(const uint8_t key[], size_t length); +#endif + +#if defined(BOTAN_HAS_AES_ARMV8) + void armv8_encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const; + void armv8_decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const; +#endif + +#if defined(BOTAN_HAS_AES_POWER8) + void power8_encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const; + void power8_decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const; +#endif + + void key_schedule(const uint8_t key[], size_t length) override; + + secure_vector m_EK, m_DK; + secure_vector m_ME, m_MD; + }; + +/** +* AES-256 +*/ +class BOTAN_PUBLIC_API(2,0) AES_256 final : public Block_Cipher_Fixed_Params<16, 32> + { + public: + void encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override; + void decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override; + + void clear() override; + + std::string provider() const override; + + std::string name() const override { return "AES-256"; } + BlockCipher* clone() const override { return new AES_256; } + size_t parallelism() const override; + + private: +#if defined(BOTAN_HAS_AES_SSSE3) + void ssse3_encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const; + void ssse3_decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const; + void ssse3_key_schedule(const uint8_t key[], size_t length); +#endif + +#if defined(BOTAN_HAS_AES_NI) + void aesni_encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const; + void aesni_decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const; + void aesni_key_schedule(const uint8_t key[], size_t length); +#endif + +#if defined(BOTAN_HAS_AES_ARMV8) + void armv8_encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const; + void armv8_decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const; +#endif + +#if defined(BOTAN_HAS_AES_POWER8) + void power8_encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const; + void power8_decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const; +#endif + + void key_schedule(const uint8_t key[], size_t length) override; + + secure_vector m_EK, m_DK; + secure_vector m_ME, m_MD; + }; + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/block/aes/aes_armv8/aes_armv8.cpp b/src/libs/3rdparty/botan/src/lib/block/aes/aes_armv8/aes_armv8.cpp new file mode 100644 index 0000000000..8a332ceafd --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/block/aes/aes_armv8/aes_armv8.cpp @@ -0,0 +1,501 @@ +/* +* AES using ARMv8 +* Contributed by Jeffrey Walton +* +* Further changes +* (C) 2017,2018 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include + +namespace Botan { + +#define AES_ENC_4_ROUNDS(K) \ + do \ + { \ + B0 = vaesmcq_u8(vaeseq_u8(B0, K)); \ + B1 = vaesmcq_u8(vaeseq_u8(B1, K)); \ + B2 = vaesmcq_u8(vaeseq_u8(B2, K)); \ + B3 = vaesmcq_u8(vaeseq_u8(B3, K)); \ + } while(0) + +#define AES_ENC_4_LAST_ROUNDS(K, K2) \ + do \ + { \ + B0 = veorq_u8(vaeseq_u8(B0, K), K2); \ + B1 = veorq_u8(vaeseq_u8(B1, K), K2); \ + B2 = veorq_u8(vaeseq_u8(B2, K), K2); \ + B3 = veorq_u8(vaeseq_u8(B3, K), K2); \ + } while(0) + +#define AES_DEC_4_ROUNDS(K) \ + do \ + { \ + B0 = vaesimcq_u8(vaesdq_u8(B0, K)); \ + B1 = vaesimcq_u8(vaesdq_u8(B1, K)); \ + B2 = vaesimcq_u8(vaesdq_u8(B2, K)); \ + B3 = vaesimcq_u8(vaesdq_u8(B3, K)); \ + } while(0) + +#define AES_DEC_4_LAST_ROUNDS(K, K2) \ + do \ + { \ + B0 = veorq_u8(vaesdq_u8(B0, K), K2); \ + B1 = veorq_u8(vaesdq_u8(B1, K), K2); \ + B2 = veorq_u8(vaesdq_u8(B2, K), K2); \ + B3 = veorq_u8(vaesdq_u8(B3, K), K2); \ + } while(0) + +/* +* AES-128 Encryption +*/ +BOTAN_FUNC_ISA("+crypto") +void AES_128::armv8_encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const + { + BOTAN_ASSERT(m_EK.empty() == false, "Key was set"); + + const uint8_t *skey = reinterpret_cast(m_EK.data()); + const uint8_t *mkey = reinterpret_cast(m_ME.data()); + + const uint8x16_t K0 = vld1q_u8(skey + 0); + const uint8x16_t K1 = vld1q_u8(skey + 16); + const uint8x16_t K2 = vld1q_u8(skey + 32); + const uint8x16_t K3 = vld1q_u8(skey + 48); + const uint8x16_t K4 = vld1q_u8(skey + 64); + const uint8x16_t K5 = vld1q_u8(skey + 80); + const uint8x16_t K6 = vld1q_u8(skey + 96); + const uint8x16_t K7 = vld1q_u8(skey + 112); + const uint8x16_t K8 = vld1q_u8(skey + 128); + const uint8x16_t K9 = vld1q_u8(skey + 144); + const uint8x16_t K10 = vld1q_u8(mkey); + + while(blocks >= 4) + { + uint8x16_t B0 = vld1q_u8(in); + uint8x16_t B1 = vld1q_u8(in+16); + uint8x16_t B2 = vld1q_u8(in+32); + uint8x16_t B3 = vld1q_u8(in+48); + + AES_ENC_4_ROUNDS(K0); + AES_ENC_4_ROUNDS(K1); + AES_ENC_4_ROUNDS(K2); + AES_ENC_4_ROUNDS(K3); + AES_ENC_4_ROUNDS(K4); + AES_ENC_4_ROUNDS(K5); + AES_ENC_4_ROUNDS(K6); + AES_ENC_4_ROUNDS(K7); + AES_ENC_4_ROUNDS(K8); + AES_ENC_4_LAST_ROUNDS(K9, K10); + + vst1q_u8(out, B0); + vst1q_u8(out+16, B1); + vst1q_u8(out+32, B2); + vst1q_u8(out+48, B3); + + in += 16*4; + out += 16*4; + blocks -= 4; + } + + for(size_t i = 0; i != blocks; ++i) + { + uint8x16_t B = vld1q_u8(in+16*i); + B = vaesmcq_u8(vaeseq_u8(B, K0)); + B = vaesmcq_u8(vaeseq_u8(B, K1)); + B = vaesmcq_u8(vaeseq_u8(B, K2)); + B = vaesmcq_u8(vaeseq_u8(B, K3)); + B = vaesmcq_u8(vaeseq_u8(B, K4)); + B = vaesmcq_u8(vaeseq_u8(B, K5)); + B = vaesmcq_u8(vaeseq_u8(B, K6)); + B = vaesmcq_u8(vaeseq_u8(B, K7)); + B = vaesmcq_u8(vaeseq_u8(B, K8)); + B = veorq_u8(vaeseq_u8(B, K9), K10); + vst1q_u8(out+16*i, B); + } + } + +/* +* AES-128 Decryption +*/ +BOTAN_FUNC_ISA("+crypto") +void AES_128::armv8_decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const + { + BOTAN_ASSERT(m_DK.empty() == false, "Key was set"); + + const uint8_t *skey = reinterpret_cast(m_DK.data()); + const uint8_t *mkey = reinterpret_cast(m_MD.data()); + + const uint8x16_t K0 = vld1q_u8(skey + 0); + const uint8x16_t K1 = vld1q_u8(skey + 16); + const uint8x16_t K2 = vld1q_u8(skey + 32); + const uint8x16_t K3 = vld1q_u8(skey + 48); + const uint8x16_t K4 = vld1q_u8(skey + 64); + const uint8x16_t K5 = vld1q_u8(skey + 80); + const uint8x16_t K6 = vld1q_u8(skey + 96); + const uint8x16_t K7 = vld1q_u8(skey + 112); + const uint8x16_t K8 = vld1q_u8(skey + 128); + const uint8x16_t K9 = vld1q_u8(skey + 144); + const uint8x16_t K10 = vld1q_u8(mkey); + + while(blocks >= 4) + { + uint8x16_t B0 = vld1q_u8(in); + uint8x16_t B1 = vld1q_u8(in+16); + uint8x16_t B2 = vld1q_u8(in+32); + uint8x16_t B3 = vld1q_u8(in+48); + + AES_DEC_4_ROUNDS(K0); + AES_DEC_4_ROUNDS(K1); + AES_DEC_4_ROUNDS(K2); + AES_DEC_4_ROUNDS(K3); + AES_DEC_4_ROUNDS(K4); + AES_DEC_4_ROUNDS(K5); + AES_DEC_4_ROUNDS(K6); + AES_DEC_4_ROUNDS(K7); + AES_DEC_4_ROUNDS(K8); + AES_DEC_4_LAST_ROUNDS(K9, K10); + + vst1q_u8(out, B0); + vst1q_u8(out+16, B1); + vst1q_u8(out+32, B2); + vst1q_u8(out+48, B3); + + in += 16*4; + out += 16*4; + blocks -= 4; + } + + for(size_t i = 0; i != blocks; ++i) + { + uint8x16_t B = vld1q_u8(in+16*i); + B = vaesimcq_u8(vaesdq_u8(B, K0)); + B = vaesimcq_u8(vaesdq_u8(B, K1)); + B = vaesimcq_u8(vaesdq_u8(B, K2)); + B = vaesimcq_u8(vaesdq_u8(B, K3)); + B = vaesimcq_u8(vaesdq_u8(B, K4)); + B = vaesimcq_u8(vaesdq_u8(B, K5)); + B = vaesimcq_u8(vaesdq_u8(B, K6)); + B = vaesimcq_u8(vaesdq_u8(B, K7)); + B = vaesimcq_u8(vaesdq_u8(B, K8)); + B = veorq_u8(vaesdq_u8(B, K9), K10); + vst1q_u8(out+16*i, B); + } + } + +/* +* AES-192 Encryption +*/ +BOTAN_FUNC_ISA("+crypto") +void AES_192::armv8_encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const + { + BOTAN_ASSERT(m_EK.empty() == false, "Key was set"); + + const uint8_t *skey = reinterpret_cast(m_EK.data()); + const uint8_t *mkey = reinterpret_cast(m_ME.data()); + + const uint8x16_t K0 = vld1q_u8(skey + 0); + const uint8x16_t K1 = vld1q_u8(skey + 16); + const uint8x16_t K2 = vld1q_u8(skey + 32); + const uint8x16_t K3 = vld1q_u8(skey + 48); + const uint8x16_t K4 = vld1q_u8(skey + 64); + const uint8x16_t K5 = vld1q_u8(skey + 80); + const uint8x16_t K6 = vld1q_u8(skey + 96); + const uint8x16_t K7 = vld1q_u8(skey + 112); + const uint8x16_t K8 = vld1q_u8(skey + 128); + const uint8x16_t K9 = vld1q_u8(skey + 144); + const uint8x16_t K10 = vld1q_u8(skey + 160); + const uint8x16_t K11 = vld1q_u8(skey + 176); + const uint8x16_t K12 = vld1q_u8(mkey); + + while(blocks >= 4) + { + uint8x16_t B0 = vld1q_u8(in); + uint8x16_t B1 = vld1q_u8(in+16); + uint8x16_t B2 = vld1q_u8(in+32); + uint8x16_t B3 = vld1q_u8(in+48); + + AES_ENC_4_ROUNDS(K0); + AES_ENC_4_ROUNDS(K1); + AES_ENC_4_ROUNDS(K2); + AES_ENC_4_ROUNDS(K3); + AES_ENC_4_ROUNDS(K4); + AES_ENC_4_ROUNDS(K5); + AES_ENC_4_ROUNDS(K6); + AES_ENC_4_ROUNDS(K7); + AES_ENC_4_ROUNDS(K8); + AES_ENC_4_ROUNDS(K9); + AES_ENC_4_ROUNDS(K10); + AES_ENC_4_LAST_ROUNDS(K11, K12); + + vst1q_u8(out, B0); + vst1q_u8(out+16, B1); + vst1q_u8(out+32, B2); + vst1q_u8(out+48, B3); + + in += 16*4; + out += 16*4; + blocks -= 4; + } + + for(size_t i = 0; i != blocks; ++i) + { + uint8x16_t B = vld1q_u8(in+16*i); + B = vaesmcq_u8(vaeseq_u8(B, K0)); + B = vaesmcq_u8(vaeseq_u8(B, K1)); + B = vaesmcq_u8(vaeseq_u8(B, K2)); + B = vaesmcq_u8(vaeseq_u8(B, K3)); + B = vaesmcq_u8(vaeseq_u8(B, K4)); + B = vaesmcq_u8(vaeseq_u8(B, K5)); + B = vaesmcq_u8(vaeseq_u8(B, K6)); + B = vaesmcq_u8(vaeseq_u8(B, K7)); + B = vaesmcq_u8(vaeseq_u8(B, K8)); + B = vaesmcq_u8(vaeseq_u8(B, K9)); + B = vaesmcq_u8(vaeseq_u8(B, K10)); + B = veorq_u8(vaeseq_u8(B, K11), K12); + vst1q_u8(out+16*i, B); + } + } + +/* +* AES-192 Decryption +*/ +BOTAN_FUNC_ISA("+crypto") +void AES_192::armv8_decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const + { + BOTAN_ASSERT(m_DK.empty() == false, "Key was set"); + const uint8_t *skey = reinterpret_cast(m_DK.data()); + const uint8_t *mkey = reinterpret_cast(m_MD.data()); + + const uint8x16_t K0 = vld1q_u8(skey + 0); + const uint8x16_t K1 = vld1q_u8(skey + 16); + const uint8x16_t K2 = vld1q_u8(skey + 32); + const uint8x16_t K3 = vld1q_u8(skey + 48); + const uint8x16_t K4 = vld1q_u8(skey + 64); + const uint8x16_t K5 = vld1q_u8(skey + 80); + const uint8x16_t K6 = vld1q_u8(skey + 96); + const uint8x16_t K7 = vld1q_u8(skey + 112); + const uint8x16_t K8 = vld1q_u8(skey + 128); + const uint8x16_t K9 = vld1q_u8(skey + 144); + const uint8x16_t K10 = vld1q_u8(skey + 160); + const uint8x16_t K11 = vld1q_u8(skey + 176); + const uint8x16_t K12 = vld1q_u8(mkey); + + while(blocks >= 4) + { + uint8x16_t B0 = vld1q_u8(in); + uint8x16_t B1 = vld1q_u8(in+16); + uint8x16_t B2 = vld1q_u8(in+32); + uint8x16_t B3 = vld1q_u8(in+48); + + AES_DEC_4_ROUNDS(K0); + AES_DEC_4_ROUNDS(K1); + AES_DEC_4_ROUNDS(K2); + AES_DEC_4_ROUNDS(K3); + AES_DEC_4_ROUNDS(K4); + AES_DEC_4_ROUNDS(K5); + AES_DEC_4_ROUNDS(K6); + AES_DEC_4_ROUNDS(K7); + AES_DEC_4_ROUNDS(K8); + AES_DEC_4_ROUNDS(K9); + AES_DEC_4_ROUNDS(K10); + AES_DEC_4_LAST_ROUNDS(K11, K12); + + vst1q_u8(out, B0); + vst1q_u8(out+16, B1); + vst1q_u8(out+32, B2); + vst1q_u8(out+48, B3); + + in += 16*4; + out += 16*4; + blocks -= 4; + } + + for(size_t i = 0; i != blocks; ++i) + { + uint8x16_t B = vld1q_u8(in+16*i); + B = vaesimcq_u8(vaesdq_u8(B, K0)); + B = vaesimcq_u8(vaesdq_u8(B, K1)); + B = vaesimcq_u8(vaesdq_u8(B, K2)); + B = vaesimcq_u8(vaesdq_u8(B, K3)); + B = vaesimcq_u8(vaesdq_u8(B, K4)); + B = vaesimcq_u8(vaesdq_u8(B, K5)); + B = vaesimcq_u8(vaesdq_u8(B, K6)); + B = vaesimcq_u8(vaesdq_u8(B, K7)); + B = vaesimcq_u8(vaesdq_u8(B, K8)); + B = vaesimcq_u8(vaesdq_u8(B, K9)); + B = vaesimcq_u8(vaesdq_u8(B, K10)); + B = veorq_u8(vaesdq_u8(B, K11), K12); + vst1q_u8(out+16*i, B); + } + } + +/* +* AES-256 Encryption +*/ +BOTAN_FUNC_ISA("+crypto") +void AES_256::armv8_encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const + { + BOTAN_ASSERT(m_EK.empty() == false, "Key was set"); + + const uint8_t *skey = reinterpret_cast(m_EK.data()); + const uint8_t *mkey = reinterpret_cast(m_ME.data()); + + const uint8x16_t K0 = vld1q_u8(skey + 0); + const uint8x16_t K1 = vld1q_u8(skey + 16); + const uint8x16_t K2 = vld1q_u8(skey + 32); + const uint8x16_t K3 = vld1q_u8(skey + 48); + const uint8x16_t K4 = vld1q_u8(skey + 64); + const uint8x16_t K5 = vld1q_u8(skey + 80); + const uint8x16_t K6 = vld1q_u8(skey + 96); + const uint8x16_t K7 = vld1q_u8(skey + 112); + const uint8x16_t K8 = vld1q_u8(skey + 128); + const uint8x16_t K9 = vld1q_u8(skey + 144); + const uint8x16_t K10 = vld1q_u8(skey + 160); + const uint8x16_t K11 = vld1q_u8(skey + 176); + const uint8x16_t K12 = vld1q_u8(skey + 192); + const uint8x16_t K13 = vld1q_u8(skey + 208); + const uint8x16_t K14 = vld1q_u8(mkey); + + while(blocks >= 4) + { + uint8x16_t B0 = vld1q_u8(in); + uint8x16_t B1 = vld1q_u8(in+16); + uint8x16_t B2 = vld1q_u8(in+32); + uint8x16_t B3 = vld1q_u8(in+48); + + AES_ENC_4_ROUNDS(K0); + AES_ENC_4_ROUNDS(K1); + AES_ENC_4_ROUNDS(K2); + AES_ENC_4_ROUNDS(K3); + AES_ENC_4_ROUNDS(K4); + AES_ENC_4_ROUNDS(K5); + AES_ENC_4_ROUNDS(K6); + AES_ENC_4_ROUNDS(K7); + AES_ENC_4_ROUNDS(K8); + AES_ENC_4_ROUNDS(K9); + AES_ENC_4_ROUNDS(K10); + AES_ENC_4_ROUNDS(K11); + AES_ENC_4_ROUNDS(K12); + AES_ENC_4_LAST_ROUNDS(K13, K14); + + vst1q_u8(out, B0); + vst1q_u8(out+16, B1); + vst1q_u8(out+32, B2); + vst1q_u8(out+48, B3); + + in += 16*4; + out += 16*4; + blocks -= 4; + } + + for(size_t i = 0; i != blocks; ++i) + { + uint8x16_t B = vld1q_u8(in+16*i); + B = vaesmcq_u8(vaeseq_u8(B, K0)); + B = vaesmcq_u8(vaeseq_u8(B, K1)); + B = vaesmcq_u8(vaeseq_u8(B, K2)); + B = vaesmcq_u8(vaeseq_u8(B, K3)); + B = vaesmcq_u8(vaeseq_u8(B, K4)); + B = vaesmcq_u8(vaeseq_u8(B, K5)); + B = vaesmcq_u8(vaeseq_u8(B, K6)); + B = vaesmcq_u8(vaeseq_u8(B, K7)); + B = vaesmcq_u8(vaeseq_u8(B, K8)); + B = vaesmcq_u8(vaeseq_u8(B, K9)); + B = vaesmcq_u8(vaeseq_u8(B, K10)); + B = vaesmcq_u8(vaeseq_u8(B, K11)); + B = vaesmcq_u8(vaeseq_u8(B, K12)); + B = veorq_u8(vaeseq_u8(B, K13), K14); + vst1q_u8(out+16*i, B); + } + } + +/* +* AES-256 Decryption +*/ +BOTAN_FUNC_ISA("+crypto") +void AES_256::armv8_decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const + { + BOTAN_ASSERT(m_DK.empty() == false, "Key was set"); + + const uint8_t *skey = reinterpret_cast(m_DK.data()); + const uint8_t *mkey = reinterpret_cast(m_MD.data()); + + const uint8x16_t K0 = vld1q_u8(skey + 0); + const uint8x16_t K1 = vld1q_u8(skey + 16); + const uint8x16_t K2 = vld1q_u8(skey + 32); + const uint8x16_t K3 = vld1q_u8(skey + 48); + const uint8x16_t K4 = vld1q_u8(skey + 64); + const uint8x16_t K5 = vld1q_u8(skey + 80); + const uint8x16_t K6 = vld1q_u8(skey + 96); + const uint8x16_t K7 = vld1q_u8(skey + 112); + const uint8x16_t K8 = vld1q_u8(skey + 128); + const uint8x16_t K9 = vld1q_u8(skey + 144); + const uint8x16_t K10 = vld1q_u8(skey + 160); + const uint8x16_t K11 = vld1q_u8(skey + 176); + const uint8x16_t K12 = vld1q_u8(skey + 192); + const uint8x16_t K13 = vld1q_u8(skey + 208); + const uint8x16_t K14 = vld1q_u8(mkey); + + while(blocks >= 4) + { + uint8x16_t B0 = vld1q_u8(in); + uint8x16_t B1 = vld1q_u8(in+16); + uint8x16_t B2 = vld1q_u8(in+32); + uint8x16_t B3 = vld1q_u8(in+48); + + AES_DEC_4_ROUNDS(K0); + AES_DEC_4_ROUNDS(K1); + AES_DEC_4_ROUNDS(K2); + AES_DEC_4_ROUNDS(K3); + AES_DEC_4_ROUNDS(K4); + AES_DEC_4_ROUNDS(K5); + AES_DEC_4_ROUNDS(K6); + AES_DEC_4_ROUNDS(K7); + AES_DEC_4_ROUNDS(K8); + AES_DEC_4_ROUNDS(K9); + AES_DEC_4_ROUNDS(K10); + AES_DEC_4_ROUNDS(K11); + AES_DEC_4_ROUNDS(K12); + AES_DEC_4_LAST_ROUNDS(K13, K14); + + vst1q_u8(out, B0); + vst1q_u8(out+16, B1); + vst1q_u8(out+32, B2); + vst1q_u8(out+48, B3); + + in += 16*4; + out += 16*4; + blocks -= 4; + } + + for(size_t i = 0; i != blocks; ++i) + { + uint8x16_t B = vld1q_u8(in+16*i); + B = vaesimcq_u8(vaesdq_u8(B, K0)); + B = vaesimcq_u8(vaesdq_u8(B, K1)); + B = vaesimcq_u8(vaesdq_u8(B, K2)); + B = vaesimcq_u8(vaesdq_u8(B, K3)); + B = vaesimcq_u8(vaesdq_u8(B, K4)); + B = vaesimcq_u8(vaesdq_u8(B, K5)); + B = vaesimcq_u8(vaesdq_u8(B, K6)); + B = vaesimcq_u8(vaesdq_u8(B, K7)); + B = vaesimcq_u8(vaesdq_u8(B, K8)); + B = vaesimcq_u8(vaesdq_u8(B, K9)); + B = vaesimcq_u8(vaesdq_u8(B, K10)); + B = vaesimcq_u8(vaesdq_u8(B, K11)); + B = vaesimcq_u8(vaesdq_u8(B, K12)); + B = veorq_u8(vaesdq_u8(B, K13), K14); + vst1q_u8(out+16*i, B); + } + } + +#undef AES_ENC_4_ROUNDS +#undef AES_ENC_4_LAST_ROUNDS +#undef AES_DEC_4_ROUNDS +#undef AES_DEC_4_LAST_ROUNDS + +} diff --git a/src/libs/3rdparty/botan/src/lib/block/aes/aes_armv8/info.txt b/src/libs/3rdparty/botan/src/lib/block/aes/aes_armv8/info.txt new file mode 100644 index 0000000000..08d51a1b2d --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/block/aes/aes_armv8/info.txt @@ -0,0 +1,10 @@ + +AES_ARMV8 -> 20170903 + + +need_isa armv8crypto + + +gcc:5 +clang:3.8 + diff --git a/src/libs/3rdparty/botan/src/lib/block/aes/aes_ni/aes_ni.cpp b/src/libs/3rdparty/botan/src/lib/block/aes/aes_ni/aes_ni.cpp new file mode 100644 index 0000000000..9f1ba8fcc2 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/block/aes/aes_ni/aes_ni.cpp @@ -0,0 +1,792 @@ +/* +* AES using AES-NI instructions +* (C) 2009,2012 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include + +namespace Botan { + +namespace { + +BOTAN_FUNC_ISA("ssse3") +__m128i aes_128_key_expansion(__m128i key, __m128i key_with_rcon) + { + key_with_rcon = _mm_shuffle_epi32(key_with_rcon, _MM_SHUFFLE(3,3,3,3)); + key = _mm_xor_si128(key, _mm_slli_si128(key, 4)); + key = _mm_xor_si128(key, _mm_slli_si128(key, 4)); + key = _mm_xor_si128(key, _mm_slli_si128(key, 4)); + return _mm_xor_si128(key, key_with_rcon); + } + +BOTAN_FUNC_ISA("ssse3") +void aes_192_key_expansion(__m128i* K1, __m128i* K2, __m128i key2_with_rcon, + uint32_t out[], bool last) + { + __m128i key1 = *K1; + __m128i key2 = *K2; + + key2_with_rcon = _mm_shuffle_epi32(key2_with_rcon, _MM_SHUFFLE(1,1,1,1)); + key1 = _mm_xor_si128(key1, _mm_slli_si128(key1, 4)); + key1 = _mm_xor_si128(key1, _mm_slli_si128(key1, 4)); + key1 = _mm_xor_si128(key1, _mm_slli_si128(key1, 4)); + key1 = _mm_xor_si128(key1, key2_with_rcon); + + *K1 = key1; + _mm_storeu_si128(reinterpret_cast<__m128i*>(out), key1); + + if(last) + return; + + key2 = _mm_xor_si128(key2, _mm_slli_si128(key2, 4)); + key2 = _mm_xor_si128(key2, _mm_shuffle_epi32(key1, _MM_SHUFFLE(3,3,3,3))); + + *K2 = key2; + out[4] = _mm_cvtsi128_si32(key2); + out[5] = _mm_cvtsi128_si32(_mm_srli_si128(key2, 4)); + } + +/* +* The second half of the AES-256 key expansion (other half same as AES-128) +*/ +BOTAN_FUNC_ISA("ssse3,aes") +__m128i aes_256_key_expansion(__m128i key, __m128i key2) + { + __m128i key_with_rcon = _mm_aeskeygenassist_si128(key2, 0x00); + key_with_rcon = _mm_shuffle_epi32(key_with_rcon, _MM_SHUFFLE(2,2,2,2)); + + key = _mm_xor_si128(key, _mm_slli_si128(key, 4)); + key = _mm_xor_si128(key, _mm_slli_si128(key, 4)); + key = _mm_xor_si128(key, _mm_slli_si128(key, 4)); + return _mm_xor_si128(key, key_with_rcon); + } + +} + +#define AES_ENC_4_ROUNDS(K) \ + do \ + { \ + B0 = _mm_aesenc_si128(B0, K); \ + B1 = _mm_aesenc_si128(B1, K); \ + B2 = _mm_aesenc_si128(B2, K); \ + B3 = _mm_aesenc_si128(B3, K); \ + } while(0) + +#define AES_ENC_4_LAST_ROUNDS(K) \ + do \ + { \ + B0 = _mm_aesenclast_si128(B0, K); \ + B1 = _mm_aesenclast_si128(B1, K); \ + B2 = _mm_aesenclast_si128(B2, K); \ + B3 = _mm_aesenclast_si128(B3, K); \ + } while(0) + +#define AES_DEC_4_ROUNDS(K) \ + do \ + { \ + B0 = _mm_aesdec_si128(B0, K); \ + B1 = _mm_aesdec_si128(B1, K); \ + B2 = _mm_aesdec_si128(B2, K); \ + B3 = _mm_aesdec_si128(B3, K); \ + } while(0) + +#define AES_DEC_4_LAST_ROUNDS(K) \ + do \ + { \ + B0 = _mm_aesdeclast_si128(B0, K); \ + B1 = _mm_aesdeclast_si128(B1, K); \ + B2 = _mm_aesdeclast_si128(B2, K); \ + B3 = _mm_aesdeclast_si128(B3, K); \ + } while(0) + +/* +* AES-128 Encryption +*/ +BOTAN_FUNC_ISA("ssse3,aes") +void AES_128::aesni_encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const + { + BOTAN_ASSERT(m_EK.empty() == false, "Key was set"); + + const __m128i* in_mm = reinterpret_cast(in); + __m128i* out_mm = reinterpret_cast<__m128i*>(out); + + const __m128i* key_mm = reinterpret_cast(m_EK.data()); + + const __m128i K0 = _mm_loadu_si128(key_mm); + const __m128i K1 = _mm_loadu_si128(key_mm + 1); + const __m128i K2 = _mm_loadu_si128(key_mm + 2); + const __m128i K3 = _mm_loadu_si128(key_mm + 3); + const __m128i K4 = _mm_loadu_si128(key_mm + 4); + const __m128i K5 = _mm_loadu_si128(key_mm + 5); + const __m128i K6 = _mm_loadu_si128(key_mm + 6); + const __m128i K7 = _mm_loadu_si128(key_mm + 7); + const __m128i K8 = _mm_loadu_si128(key_mm + 8); + const __m128i K9 = _mm_loadu_si128(key_mm + 9); + const __m128i K10 = _mm_loadu_si128(key_mm + 10); + + while(blocks >= 4) + { + __m128i B0 = _mm_loadu_si128(in_mm + 0); + __m128i B1 = _mm_loadu_si128(in_mm + 1); + __m128i B2 = _mm_loadu_si128(in_mm + 2); + __m128i B3 = _mm_loadu_si128(in_mm + 3); + + B0 = _mm_xor_si128(B0, K0); + B1 = _mm_xor_si128(B1, K0); + B2 = _mm_xor_si128(B2, K0); + B3 = _mm_xor_si128(B3, K0); + + AES_ENC_4_ROUNDS(K1); + AES_ENC_4_ROUNDS(K2); + AES_ENC_4_ROUNDS(K3); + AES_ENC_4_ROUNDS(K4); + AES_ENC_4_ROUNDS(K5); + AES_ENC_4_ROUNDS(K6); + AES_ENC_4_ROUNDS(K7); + AES_ENC_4_ROUNDS(K8); + AES_ENC_4_ROUNDS(K9); + AES_ENC_4_LAST_ROUNDS(K10); + + _mm_storeu_si128(out_mm + 0, B0); + _mm_storeu_si128(out_mm + 1, B1); + _mm_storeu_si128(out_mm + 2, B2); + _mm_storeu_si128(out_mm + 3, B3); + + blocks -= 4; + in_mm += 4; + out_mm += 4; + } + + for(size_t i = 0; i != blocks; ++i) + { + __m128i B = _mm_loadu_si128(in_mm + i); + + B = _mm_xor_si128(B, K0); + + B = _mm_aesenc_si128(B, K1); + B = _mm_aesenc_si128(B, K2); + B = _mm_aesenc_si128(B, K3); + B = _mm_aesenc_si128(B, K4); + B = _mm_aesenc_si128(B, K5); + B = _mm_aesenc_si128(B, K6); + B = _mm_aesenc_si128(B, K7); + B = _mm_aesenc_si128(B, K8); + B = _mm_aesenc_si128(B, K9); + B = _mm_aesenclast_si128(B, K10); + + _mm_storeu_si128(out_mm + i, B); + } + } + +/* +* AES-128 Decryption +*/ +BOTAN_FUNC_ISA("ssse3,aes") +void AES_128::aesni_decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const + { + BOTAN_ASSERT(m_DK.empty() == false, "Key was set"); + + const __m128i* in_mm = reinterpret_cast(in); + __m128i* out_mm = reinterpret_cast<__m128i*>(out); + + const __m128i* key_mm = reinterpret_cast(m_DK.data()); + + const __m128i K0 = _mm_loadu_si128(key_mm); + const __m128i K1 = _mm_loadu_si128(key_mm + 1); + const __m128i K2 = _mm_loadu_si128(key_mm + 2); + const __m128i K3 = _mm_loadu_si128(key_mm + 3); + const __m128i K4 = _mm_loadu_si128(key_mm + 4); + const __m128i K5 = _mm_loadu_si128(key_mm + 5); + const __m128i K6 = _mm_loadu_si128(key_mm + 6); + const __m128i K7 = _mm_loadu_si128(key_mm + 7); + const __m128i K8 = _mm_loadu_si128(key_mm + 8); + const __m128i K9 = _mm_loadu_si128(key_mm + 9); + const __m128i K10 = _mm_loadu_si128(key_mm + 10); + + while(blocks >= 4) + { + __m128i B0 = _mm_loadu_si128(in_mm + 0); + __m128i B1 = _mm_loadu_si128(in_mm + 1); + __m128i B2 = _mm_loadu_si128(in_mm + 2); + __m128i B3 = _mm_loadu_si128(in_mm + 3); + + B0 = _mm_xor_si128(B0, K0); + B1 = _mm_xor_si128(B1, K0); + B2 = _mm_xor_si128(B2, K0); + B3 = _mm_xor_si128(B3, K0); + + AES_DEC_4_ROUNDS(K1); + AES_DEC_4_ROUNDS(K2); + AES_DEC_4_ROUNDS(K3); + AES_DEC_4_ROUNDS(K4); + AES_DEC_4_ROUNDS(K5); + AES_DEC_4_ROUNDS(K6); + AES_DEC_4_ROUNDS(K7); + AES_DEC_4_ROUNDS(K8); + AES_DEC_4_ROUNDS(K9); + AES_DEC_4_LAST_ROUNDS(K10); + + _mm_storeu_si128(out_mm + 0, B0); + _mm_storeu_si128(out_mm + 1, B1); + _mm_storeu_si128(out_mm + 2, B2); + _mm_storeu_si128(out_mm + 3, B3); + + blocks -= 4; + in_mm += 4; + out_mm += 4; + } + + for(size_t i = 0; i != blocks; ++i) + { + __m128i B = _mm_loadu_si128(in_mm + i); + + B = _mm_xor_si128(B, K0); + + B = _mm_aesdec_si128(B, K1); + B = _mm_aesdec_si128(B, K2); + B = _mm_aesdec_si128(B, K3); + B = _mm_aesdec_si128(B, K4); + B = _mm_aesdec_si128(B, K5); + B = _mm_aesdec_si128(B, K6); + B = _mm_aesdec_si128(B, K7); + B = _mm_aesdec_si128(B, K8); + B = _mm_aesdec_si128(B, K9); + B = _mm_aesdeclast_si128(B, K10); + + _mm_storeu_si128(out_mm + i, B); + } + } + +/* +* AES-128 Key Schedule +*/ +BOTAN_FUNC_ISA("ssse3,aes") +void AES_128::aesni_key_schedule(const uint8_t key[], size_t) + { + m_EK.resize(44); + m_DK.resize(44); + + #define AES_128_key_exp(K, RCON) \ + aes_128_key_expansion(K, _mm_aeskeygenassist_si128(K, RCON)) + + const __m128i K0 = _mm_loadu_si128(reinterpret_cast(key)); + const __m128i K1 = AES_128_key_exp(K0, 0x01); + const __m128i K2 = AES_128_key_exp(K1, 0x02); + const __m128i K3 = AES_128_key_exp(K2, 0x04); + const __m128i K4 = AES_128_key_exp(K3, 0x08); + const __m128i K5 = AES_128_key_exp(K4, 0x10); + const __m128i K6 = AES_128_key_exp(K5, 0x20); + const __m128i K7 = AES_128_key_exp(K6, 0x40); + const __m128i K8 = AES_128_key_exp(K7, 0x80); + const __m128i K9 = AES_128_key_exp(K8, 0x1B); + const __m128i K10 = AES_128_key_exp(K9, 0x36); + + __m128i* EK_mm = reinterpret_cast<__m128i*>(m_EK.data()); + _mm_storeu_si128(EK_mm , K0); + _mm_storeu_si128(EK_mm + 1, K1); + _mm_storeu_si128(EK_mm + 2, K2); + _mm_storeu_si128(EK_mm + 3, K3); + _mm_storeu_si128(EK_mm + 4, K4); + _mm_storeu_si128(EK_mm + 5, K5); + _mm_storeu_si128(EK_mm + 6, K6); + _mm_storeu_si128(EK_mm + 7, K7); + _mm_storeu_si128(EK_mm + 8, K8); + _mm_storeu_si128(EK_mm + 9, K9); + _mm_storeu_si128(EK_mm + 10, K10); + + // Now generate decryption keys + + __m128i* DK_mm = reinterpret_cast<__m128i*>(m_DK.data()); + _mm_storeu_si128(DK_mm , K10); + _mm_storeu_si128(DK_mm + 1, _mm_aesimc_si128(K9)); + _mm_storeu_si128(DK_mm + 2, _mm_aesimc_si128(K8)); + _mm_storeu_si128(DK_mm + 3, _mm_aesimc_si128(K7)); + _mm_storeu_si128(DK_mm + 4, _mm_aesimc_si128(K6)); + _mm_storeu_si128(DK_mm + 5, _mm_aesimc_si128(K5)); + _mm_storeu_si128(DK_mm + 6, _mm_aesimc_si128(K4)); + _mm_storeu_si128(DK_mm + 7, _mm_aesimc_si128(K3)); + _mm_storeu_si128(DK_mm + 8, _mm_aesimc_si128(K2)); + _mm_storeu_si128(DK_mm + 9, _mm_aesimc_si128(K1)); + _mm_storeu_si128(DK_mm + 10, K0); + } + +/* +* AES-192 Encryption +*/ +BOTAN_FUNC_ISA("ssse3,aes") +void AES_192::aesni_encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const + { + BOTAN_ASSERT(m_EK.empty() == false, "Key was set"); + + const __m128i* in_mm = reinterpret_cast(in); + __m128i* out_mm = reinterpret_cast<__m128i*>(out); + + const __m128i* key_mm = reinterpret_cast(m_EK.data()); + + const __m128i K0 = _mm_loadu_si128(key_mm); + const __m128i K1 = _mm_loadu_si128(key_mm + 1); + const __m128i K2 = _mm_loadu_si128(key_mm + 2); + const __m128i K3 = _mm_loadu_si128(key_mm + 3); + const __m128i K4 = _mm_loadu_si128(key_mm + 4); + const __m128i K5 = _mm_loadu_si128(key_mm + 5); + const __m128i K6 = _mm_loadu_si128(key_mm + 6); + const __m128i K7 = _mm_loadu_si128(key_mm + 7); + const __m128i K8 = _mm_loadu_si128(key_mm + 8); + const __m128i K9 = _mm_loadu_si128(key_mm + 9); + const __m128i K10 = _mm_loadu_si128(key_mm + 10); + const __m128i K11 = _mm_loadu_si128(key_mm + 11); + const __m128i K12 = _mm_loadu_si128(key_mm + 12); + + while(blocks >= 4) + { + __m128i B0 = _mm_loadu_si128(in_mm + 0); + __m128i B1 = _mm_loadu_si128(in_mm + 1); + __m128i B2 = _mm_loadu_si128(in_mm + 2); + __m128i B3 = _mm_loadu_si128(in_mm + 3); + + B0 = _mm_xor_si128(B0, K0); + B1 = _mm_xor_si128(B1, K0); + B2 = _mm_xor_si128(B2, K0); + B3 = _mm_xor_si128(B3, K0); + + AES_ENC_4_ROUNDS(K1); + AES_ENC_4_ROUNDS(K2); + AES_ENC_4_ROUNDS(K3); + AES_ENC_4_ROUNDS(K4); + AES_ENC_4_ROUNDS(K5); + AES_ENC_4_ROUNDS(K6); + AES_ENC_4_ROUNDS(K7); + AES_ENC_4_ROUNDS(K8); + AES_ENC_4_ROUNDS(K9); + AES_ENC_4_ROUNDS(K10); + AES_ENC_4_ROUNDS(K11); + AES_ENC_4_LAST_ROUNDS(K12); + + _mm_storeu_si128(out_mm + 0, B0); + _mm_storeu_si128(out_mm + 1, B1); + _mm_storeu_si128(out_mm + 2, B2); + _mm_storeu_si128(out_mm + 3, B3); + + blocks -= 4; + in_mm += 4; + out_mm += 4; + } + + for(size_t i = 0; i != blocks; ++i) + { + __m128i B = _mm_loadu_si128(in_mm + i); + + B = _mm_xor_si128(B, K0); + + B = _mm_aesenc_si128(B, K1); + B = _mm_aesenc_si128(B, K2); + B = _mm_aesenc_si128(B, K3); + B = _mm_aesenc_si128(B, K4); + B = _mm_aesenc_si128(B, K5); + B = _mm_aesenc_si128(B, K6); + B = _mm_aesenc_si128(B, K7); + B = _mm_aesenc_si128(B, K8); + B = _mm_aesenc_si128(B, K9); + B = _mm_aesenc_si128(B, K10); + B = _mm_aesenc_si128(B, K11); + B = _mm_aesenclast_si128(B, K12); + + _mm_storeu_si128(out_mm + i, B); + } + } + +/* +* AES-192 Decryption +*/ +BOTAN_FUNC_ISA("ssse3,aes") +void AES_192::aesni_decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const + { + BOTAN_ASSERT(m_DK.empty() == false, "Key was set"); + + const __m128i* in_mm = reinterpret_cast(in); + __m128i* out_mm = reinterpret_cast<__m128i*>(out); + + const __m128i* key_mm = reinterpret_cast(m_DK.data()); + + const __m128i K0 = _mm_loadu_si128(key_mm); + const __m128i K1 = _mm_loadu_si128(key_mm + 1); + const __m128i K2 = _mm_loadu_si128(key_mm + 2); + const __m128i K3 = _mm_loadu_si128(key_mm + 3); + const __m128i K4 = _mm_loadu_si128(key_mm + 4); + const __m128i K5 = _mm_loadu_si128(key_mm + 5); + const __m128i K6 = _mm_loadu_si128(key_mm + 6); + const __m128i K7 = _mm_loadu_si128(key_mm + 7); + const __m128i K8 = _mm_loadu_si128(key_mm + 8); + const __m128i K9 = _mm_loadu_si128(key_mm + 9); + const __m128i K10 = _mm_loadu_si128(key_mm + 10); + const __m128i K11 = _mm_loadu_si128(key_mm + 11); + const __m128i K12 = _mm_loadu_si128(key_mm + 12); + + while(blocks >= 4) + { + __m128i B0 = _mm_loadu_si128(in_mm + 0); + __m128i B1 = _mm_loadu_si128(in_mm + 1); + __m128i B2 = _mm_loadu_si128(in_mm + 2); + __m128i B3 = _mm_loadu_si128(in_mm + 3); + + B0 = _mm_xor_si128(B0, K0); + B1 = _mm_xor_si128(B1, K0); + B2 = _mm_xor_si128(B2, K0); + B3 = _mm_xor_si128(B3, K0); + + AES_DEC_4_ROUNDS(K1); + AES_DEC_4_ROUNDS(K2); + AES_DEC_4_ROUNDS(K3); + AES_DEC_4_ROUNDS(K4); + AES_DEC_4_ROUNDS(K5); + AES_DEC_4_ROUNDS(K6); + AES_DEC_4_ROUNDS(K7); + AES_DEC_4_ROUNDS(K8); + AES_DEC_4_ROUNDS(K9); + AES_DEC_4_ROUNDS(K10); + AES_DEC_4_ROUNDS(K11); + AES_DEC_4_LAST_ROUNDS(K12); + + _mm_storeu_si128(out_mm + 0, B0); + _mm_storeu_si128(out_mm + 1, B1); + _mm_storeu_si128(out_mm + 2, B2); + _mm_storeu_si128(out_mm + 3, B3); + + blocks -= 4; + in_mm += 4; + out_mm += 4; + } + + for(size_t i = 0; i != blocks; ++i) + { + __m128i B = _mm_loadu_si128(in_mm + i); + + B = _mm_xor_si128(B, K0); + + B = _mm_aesdec_si128(B, K1); + B = _mm_aesdec_si128(B, K2); + B = _mm_aesdec_si128(B, K3); + B = _mm_aesdec_si128(B, K4); + B = _mm_aesdec_si128(B, K5); + B = _mm_aesdec_si128(B, K6); + B = _mm_aesdec_si128(B, K7); + B = _mm_aesdec_si128(B, K8); + B = _mm_aesdec_si128(B, K9); + B = _mm_aesdec_si128(B, K10); + B = _mm_aesdec_si128(B, K11); + B = _mm_aesdeclast_si128(B, K12); + + _mm_storeu_si128(out_mm + i, B); + } + } + +/* +* AES-192 Key Schedule +*/ +BOTAN_FUNC_ISA("ssse3,aes") +void AES_192::aesni_key_schedule(const uint8_t key[], size_t) + { + m_EK.resize(52); + m_DK.resize(52); + + __m128i K0 = _mm_loadu_si128(reinterpret_cast(key)); + __m128i K1 = _mm_loadu_si128(reinterpret_cast(key + 8)); + K1 = _mm_srli_si128(K1, 8); + + load_le(m_EK.data(), key, 6); + + #define AES_192_key_exp(RCON, EK_OFF) \ + aes_192_key_expansion(&K0, &K1, \ + _mm_aeskeygenassist_si128(K1, RCON), \ + &m_EK[EK_OFF], EK_OFF == 48) + + AES_192_key_exp(0x01, 6); + AES_192_key_exp(0x02, 12); + AES_192_key_exp(0x04, 18); + AES_192_key_exp(0x08, 24); + AES_192_key_exp(0x10, 30); + AES_192_key_exp(0x20, 36); + AES_192_key_exp(0x40, 42); + AES_192_key_exp(0x80, 48); + + #undef AES_192_key_exp + + // Now generate decryption keys + const __m128i* EK_mm = reinterpret_cast(m_EK.data()); + + __m128i* DK_mm = reinterpret_cast<__m128i*>(m_DK.data()); + _mm_storeu_si128(DK_mm , _mm_loadu_si128(EK_mm + 12)); + _mm_storeu_si128(DK_mm + 1, _mm_aesimc_si128(_mm_loadu_si128(EK_mm + 11))); + _mm_storeu_si128(DK_mm + 2, _mm_aesimc_si128(_mm_loadu_si128(EK_mm + 10))); + _mm_storeu_si128(DK_mm + 3, _mm_aesimc_si128(_mm_loadu_si128(EK_mm + 9))); + _mm_storeu_si128(DK_mm + 4, _mm_aesimc_si128(_mm_loadu_si128(EK_mm + 8))); + _mm_storeu_si128(DK_mm + 5, _mm_aesimc_si128(_mm_loadu_si128(EK_mm + 7))); + _mm_storeu_si128(DK_mm + 6, _mm_aesimc_si128(_mm_loadu_si128(EK_mm + 6))); + _mm_storeu_si128(DK_mm + 7, _mm_aesimc_si128(_mm_loadu_si128(EK_mm + 5))); + _mm_storeu_si128(DK_mm + 8, _mm_aesimc_si128(_mm_loadu_si128(EK_mm + 4))); + _mm_storeu_si128(DK_mm + 9, _mm_aesimc_si128(_mm_loadu_si128(EK_mm + 3))); + _mm_storeu_si128(DK_mm + 10, _mm_aesimc_si128(_mm_loadu_si128(EK_mm + 2))); + _mm_storeu_si128(DK_mm + 11, _mm_aesimc_si128(_mm_loadu_si128(EK_mm + 1))); + _mm_storeu_si128(DK_mm + 12, _mm_loadu_si128(EK_mm + 0)); + } + +/* +* AES-256 Encryption +*/ +BOTAN_FUNC_ISA("ssse3,aes") +void AES_256::aesni_encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const + { + BOTAN_ASSERT(m_EK.empty() == false, "Key was set"); + + const __m128i* in_mm = reinterpret_cast(in); + __m128i* out_mm = reinterpret_cast<__m128i*>(out); + + const __m128i* key_mm = reinterpret_cast(m_EK.data()); + + const __m128i K0 = _mm_loadu_si128(key_mm); + const __m128i K1 = _mm_loadu_si128(key_mm + 1); + const __m128i K2 = _mm_loadu_si128(key_mm + 2); + const __m128i K3 = _mm_loadu_si128(key_mm + 3); + const __m128i K4 = _mm_loadu_si128(key_mm + 4); + const __m128i K5 = _mm_loadu_si128(key_mm + 5); + const __m128i K6 = _mm_loadu_si128(key_mm + 6); + const __m128i K7 = _mm_loadu_si128(key_mm + 7); + const __m128i K8 = _mm_loadu_si128(key_mm + 8); + const __m128i K9 = _mm_loadu_si128(key_mm + 9); + const __m128i K10 = _mm_loadu_si128(key_mm + 10); + const __m128i K11 = _mm_loadu_si128(key_mm + 11); + const __m128i K12 = _mm_loadu_si128(key_mm + 12); + const __m128i K13 = _mm_loadu_si128(key_mm + 13); + const __m128i K14 = _mm_loadu_si128(key_mm + 14); + + while(blocks >= 4) + { + __m128i B0 = _mm_loadu_si128(in_mm + 0); + __m128i B1 = _mm_loadu_si128(in_mm + 1); + __m128i B2 = _mm_loadu_si128(in_mm + 2); + __m128i B3 = _mm_loadu_si128(in_mm + 3); + + B0 = _mm_xor_si128(B0, K0); + B1 = _mm_xor_si128(B1, K0); + B2 = _mm_xor_si128(B2, K0); + B3 = _mm_xor_si128(B3, K0); + + AES_ENC_4_ROUNDS(K1); + AES_ENC_4_ROUNDS(K2); + AES_ENC_4_ROUNDS(K3); + AES_ENC_4_ROUNDS(K4); + AES_ENC_4_ROUNDS(K5); + AES_ENC_4_ROUNDS(K6); + AES_ENC_4_ROUNDS(K7); + AES_ENC_4_ROUNDS(K8); + AES_ENC_4_ROUNDS(K9); + AES_ENC_4_ROUNDS(K10); + AES_ENC_4_ROUNDS(K11); + AES_ENC_4_ROUNDS(K12); + AES_ENC_4_ROUNDS(K13); + AES_ENC_4_LAST_ROUNDS(K14); + + _mm_storeu_si128(out_mm + 0, B0); + _mm_storeu_si128(out_mm + 1, B1); + _mm_storeu_si128(out_mm + 2, B2); + _mm_storeu_si128(out_mm + 3, B3); + + blocks -= 4; + in_mm += 4; + out_mm += 4; + } + + for(size_t i = 0; i != blocks; ++i) + { + __m128i B = _mm_loadu_si128(in_mm + i); + + B = _mm_xor_si128(B, K0); + + B = _mm_aesenc_si128(B, K1); + B = _mm_aesenc_si128(B, K2); + B = _mm_aesenc_si128(B, K3); + B = _mm_aesenc_si128(B, K4); + B = _mm_aesenc_si128(B, K5); + B = _mm_aesenc_si128(B, K6); + B = _mm_aesenc_si128(B, K7); + B = _mm_aesenc_si128(B, K8); + B = _mm_aesenc_si128(B, K9); + B = _mm_aesenc_si128(B, K10); + B = _mm_aesenc_si128(B, K11); + B = _mm_aesenc_si128(B, K12); + B = _mm_aesenc_si128(B, K13); + B = _mm_aesenclast_si128(B, K14); + + _mm_storeu_si128(out_mm + i, B); + } + } + +/* +* AES-256 Decryption +*/ +BOTAN_FUNC_ISA("ssse3,aes") +void AES_256::aesni_decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const + { + BOTAN_ASSERT(m_DK.empty() == false, "Key was set"); + + const __m128i* in_mm = reinterpret_cast(in); + __m128i* out_mm = reinterpret_cast<__m128i*>(out); + + const __m128i* key_mm = reinterpret_cast(m_DK.data()); + + const __m128i K0 = _mm_loadu_si128(key_mm); + const __m128i K1 = _mm_loadu_si128(key_mm + 1); + const __m128i K2 = _mm_loadu_si128(key_mm + 2); + const __m128i K3 = _mm_loadu_si128(key_mm + 3); + const __m128i K4 = _mm_loadu_si128(key_mm + 4); + const __m128i K5 = _mm_loadu_si128(key_mm + 5); + const __m128i K6 = _mm_loadu_si128(key_mm + 6); + const __m128i K7 = _mm_loadu_si128(key_mm + 7); + const __m128i K8 = _mm_loadu_si128(key_mm + 8); + const __m128i K9 = _mm_loadu_si128(key_mm + 9); + const __m128i K10 = _mm_loadu_si128(key_mm + 10); + const __m128i K11 = _mm_loadu_si128(key_mm + 11); + const __m128i K12 = _mm_loadu_si128(key_mm + 12); + const __m128i K13 = _mm_loadu_si128(key_mm + 13); + const __m128i K14 = _mm_loadu_si128(key_mm + 14); + + while(blocks >= 4) + { + __m128i B0 = _mm_loadu_si128(in_mm + 0); + __m128i B1 = _mm_loadu_si128(in_mm + 1); + __m128i B2 = _mm_loadu_si128(in_mm + 2); + __m128i B3 = _mm_loadu_si128(in_mm + 3); + + B0 = _mm_xor_si128(B0, K0); + B1 = _mm_xor_si128(B1, K0); + B2 = _mm_xor_si128(B2, K0); + B3 = _mm_xor_si128(B3, K0); + + AES_DEC_4_ROUNDS(K1); + AES_DEC_4_ROUNDS(K2); + AES_DEC_4_ROUNDS(K3); + AES_DEC_4_ROUNDS(K4); + AES_DEC_4_ROUNDS(K5); + AES_DEC_4_ROUNDS(K6); + AES_DEC_4_ROUNDS(K7); + AES_DEC_4_ROUNDS(K8); + AES_DEC_4_ROUNDS(K9); + AES_DEC_4_ROUNDS(K10); + AES_DEC_4_ROUNDS(K11); + AES_DEC_4_ROUNDS(K12); + AES_DEC_4_ROUNDS(K13); + AES_DEC_4_LAST_ROUNDS(K14); + + _mm_storeu_si128(out_mm + 0, B0); + _mm_storeu_si128(out_mm + 1, B1); + _mm_storeu_si128(out_mm + 2, B2); + _mm_storeu_si128(out_mm + 3, B3); + + blocks -= 4; + in_mm += 4; + out_mm += 4; + } + + for(size_t i = 0; i != blocks; ++i) + { + __m128i B = _mm_loadu_si128(in_mm + i); + + B = _mm_xor_si128(B, K0); + + B = _mm_aesdec_si128(B, K1); + B = _mm_aesdec_si128(B, K2); + B = _mm_aesdec_si128(B, K3); + B = _mm_aesdec_si128(B, K4); + B = _mm_aesdec_si128(B, K5); + B = _mm_aesdec_si128(B, K6); + B = _mm_aesdec_si128(B, K7); + B = _mm_aesdec_si128(B, K8); + B = _mm_aesdec_si128(B, K9); + B = _mm_aesdec_si128(B, K10); + B = _mm_aesdec_si128(B, K11); + B = _mm_aesdec_si128(B, K12); + B = _mm_aesdec_si128(B, K13); + B = _mm_aesdeclast_si128(B, K14); + + _mm_storeu_si128(out_mm + i, B); + } + } + +/* +* AES-256 Key Schedule +*/ +BOTAN_FUNC_ISA("ssse3,aes") +void AES_256::aesni_key_schedule(const uint8_t key[], size_t) + { + m_EK.resize(60); + m_DK.resize(60); + + const __m128i K0 = _mm_loadu_si128(reinterpret_cast(key)); + const __m128i K1 = _mm_loadu_si128(reinterpret_cast(key + 16)); + + const __m128i K2 = aes_128_key_expansion(K0, _mm_aeskeygenassist_si128(K1, 0x01)); + const __m128i K3 = aes_256_key_expansion(K1, K2); + + const __m128i K4 = aes_128_key_expansion(K2, _mm_aeskeygenassist_si128(K3, 0x02)); + const __m128i K5 = aes_256_key_expansion(K3, K4); + + const __m128i K6 = aes_128_key_expansion(K4, _mm_aeskeygenassist_si128(K5, 0x04)); + const __m128i K7 = aes_256_key_expansion(K5, K6); + + const __m128i K8 = aes_128_key_expansion(K6, _mm_aeskeygenassist_si128(K7, 0x08)); + const __m128i K9 = aes_256_key_expansion(K7, K8); + + const __m128i K10 = aes_128_key_expansion(K8, _mm_aeskeygenassist_si128(K9, 0x10)); + const __m128i K11 = aes_256_key_expansion(K9, K10); + + const __m128i K12 = aes_128_key_expansion(K10, _mm_aeskeygenassist_si128(K11, 0x20)); + const __m128i K13 = aes_256_key_expansion(K11, K12); + + const __m128i K14 = aes_128_key_expansion(K12, _mm_aeskeygenassist_si128(K13, 0x40)); + + __m128i* EK_mm = reinterpret_cast<__m128i*>(m_EK.data()); + _mm_storeu_si128(EK_mm , K0); + _mm_storeu_si128(EK_mm + 1, K1); + _mm_storeu_si128(EK_mm + 2, K2); + _mm_storeu_si128(EK_mm + 3, K3); + _mm_storeu_si128(EK_mm + 4, K4); + _mm_storeu_si128(EK_mm + 5, K5); + _mm_storeu_si128(EK_mm + 6, K6); + _mm_storeu_si128(EK_mm + 7, K7); + _mm_storeu_si128(EK_mm + 8, K8); + _mm_storeu_si128(EK_mm + 9, K9); + _mm_storeu_si128(EK_mm + 10, K10); + _mm_storeu_si128(EK_mm + 11, K11); + _mm_storeu_si128(EK_mm + 12, K12); + _mm_storeu_si128(EK_mm + 13, K13); + _mm_storeu_si128(EK_mm + 14, K14); + + // Now generate decryption keys + __m128i* DK_mm = reinterpret_cast<__m128i*>(m_DK.data()); + _mm_storeu_si128(DK_mm , K14); + _mm_storeu_si128(DK_mm + 1, _mm_aesimc_si128(K13)); + _mm_storeu_si128(DK_mm + 2, _mm_aesimc_si128(K12)); + _mm_storeu_si128(DK_mm + 3, _mm_aesimc_si128(K11)); + _mm_storeu_si128(DK_mm + 4, _mm_aesimc_si128(K10)); + _mm_storeu_si128(DK_mm + 5, _mm_aesimc_si128(K9)); + _mm_storeu_si128(DK_mm + 6, _mm_aesimc_si128(K8)); + _mm_storeu_si128(DK_mm + 7, _mm_aesimc_si128(K7)); + _mm_storeu_si128(DK_mm + 8, _mm_aesimc_si128(K6)); + _mm_storeu_si128(DK_mm + 9, _mm_aesimc_si128(K5)); + _mm_storeu_si128(DK_mm + 10, _mm_aesimc_si128(K4)); + _mm_storeu_si128(DK_mm + 11, _mm_aesimc_si128(K3)); + _mm_storeu_si128(DK_mm + 12, _mm_aesimc_si128(K2)); + _mm_storeu_si128(DK_mm + 13, _mm_aesimc_si128(K1)); + _mm_storeu_si128(DK_mm + 14, K0); + } + +#undef AES_ENC_4_ROUNDS +#undef AES_ENC_4_LAST_ROUNDS +#undef AES_DEC_4_ROUNDS +#undef AES_DEC_4_LAST_ROUNDS + +} 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 new file mode 100644 index 0000000000..d5d3593489 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/block/aes/aes_ni/info.txt @@ -0,0 +1,7 @@ + +AES_NI -> 20131128 + + +load_on auto + +need_isa aesni diff --git a/src/libs/3rdparty/botan/src/lib/block/aes/aes_power8/aes_power8.cpp b/src/libs/3rdparty/botan/src/lib/block/aes/aes_power8/aes_power8.cpp new file mode 100644 index 0000000000..98520a13cf --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/block/aes/aes_power8/aes_power8.cpp @@ -0,0 +1,328 @@ +/* +* AES using POWER8 crypto extensions +* +* Contributed by Jeffrey Walton +* +* Further changes +* (C) 2018 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include + +#include +#undef vector +#undef bool + +namespace Botan { + +namespace { + +__vector unsigned long long LoadKey(const uint32_t* src) + { + __vector unsigned int vec = vec_vsx_ld(0, src); + + if(CPUID::is_little_endian()) + { + const __vector unsigned char mask = {12,13,14,15, 8,9,10,11, 4,5,6,7, 0,1,2,3}; + const __vector unsigned char zero = {0}; + return (__vector unsigned long long)vec_perm((__vector unsigned char)vec, zero, mask); + } + else + { + return (__vector unsigned long long)vec; + } + } + +__vector unsigned char Reverse8x16(const __vector unsigned char src) + { + if(CPUID::is_little_endian()) + { + const __vector unsigned char mask = {15,14,13,12, 11,10,9,8, 7,6,5,4, 3,2,1,0}; + const __vector unsigned char zero = {0}; + return vec_perm(src, zero, mask); + } + else + { + return src; + } + } + +__vector unsigned long long LoadBlock(const uint8_t* src) + { + return (__vector unsigned long long)Reverse8x16(vec_vsx_ld(0, src)); + } + +void StoreBlock(const __vector unsigned long long src, uint8_t* dest) + { + vec_vsx_st(Reverse8x16((__vector unsigned char)src), 0, dest); + } + +} + +BOTAN_FUNC_ISA("crypto") +void AES_128::power8_encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const + { + BOTAN_ASSERT(m_EK.empty() == false, "Key was set"); + + const __vector unsigned long long K0 = LoadKey(&m_EK[0]); + const __vector unsigned long long K1 = LoadKey(&m_EK[4]); + const __vector unsigned long long K2 = LoadKey(&m_EK[8]); + const __vector unsigned long long K3 = LoadKey(&m_EK[12]); + const __vector unsigned long long K4 = LoadKey(&m_EK[16]); + const __vector unsigned long long K5 = LoadKey(&m_EK[20]); + const __vector unsigned long long K6 = LoadKey(&m_EK[24]); + const __vector unsigned long long K7 = LoadKey(&m_EK[28]); + const __vector unsigned long long K8 = LoadKey(&m_EK[32]); + const __vector unsigned long long K9 = LoadKey(&m_EK[36]); + const __vector unsigned long long K10 = LoadBlock(m_ME.data()); + + for(size_t i = 0; i != blocks; ++i) + { + __vector unsigned long long B = LoadBlock(in); + + B = vec_xor(B, K0); + B = __builtin_crypto_vcipher(B, K1); + B = __builtin_crypto_vcipher(B, K2); + B = __builtin_crypto_vcipher(B, K3); + B = __builtin_crypto_vcipher(B, K4); + B = __builtin_crypto_vcipher(B, K5); + B = __builtin_crypto_vcipher(B, K6); + B = __builtin_crypto_vcipher(B, K7); + B = __builtin_crypto_vcipher(B, K8); + B = __builtin_crypto_vcipher(B, K9); + B = __builtin_crypto_vcipherlast(B, K10); + + StoreBlock(B, out); + + out += 16; + in += 16; + } + } + +BOTAN_FUNC_ISA("crypto") +void AES_128::power8_decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const + { + BOTAN_ASSERT(m_EK.empty() == false, "Key was set"); + + const __vector unsigned long long K0 = LoadBlock(m_ME.data()); + const __vector unsigned long long K1 = LoadKey(&m_EK[36]); + const __vector unsigned long long K2 = LoadKey(&m_EK[32]); + const __vector unsigned long long K3 = LoadKey(&m_EK[28]); + const __vector unsigned long long K4 = LoadKey(&m_EK[24]); + const __vector unsigned long long K5 = LoadKey(&m_EK[20]); + const __vector unsigned long long K6 = LoadKey(&m_EK[16]); + const __vector unsigned long long K7 = LoadKey(&m_EK[12]); + const __vector unsigned long long K8 = LoadKey(&m_EK[8]); + const __vector unsigned long long K9 = LoadKey(&m_EK[4]); + const __vector unsigned long long K10 = LoadKey(&m_EK[0]); + + for(size_t i = 0; i != blocks; ++i) + { + __vector unsigned long long B = LoadBlock(in); + + B = vec_xor(B, K0); + B = __builtin_crypto_vncipher(B, K1); + B = __builtin_crypto_vncipher(B, K2); + B = __builtin_crypto_vncipher(B, K3); + B = __builtin_crypto_vncipher(B, K4); + B = __builtin_crypto_vncipher(B, K5); + B = __builtin_crypto_vncipher(B, K6); + B = __builtin_crypto_vncipher(B, K7); + B = __builtin_crypto_vncipher(B, K8); + B = __builtin_crypto_vncipher(B, K9); + B = __builtin_crypto_vncipherlast(B, K10); + + StoreBlock(B, out); + + out += 16; + in += 16; + } + } + +BOTAN_FUNC_ISA("crypto") +void AES_192::power8_encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const + { + BOTAN_ASSERT(m_EK.empty() == false, "Key was set"); + + const __vector unsigned long long K0 = LoadKey(&m_EK[0]); + const __vector unsigned long long K1 = LoadKey(&m_EK[4]); + const __vector unsigned long long K2 = LoadKey(&m_EK[8]); + const __vector unsigned long long K3 = LoadKey(&m_EK[12]); + const __vector unsigned long long K4 = LoadKey(&m_EK[16]); + const __vector unsigned long long K5 = LoadKey(&m_EK[20]); + const __vector unsigned long long K6 = LoadKey(&m_EK[24]); + const __vector unsigned long long K7 = LoadKey(&m_EK[28]); + const __vector unsigned long long K8 = LoadKey(&m_EK[32]); + const __vector unsigned long long K9 = LoadKey(&m_EK[36]); + const __vector unsigned long long K10 = LoadKey(&m_EK[40]); + const __vector unsigned long long K11 = LoadKey(&m_EK[44]); + const __vector unsigned long long K12 = LoadBlock(m_ME.data()); + + for(size_t i = 0; i != blocks; ++i) + { + __vector unsigned long long B = LoadBlock(in); + + B = vec_xor(B, K0); + B = __builtin_crypto_vcipher(B, K1); + B = __builtin_crypto_vcipher(B, K2); + B = __builtin_crypto_vcipher(B, K3); + B = __builtin_crypto_vcipher(B, K4); + B = __builtin_crypto_vcipher(B, K5); + B = __builtin_crypto_vcipher(B, K6); + B = __builtin_crypto_vcipher(B, K7); + B = __builtin_crypto_vcipher(B, K8); + B = __builtin_crypto_vcipher(B, K9); + B = __builtin_crypto_vcipher(B, K10); + B = __builtin_crypto_vcipher(B, K11); + B = __builtin_crypto_vcipherlast(B, K12); + + StoreBlock(B, out); + + out += 16; + in += 16; + } + } + +BOTAN_FUNC_ISA("crypto") +void AES_192::power8_decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const + { + BOTAN_ASSERT(m_EK.empty() == false, "Key was set"); + + const __vector unsigned long long K0 = LoadBlock(m_ME.data()); + const __vector unsigned long long K1 = LoadKey(&m_EK[44]); + const __vector unsigned long long K2 = LoadKey(&m_EK[40]); + const __vector unsigned long long K3 = LoadKey(&m_EK[36]); + const __vector unsigned long long K4 = LoadKey(&m_EK[32]); + const __vector unsigned long long K5 = LoadKey(&m_EK[28]); + const __vector unsigned long long K6 = LoadKey(&m_EK[24]); + const __vector unsigned long long K7 = LoadKey(&m_EK[20]); + const __vector unsigned long long K8 = LoadKey(&m_EK[16]); + const __vector unsigned long long K9 = LoadKey(&m_EK[12]); + const __vector unsigned long long K10 = LoadKey(&m_EK[8]); + const __vector unsigned long long K11 = LoadKey(&m_EK[4]); + const __vector unsigned long long K12 = LoadKey(&m_EK[0]); + + for(size_t i = 0; i != blocks; ++i) + { + __vector unsigned long long B = LoadBlock(in); + + B = vec_xor(B, K0); + B = __builtin_crypto_vncipher(B, K1); + B = __builtin_crypto_vncipher(B, K2); + B = __builtin_crypto_vncipher(B, K3); + B = __builtin_crypto_vncipher(B, K4); + B = __builtin_crypto_vncipher(B, K5); + B = __builtin_crypto_vncipher(B, K6); + B = __builtin_crypto_vncipher(B, K7); + B = __builtin_crypto_vncipher(B, K8); + B = __builtin_crypto_vncipher(B, K9); + B = __builtin_crypto_vncipher(B, K10); + B = __builtin_crypto_vncipher(B, K11); + B = __builtin_crypto_vncipherlast(B, K12); + + StoreBlock(B, out); + + out += 16; + in += 16; + } + } + +BOTAN_FUNC_ISA("crypto") +void AES_256::power8_encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const + { + BOTAN_ASSERT(m_EK.empty() == false, "Key was set"); + const __vector unsigned long long K0 = LoadKey(&m_EK[0]); + const __vector unsigned long long K1 = LoadKey(&m_EK[4]); + const __vector unsigned long long K2 = LoadKey(&m_EK[8]); + const __vector unsigned long long K3 = LoadKey(&m_EK[12]); + const __vector unsigned long long K4 = LoadKey(&m_EK[16]); + const __vector unsigned long long K5 = LoadKey(&m_EK[20]); + const __vector unsigned long long K6 = LoadKey(&m_EK[24]); + const __vector unsigned long long K7 = LoadKey(&m_EK[28]); + const __vector unsigned long long K8 = LoadKey(&m_EK[32]); + const __vector unsigned long long K9 = LoadKey(&m_EK[36]); + const __vector unsigned long long K10 = LoadKey(&m_EK[40]); + const __vector unsigned long long K11 = LoadKey(&m_EK[44]); + const __vector unsigned long long K12 = LoadKey(&m_EK[48]); + const __vector unsigned long long K13 = LoadKey(&m_EK[52]); + const __vector unsigned long long K14 = LoadBlock(m_ME.data()); + + for(size_t i = 0; i != blocks; ++i) + { + __vector unsigned long long B = LoadBlock(in); + + B = vec_xor(B, K0); + B = __builtin_crypto_vcipher(B, K1); + B = __builtin_crypto_vcipher(B, K2); + B = __builtin_crypto_vcipher(B, K3); + B = __builtin_crypto_vcipher(B, K4); + B = __builtin_crypto_vcipher(B, K5); + B = __builtin_crypto_vcipher(B, K6); + B = __builtin_crypto_vcipher(B, K7); + B = __builtin_crypto_vcipher(B, K8); + B = __builtin_crypto_vcipher(B, K9); + B = __builtin_crypto_vcipher(B, K10); + B = __builtin_crypto_vcipher(B, K11); + B = __builtin_crypto_vcipher(B, K12); + B = __builtin_crypto_vcipher(B, K13); + B = __builtin_crypto_vcipherlast(B, K14); + + StoreBlock(B, out); + + out += 16; + in += 16; + } + } + +BOTAN_FUNC_ISA("crypto") +void AES_256::power8_decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const + { + BOTAN_ASSERT(m_EK.empty() == false, "Key was set"); + + const __vector unsigned long long K0 = LoadBlock(m_ME.data()); + const __vector unsigned long long K1 = LoadKey(&m_EK[52]); + const __vector unsigned long long K2 = LoadKey(&m_EK[48]); + const __vector unsigned long long K3 = LoadKey(&m_EK[44]); + const __vector unsigned long long K4 = LoadKey(&m_EK[40]); + const __vector unsigned long long K5 = LoadKey(&m_EK[36]); + const __vector unsigned long long K6 = LoadKey(&m_EK[32]); + const __vector unsigned long long K7 = LoadKey(&m_EK[28]); + const __vector unsigned long long K8 = LoadKey(&m_EK[24]); + const __vector unsigned long long K9 = LoadKey(&m_EK[20]); + const __vector unsigned long long K10 = LoadKey(&m_EK[16]); + const __vector unsigned long long K11 = LoadKey(&m_EK[12]); + const __vector unsigned long long K12 = LoadKey(&m_EK[8]); + const __vector unsigned long long K13 = LoadKey(&m_EK[4]); + const __vector unsigned long long K14 = LoadKey(&m_EK[0]); + + for(size_t i = 0; i != blocks; ++i) + { + __vector unsigned long long B = LoadBlock(in); + + B = vec_xor(B, K0); + B = __builtin_crypto_vncipher(B, K1); + B = __builtin_crypto_vncipher(B, K2); + B = __builtin_crypto_vncipher(B, K3); + B = __builtin_crypto_vncipher(B, K4); + B = __builtin_crypto_vncipher(B, K5); + B = __builtin_crypto_vncipher(B, K6); + B = __builtin_crypto_vncipher(B, K7); + B = __builtin_crypto_vncipher(B, K8); + B = __builtin_crypto_vncipher(B, K9); + B = __builtin_crypto_vncipher(B, K10); + B = __builtin_crypto_vncipher(B, K11); + B = __builtin_crypto_vncipher(B, K12); + B = __builtin_crypto_vncipher(B, K13); + B = __builtin_crypto_vncipherlast(B, K14); + + StoreBlock(B, out); + + out += 16; + in += 16; + } + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/block/aes/aes_power8/info.txt b/src/libs/3rdparty/botan/src/lib/block/aes/aes_power8/info.txt new file mode 100644 index 0000000000..6aa52d25a0 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/block/aes/aes_power8/info.txt @@ -0,0 +1,9 @@ + +AES_POWER8 -> 20180223 + + + +ppc64 + + +need_isa ppccrypto diff --git a/src/libs/3rdparty/botan/src/lib/block/aes/aes_ssse3/aes_ssse3.cpp b/src/libs/3rdparty/botan/src/lib/block/aes/aes_ssse3/aes_ssse3.cpp new file mode 100644 index 0000000000..47d70d0b8b --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/block/aes/aes_ssse3/aes_ssse3.cpp @@ -0,0 +1,637 @@ +/* +* AES using SSSE3 +* (C) 2010,2016 Jack Lloyd +* +* This is more or less a direct translation of public domain x86-64 +* assembly written by Mike Hamburg, described in "Accelerating AES +* with Vector Permute Instructions" (CHES 2009). His original code is +* available at https://crypto.stanford.edu/vpaes/ +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include + +namespace Botan { + +namespace { + +const __m128i low_nibs = _mm_set1_epi8(0x0F); + +const __m128i k_ipt1 = _mm_set_epi32( + 0xCABAE090, 0x52227808, 0xC2B2E898, 0x5A2A7000); +const __m128i k_ipt2 = _mm_set_epi32( + 0xCD80B1FC, 0xB0FDCC81, 0x4C01307D, 0x317C4D00); + +const __m128i k_inv1 = _mm_set_epi32( + 0x04070309, 0x0A0B0C02, 0x0E05060F, 0x0D080180); +const __m128i k_inv2 = _mm_set_epi32( + 0x030D0E0C, 0x02050809, 0x01040A06, 0x0F0B0780); + +const __m128i sb1u = _mm_set_epi32( + 0xA5DF7A6E, 0x142AF544, 0xB19BE18F, 0xCB503E00); +const __m128i sb1t = _mm_set_epi32( + 0x3BF7CCC1, 0x0D2ED9EF, 0x3618D415, 0xFAE22300); + +const __m128i mc_forward[4] = { + _mm_set_epi32(0x0C0F0E0D, 0x080B0A09, 0x04070605, 0x00030201), + _mm_set_epi32(0x00030201, 0x0C0F0E0D, 0x080B0A09, 0x04070605), + _mm_set_epi32(0x04070605, 0x00030201, 0x0C0F0E0D, 0x080B0A09), + _mm_set_epi32(0x080B0A09, 0x04070605, 0x00030201, 0x0C0F0E0D) +}; + +const __m128i sr[4] = { + _mm_set_epi32(0x0F0E0D0C, 0x0B0A0908, 0x07060504, 0x03020100), + _mm_set_epi32(0x0B06010C, 0x07020D08, 0x030E0904, 0x0F0A0500), + _mm_set_epi32(0x070E050C, 0x030A0108, 0x0F060D04, 0x0B020900), + _mm_set_epi32(0x0306090C, 0x0F020508, 0x0B0E0104, 0x070A0D00), +}; + +#define mm_xor3(x, y, z) _mm_xor_si128(x, _mm_xor_si128(y, z)) + +BOTAN_FUNC_ISA("ssse3") +__m128i aes_schedule_transform(__m128i input, + __m128i table_1, + __m128i table_2) + { + __m128i i_1 = _mm_and_si128(low_nibs, input); + __m128i i_2 = _mm_srli_epi32(_mm_andnot_si128(low_nibs, input), 4); + + return _mm_xor_si128( + _mm_shuffle_epi8(table_1, i_1), + _mm_shuffle_epi8(table_2, i_2)); + } + +BOTAN_FUNC_ISA("ssse3") +__m128i aes_schedule_mangle(__m128i k, uint8_t round_no) + { + __m128i t = _mm_shuffle_epi8(_mm_xor_si128(k, _mm_set1_epi8(0x5B)), + mc_forward[0]); + + __m128i t2 = t; + + t = _mm_shuffle_epi8(t, mc_forward[0]); + + t2 = mm_xor3(t2, t, _mm_shuffle_epi8(t, mc_forward[0])); + + return _mm_shuffle_epi8(t2, sr[round_no % 4]); + } + +BOTAN_FUNC_ISA("ssse3") +__m128i aes_schedule_192_smear(__m128i x, __m128i y) + { + return mm_xor3(y, + _mm_shuffle_epi32(x, 0xFE), + _mm_shuffle_epi32(y, 0x80)); + } + +BOTAN_FUNC_ISA("ssse3") +__m128i aes_schedule_mangle_dec(__m128i k, uint8_t round_no) + { + const __m128i dsk[8] = { + _mm_set_epi32(0x4AED9334, 0x82255BFC, 0xB6116FC8, 0x7ED9A700), + _mm_set_epi32(0x8BB89FAC, 0xE9DAFDCE, 0x45765162, 0x27143300), + _mm_set_epi32(0x4622EE8A, 0xADC90561, 0x27438FEB, 0xCCA86400), + _mm_set_epi32(0x73AEE13C, 0xBD602FF2, 0x815C13CE, 0x4F92DD00), + _mm_set_epi32(0xF83F3EF9, 0xFA3D3CFB, 0x03C4C502, 0x01C6C700), + _mm_set_epi32(0xA5526A9D, 0x7384BC4B, 0xEE1921D6, 0x38CFF700), + _mm_set_epi32(0xA080D3F3, 0x10306343, 0xE3C390B0, 0x53732000), + _mm_set_epi32(0x2F45AEC4, 0x8CE60D67, 0xA0CA214B, 0x036982E8) + }; + + __m128i t = aes_schedule_transform(k, dsk[0], dsk[1]); + __m128i output = _mm_shuffle_epi8(t, mc_forward[0]); + + t = aes_schedule_transform(t, dsk[2], dsk[3]); + output = _mm_shuffle_epi8(_mm_xor_si128(t, output), mc_forward[0]); + + t = aes_schedule_transform(t, dsk[4], dsk[5]); + output = _mm_shuffle_epi8(_mm_xor_si128(t, output), mc_forward[0]); + + t = aes_schedule_transform(t, dsk[6], dsk[7]); + output = _mm_shuffle_epi8(_mm_xor_si128(t, output), mc_forward[0]); + + return _mm_shuffle_epi8(output, sr[round_no % 4]); + } + +BOTAN_FUNC_ISA("ssse3") +__m128i aes_schedule_mangle_last(__m128i k, uint8_t round_no) + { + const __m128i out_tr1 = _mm_set_epi32( + 0xF7974121, 0xDEBE6808, 0xFF9F4929, 0xD6B66000); + const __m128i out_tr2 = _mm_set_epi32( + 0xE10D5DB1, 0xB05C0CE0, 0x01EDBD51, 0x50BCEC00); + + k = _mm_shuffle_epi8(k, sr[round_no % 4]); + k = _mm_xor_si128(k, _mm_set1_epi8(0x5B)); + return aes_schedule_transform(k, out_tr1, out_tr2); + } + +BOTAN_FUNC_ISA("ssse3") +__m128i aes_schedule_mangle_last_dec(__m128i k) + { + const __m128i deskew1 = _mm_set_epi32( + 0x1DFEB95A, 0x5DBEF91A, 0x07E4A340, 0x47A4E300); + const __m128i deskew2 = _mm_set_epi32( + 0x2841C2AB, 0xF49D1E77, 0x5F36B5DC, 0x83EA6900); + + k = _mm_xor_si128(k, _mm_set1_epi8(0x5B)); + return aes_schedule_transform(k, deskew1, deskew2); + } + +BOTAN_FUNC_ISA("ssse3") +__m128i aes_schedule_round(__m128i* rcon, __m128i input1, __m128i input2) + { + if(rcon) + { + input2 = _mm_xor_si128(_mm_alignr_epi8(_mm_setzero_si128(), *rcon, 15), + input2); + + *rcon = _mm_alignr_epi8(*rcon, *rcon, 15); // next rcon + + input1 = _mm_shuffle_epi32(input1, 0xFF); // rotate + input1 = _mm_alignr_epi8(input1, input1, 1); + } + + __m128i smeared = _mm_xor_si128(input2, _mm_slli_si128(input2, 4)); + smeared = mm_xor3(smeared, _mm_slli_si128(smeared, 8), _mm_set1_epi8(0x5B)); + + __m128i t = _mm_srli_epi32(_mm_andnot_si128(low_nibs, input1), 4); + + input1 = _mm_and_si128(low_nibs, input1); + + __m128i t2 = _mm_shuffle_epi8(k_inv2, input1); + + input1 = _mm_xor_si128(input1, t); + + __m128i t3 = _mm_xor_si128(t2, _mm_shuffle_epi8(k_inv1, t)); + __m128i t4 = _mm_xor_si128(t2, _mm_shuffle_epi8(k_inv1, input1)); + + __m128i t5 = _mm_xor_si128(input1, _mm_shuffle_epi8(k_inv1, t3)); + __m128i t6 = _mm_xor_si128(t, _mm_shuffle_epi8(k_inv1, t4)); + + return mm_xor3(_mm_shuffle_epi8(sb1u, t5), + _mm_shuffle_epi8(sb1t, t6), + smeared); + } + +BOTAN_FUNC_ISA("ssse3") +__m128i aes_ssse3_encrypt(__m128i B, const __m128i* keys, size_t rounds) + { + const __m128i sb2u = _mm_set_epi32( + 0x5EB7E955, 0xBC982FCD, 0xE27A93C6, 0x0B712400); + const __m128i sb2t = _mm_set_epi32( + 0xC2A163C8, 0xAB82234A, 0x69EB8840, 0x0AE12900); + + const __m128i sbou = _mm_set_epi32( + 0x15AABF7A, 0xC502A878, 0xD0D26D17, 0x6FBDC700); + const __m128i sbot = _mm_set_epi32( + 0x8E1E90D1, 0x412B35FA, 0xCFE474A5, 0x5FBB6A00); + + const __m128i mc_backward[4] = { + _mm_set_epi32(0x0E0D0C0F, 0x0A09080B, 0x06050407, 0x02010003), + _mm_set_epi32(0x0A09080B, 0x06050407, 0x02010003, 0x0E0D0C0F), + _mm_set_epi32(0x06050407, 0x02010003, 0x0E0D0C0F, 0x0A09080B), + _mm_set_epi32(0x02010003, 0x0E0D0C0F, 0x0A09080B, 0x06050407), + }; + + B = mm_xor3(_mm_shuffle_epi8(k_ipt1, _mm_and_si128(low_nibs, B)), + _mm_shuffle_epi8(k_ipt2, + _mm_srli_epi32( + _mm_andnot_si128(low_nibs, B), + 4)), + _mm_loadu_si128(keys)); + + for(size_t r = 1; ; ++r) + { + const __m128i K = _mm_loadu_si128(keys + r); + + __m128i t = _mm_srli_epi32(_mm_andnot_si128(low_nibs, B), 4); + + B = _mm_and_si128(low_nibs, B); + + __m128i t2 = _mm_shuffle_epi8(k_inv2, B); + + B = _mm_xor_si128(B, t); + + __m128i t3 = _mm_xor_si128(t2, _mm_shuffle_epi8(k_inv1, t)); + __m128i t4 = _mm_xor_si128(t2, _mm_shuffle_epi8(k_inv1, B)); + + __m128i t5 = _mm_xor_si128(B, _mm_shuffle_epi8(k_inv1, t3)); + __m128i t6 = _mm_xor_si128(t, _mm_shuffle_epi8(k_inv1, t4)); + + if(r == rounds) + { + B = _mm_shuffle_epi8( + mm_xor3(_mm_shuffle_epi8(sbou, t5), + _mm_shuffle_epi8(sbot, t6), + K), + sr[r % 4]); + + return B; + } + + __m128i t7 = mm_xor3(_mm_shuffle_epi8(sb1t, t6), + _mm_shuffle_epi8(sb1u, t5), + K); + + __m128i t8 = mm_xor3(_mm_shuffle_epi8(sb2t, t6), + _mm_shuffle_epi8(sb2u, t5), + _mm_shuffle_epi8(t7, mc_forward[r % 4])); + + B = mm_xor3(_mm_shuffle_epi8(t8, mc_forward[r % 4]), + _mm_shuffle_epi8(t7, mc_backward[r % 4]), + t8); + } + } + +BOTAN_FUNC_ISA("ssse3") +__m128i aes_ssse3_decrypt(__m128i B, const __m128i* keys, size_t rounds) + { + const __m128i k_dipt1 = _mm_set_epi32( + 0x154A411E, 0x114E451A, 0x0F505B04, 0x0B545F00); + const __m128i k_dipt2 = _mm_set_epi32( + 0x12771772, 0xF491F194, 0x86E383E6, 0x60056500); + + const __m128i sb9u = _mm_set_epi32( + 0xCAD51F50, 0x4F994CC9, 0x851C0353, 0x9A86D600); + const __m128i sb9t = _mm_set_epi32( + 0x725E2C9E, 0xB2FBA565, 0xC03B1789, 0xECD74900); + + const __m128i sbeu = _mm_set_epi32( + 0x22426004, 0x64B4F6B0, 0x46F29296, 0x26D4D000); + const __m128i sbet = _mm_set_epi32( + 0x9467F36B, 0x98593E32, 0x0C55A6CD, 0xFFAAC100); + + const __m128i sbdu = _mm_set_epi32( + 0xF56E9B13, 0x882A4439, 0x7D57CCDF, 0xE6B1A200); + const __m128i sbdt = _mm_set_epi32( + 0x2931180D, 0x15DEEFD3, 0x3CE2FAF7, 0x24C6CB00); + + const __m128i sbbu = _mm_set_epi32( + 0x602646F6, 0xB0F2D404, 0xD0226492, 0x96B44200); + const __m128i sbbt = _mm_set_epi32( + 0xF3FF0C3E, 0x3255AA6B, 0xC19498A6, 0xCD596700); + + __m128i mc = mc_forward[3]; + + __m128i t = + _mm_shuffle_epi8(k_dipt2, + _mm_srli_epi32( + _mm_andnot_si128(low_nibs, B), + 4)); + + B = mm_xor3(t, _mm_loadu_si128(keys), + _mm_shuffle_epi8(k_dipt1, _mm_and_si128(B, low_nibs))); + + for(size_t r = 1; ; ++r) + { + const __m128i K = _mm_loadu_si128(keys + r); + + t = _mm_srli_epi32(_mm_andnot_si128(low_nibs, B), 4); + + B = _mm_and_si128(low_nibs, B); + + __m128i t2 = _mm_shuffle_epi8(k_inv2, B); + + B = _mm_xor_si128(B, t); + + __m128i t3 = _mm_xor_si128(t2, _mm_shuffle_epi8(k_inv1, t)); + __m128i t4 = _mm_xor_si128(t2, _mm_shuffle_epi8(k_inv1, B)); + __m128i t5 = _mm_xor_si128(B, _mm_shuffle_epi8(k_inv1, t3)); + __m128i t6 = _mm_xor_si128(t, _mm_shuffle_epi8(k_inv1, t4)); + + if(r == rounds) + { + const __m128i sbou = _mm_set_epi32( + 0xC7AA6DB9, 0xD4943E2D, 0x1387EA53, 0x7EF94000); + const __m128i sbot = _mm_set_epi32( + 0xCA4B8159, 0xD8C58E9C, 0x12D7560F, 0x93441D00); + + __m128i x = _mm_shuffle_epi8(sbou, t5); + __m128i y = _mm_shuffle_epi8(sbot, t6); + x = _mm_xor_si128(x, K); + x = _mm_xor_si128(x, y); + + const uint32_t which_sr = ((((rounds - 1) << 4) ^ 48) & 48) / 16; + return _mm_shuffle_epi8(x, sr[which_sr]); + } + + __m128i t8 = _mm_xor_si128(_mm_shuffle_epi8(sb9t, t6), + _mm_xor_si128(_mm_shuffle_epi8(sb9u, t5), K)); + + __m128i t9 = mm_xor3(_mm_shuffle_epi8(t8, mc), + _mm_shuffle_epi8(sbdu, t5), + _mm_shuffle_epi8(sbdt, t6)); + + __m128i t12 = _mm_xor_si128( + _mm_xor_si128( + _mm_shuffle_epi8(t9, mc), + _mm_shuffle_epi8(sbbu, t5)), + _mm_shuffle_epi8(sbbt, t6)); + + B = _mm_xor_si128(_mm_xor_si128(_mm_shuffle_epi8(t12, mc), + _mm_shuffle_epi8(sbeu, t5)), + _mm_shuffle_epi8(sbet, t6)); + + mc = _mm_alignr_epi8(mc, mc, 12); + } + } + +} + +/* +* AES-128 Encryption +*/ +BOTAN_FUNC_ISA("ssse3") +void AES_128::ssse3_encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const + { + const __m128i* in_mm = reinterpret_cast(in); + __m128i* out_mm = reinterpret_cast<__m128i*>(out); + + const __m128i* keys = reinterpret_cast(m_EK.data()); + + CT::poison(in, blocks * block_size()); + + BOTAN_PARALLEL_FOR(size_t i = 0; i < blocks; ++i) + { + __m128i B = _mm_loadu_si128(in_mm + i); + _mm_storeu_si128(out_mm + i, aes_ssse3_encrypt(B, keys, 10)); + } + + CT::unpoison(in, blocks * block_size()); + CT::unpoison(out, blocks * block_size()); + } + +/* +* AES-128 Decryption +*/ +BOTAN_FUNC_ISA("ssse3") +void AES_128::ssse3_decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const + { + const __m128i* in_mm = reinterpret_cast(in); + __m128i* out_mm = reinterpret_cast<__m128i*>(out); + + const __m128i* keys = reinterpret_cast(m_DK.data()); + + CT::poison(in, blocks * block_size()); + + BOTAN_PARALLEL_FOR(size_t i = 0; i < blocks; ++i) + { + __m128i B = _mm_loadu_si128(in_mm + i); + _mm_storeu_si128(out_mm + i, aes_ssse3_decrypt(B, keys, 10)); + } + + CT::unpoison(in, blocks * block_size()); + CT::unpoison(out, blocks * block_size()); + } + +/* +* AES-128 Key Schedule +*/ +BOTAN_FUNC_ISA("ssse3") +void AES_128::ssse3_key_schedule(const uint8_t keyb[], size_t) + { + __m128i rcon = _mm_set_epi32(0x702A9808, 0x4D7C7D81, + 0x1F8391B9, 0xAF9DEEB6); + + __m128i key = _mm_loadu_si128(reinterpret_cast(keyb)); + + m_EK.resize(11*4); + m_DK.resize(11*4); + + __m128i* EK_mm = reinterpret_cast<__m128i*>(m_EK.data()); + __m128i* DK_mm = reinterpret_cast<__m128i*>(m_DK.data()); + + _mm_storeu_si128(DK_mm + 10, _mm_shuffle_epi8(key, sr[2])); + + key = aes_schedule_transform(key, k_ipt1, k_ipt2); + + _mm_storeu_si128(EK_mm, key); + + for(size_t i = 1; i != 10; ++i) + { + key = aes_schedule_round(&rcon, key, key); + + _mm_storeu_si128(EK_mm + i, + aes_schedule_mangle(key, (12-i) % 4)); + + _mm_storeu_si128(DK_mm + (10-i), + aes_schedule_mangle_dec(key, (10-i) % 4)); + } + + key = aes_schedule_round(&rcon, key, key); + _mm_storeu_si128(EK_mm + 10, aes_schedule_mangle_last(key, 2)); + _mm_storeu_si128(DK_mm, aes_schedule_mangle_last_dec(key)); + } + +/* +* AES-192 Encryption +*/ +BOTAN_FUNC_ISA("ssse3") +void AES_192::ssse3_encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const + { + const __m128i* in_mm = reinterpret_cast(in); + __m128i* out_mm = reinterpret_cast<__m128i*>(out); + + const __m128i* keys = reinterpret_cast(m_EK.data()); + + CT::poison(in, blocks * block_size()); + + for(size_t i = 0; i != blocks; ++i) + { + __m128i B = _mm_loadu_si128(in_mm + i); + _mm_storeu_si128(out_mm + i, aes_ssse3_encrypt(B, keys, 12)); + } + + CT::unpoison(in, blocks * block_size()); + CT::unpoison(out, blocks * block_size()); + } + +/* +* AES-192 Decryption +*/ +BOTAN_FUNC_ISA("ssse3") +void AES_192::ssse3_decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const + { + const __m128i* in_mm = reinterpret_cast(in); + __m128i* out_mm = reinterpret_cast<__m128i*>(out); + + const __m128i* keys = reinterpret_cast(m_DK.data()); + + CT::poison(in, blocks * block_size()); + + for(size_t i = 0; i != blocks; ++i) + { + __m128i B = _mm_loadu_si128(in_mm + i); + _mm_storeu_si128(out_mm + i, aes_ssse3_decrypt(B, keys, 12)); + } + + CT::unpoison(in, blocks * block_size()); + CT::unpoison(out, blocks * block_size()); + } + +/* +* AES-192 Key Schedule +*/ +BOTAN_FUNC_ISA("ssse3") +void AES_192::ssse3_key_schedule(const uint8_t keyb[], size_t) + { + __m128i rcon = _mm_set_epi32(0x702A9808, 0x4D7C7D81, + 0x1F8391B9, 0xAF9DEEB6); + + m_EK.resize(13*4); + m_DK.resize(13*4); + + __m128i* EK_mm = reinterpret_cast<__m128i*>(m_EK.data()); + __m128i* DK_mm = reinterpret_cast<__m128i*>(m_DK.data()); + + __m128i key1 = _mm_loadu_si128(reinterpret_cast(keyb)); + __m128i key2 = _mm_loadu_si128(reinterpret_cast((keyb + 8))); + + _mm_storeu_si128(DK_mm + 12, _mm_shuffle_epi8(key1, sr[0])); + + key1 = aes_schedule_transform(key1, k_ipt1, k_ipt2); + key2 = aes_schedule_transform(key2, k_ipt1, k_ipt2); + + _mm_storeu_si128(EK_mm + 0, key1); + + // key2 with 8 high bytes masked off + __m128i t = _mm_slli_si128(_mm_srli_si128(key2, 8), 8); + + for(size_t i = 0; i != 4; ++i) + { + key2 = aes_schedule_round(&rcon, key2, key1); + + _mm_storeu_si128(EK_mm + 3*i+1, + aes_schedule_mangle(_mm_alignr_epi8(key2, t, 8), (i+3)%4)); + _mm_storeu_si128(DK_mm + 11-3*i, + aes_schedule_mangle_dec(_mm_alignr_epi8(key2, t, 8), (i+3)%4)); + + t = aes_schedule_192_smear(key2, t); + + _mm_storeu_si128(EK_mm + 3*i+2, + aes_schedule_mangle(t, (i+2)%4)); + _mm_storeu_si128(DK_mm + 10-3*i, + aes_schedule_mangle_dec(t, (i+2)%4)); + + key2 = aes_schedule_round(&rcon, t, key2); + + if(i == 3) + { + _mm_storeu_si128(EK_mm + 3*i+3, + aes_schedule_mangle_last(key2, (i+1)%4)); + _mm_storeu_si128(DK_mm + 9-3*i, + aes_schedule_mangle_last_dec(key2)); + } + else + { + _mm_storeu_si128(EK_mm + 3*i+3, + aes_schedule_mangle(key2, (i+1)%4)); + _mm_storeu_si128(DK_mm + 9-3*i, + aes_schedule_mangle_dec(key2, (i+1)%4)); + } + + key1 = key2; + key2 = aes_schedule_192_smear(key2, + _mm_slli_si128(_mm_srli_si128(t, 8), 8)); + t = _mm_slli_si128(_mm_srli_si128(key2, 8), 8); + } + } + +/* +* AES-256 Encryption +*/ +BOTAN_FUNC_ISA("ssse3") +void AES_256::ssse3_encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const + { + const __m128i* in_mm = reinterpret_cast(in); + __m128i* out_mm = reinterpret_cast<__m128i*>(out); + + const __m128i* keys = reinterpret_cast(m_EK.data()); + + CT::poison(in, blocks * block_size()); + + for(size_t i = 0; i != blocks; ++i) + { + __m128i B = _mm_loadu_si128(in_mm + i); + _mm_storeu_si128(out_mm + i, aes_ssse3_encrypt(B, keys, 14)); + } + + CT::unpoison(in, blocks * block_size()); + CT::unpoison(out, blocks * block_size()); + } + +/* +* AES-256 Decryption +*/ +BOTAN_FUNC_ISA("ssse3") +void AES_256::ssse3_decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const + { + const __m128i* in_mm = reinterpret_cast(in); + __m128i* out_mm = reinterpret_cast<__m128i*>(out); + + const __m128i* keys = reinterpret_cast(m_DK.data()); + + CT::poison(in, blocks * block_size()); + + for(size_t i = 0; i != blocks; ++i) + { + __m128i B = _mm_loadu_si128(in_mm + i); + _mm_storeu_si128(out_mm + i, aes_ssse3_decrypt(B, keys, 14)); + } + + CT::unpoison(in, blocks * block_size()); + CT::unpoison(out, blocks * block_size()); + } + +/* +* AES-256 Key Schedule +*/ +BOTAN_FUNC_ISA("ssse3") +void AES_256::ssse3_key_schedule(const uint8_t keyb[], size_t) + { + __m128i rcon = _mm_set_epi32(0x702A9808, 0x4D7C7D81, + 0x1F8391B9, 0xAF9DEEB6); + + m_EK.resize(15*4); + m_DK.resize(15*4); + + __m128i* EK_mm = reinterpret_cast<__m128i*>(m_EK.data()); + __m128i* DK_mm = reinterpret_cast<__m128i*>(m_DK.data()); + + __m128i key1 = _mm_loadu_si128(reinterpret_cast(keyb)); + __m128i key2 = _mm_loadu_si128(reinterpret_cast((keyb + 16))); + + _mm_storeu_si128(DK_mm + 14, _mm_shuffle_epi8(key1, sr[2])); + + key1 = aes_schedule_transform(key1, k_ipt1, k_ipt2); + key2 = aes_schedule_transform(key2, k_ipt1, k_ipt2); + + _mm_storeu_si128(EK_mm + 0, key1); + _mm_storeu_si128(EK_mm + 1, aes_schedule_mangle(key2, 3)); + + _mm_storeu_si128(DK_mm + 13, aes_schedule_mangle_dec(key2, 1)); + + for(size_t i = 2; i != 14; i += 2) + { + __m128i k_t = key2; + key1 = key2 = aes_schedule_round(&rcon, key2, key1); + + _mm_storeu_si128(EK_mm + i, aes_schedule_mangle(key2, i % 4)); + _mm_storeu_si128(DK_mm + (14-i), aes_schedule_mangle_dec(key2, (i+2) % 4)); + + key2 = aes_schedule_round(nullptr, _mm_shuffle_epi32(key2, 0xFF), k_t); + _mm_storeu_si128(EK_mm + i + 1, aes_schedule_mangle(key2, (i - 1) % 4)); + _mm_storeu_si128(DK_mm + (13-i), aes_schedule_mangle_dec(key2, (i+1) % 4)); + } + + key2 = aes_schedule_round(&rcon, key2, key1); + + _mm_storeu_si128(EK_mm + 14, aes_schedule_mangle_last(key2, 2)); + _mm_storeu_si128(DK_mm + 0, aes_schedule_mangle_last_dec(key2)); + } + +} 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 new file mode 100644 index 0000000000..8457eed569 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/block/aes/aes_ssse3/info.txt @@ -0,0 +1,15 @@ + +AES_SSSE3 -> 20131128 + + +load_on auto + +need_isa ssse3 + +# Intel C++ can't deal with syntax for defining constants :( + +gcc +clang +msvc +sunstudio + diff --git a/src/libs/3rdparty/botan/src/lib/block/aes/info.txt b/src/libs/3rdparty/botan/src/lib/block/aes/info.txt new file mode 100644 index 0000000000..62455cf2c3 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/block/aes/info.txt @@ -0,0 +1,3 @@ + +AES -> 20131128 + diff --git a/src/libs/3rdparty/botan/src/lib/block/block_cipher.cpp b/src/libs/3rdparty/botan/src/lib/block/block_cipher.cpp new file mode 100644 index 0000000000..3ace6cd4f4 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/block/block_cipher.cpp @@ -0,0 +1,349 @@ +/* +* Block Ciphers +* (C) 2015 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include + +#if defined(BOTAN_HAS_AES) + #include +#endif + +#if defined(BOTAN_HAS_ARIA) + #include +#endif + +#if defined(BOTAN_HAS_BLOWFISH) + #include +#endif + +#if defined(BOTAN_HAS_CAMELLIA) + #include +#endif + +#if defined(BOTAN_HAS_CAST_128) + #include +#endif + +#if defined(BOTAN_HAS_CAST_256) + #include +#endif + +#if defined(BOTAN_HAS_CASCADE) + #include +#endif + +#if defined(BOTAN_HAS_DES) + #include + #include +#endif + +#if defined(BOTAN_HAS_GOST_28147_89) + #include +#endif + +#if defined(BOTAN_HAS_IDEA) + #include +#endif + +#if defined(BOTAN_HAS_KASUMI) + #include +#endif + +#if defined(BOTAN_HAS_LION) + #include +#endif + +#if defined(BOTAN_HAS_MISTY1) + #include +#endif + +#if defined(BOTAN_HAS_NOEKEON) + #include +#endif + +#if defined(BOTAN_HAS_SEED) + #include +#endif + +#if defined(BOTAN_HAS_SERPENT) + #include +#endif + +#if defined(BOTAN_HAS_SHACAL2) + #include +#endif + +#if defined(BOTAN_HAS_SM4) + #include +#endif + +#if defined(BOTAN_HAS_TWOFISH) + #include +#endif + +#if defined(BOTAN_HAS_THREEFISH_512) + #include +#endif + +#if defined(BOTAN_HAS_XTEA) + #include +#endif + +#if defined(BOTAN_HAS_OPENSSL) + #include +#endif + +namespace Botan { + +std::unique_ptr +BlockCipher::create(const std::string& algo, + const std::string& provider) + { +#if defined(BOTAN_HAS_OPENSSL) + if(provider.empty() || provider == "openssl") + { + if(auto bc = make_openssl_block_cipher(algo)) + return bc; + + if(!provider.empty()) + return nullptr; + } +#endif + + // TODO: CommonCrypto + // TODO: CryptoAPI + // TODO: /dev/crypto + + // Only base providers from here on out + if(provider.empty() == false && provider != "base") + return nullptr; + +#if defined(BOTAN_HAS_AES) + if(algo == "AES-128") + { + return std::unique_ptr(new AES_128); + } + + if(algo == "AES-192") + { + return std::unique_ptr(new AES_192); + } + + if(algo == "AES-256") + { + return std::unique_ptr(new AES_256); + } +#endif + +#if defined(BOTAN_HAS_ARIA) + if(algo == "ARIA-128") + { + return std::unique_ptr(new ARIA_128); + } + + if(algo == "ARIA-192") + { + return std::unique_ptr(new ARIA_192); + } + + if(algo == "ARIA-256") + { + return std::unique_ptr(new ARIA_256); + } +#endif + +#if defined(BOTAN_HAS_SERPENT) + if(algo == "Serpent") + { + return std::unique_ptr(new Serpent); + } +#endif + +#if defined(BOTAN_HAS_SHACAL2) + if(algo == "SHACAL2") + { + return std::unique_ptr(new SHACAL2); + } +#endif + +#if defined(BOTAN_HAS_TWOFISH) + if(algo == "Twofish") + { + return std::unique_ptr(new Twofish); + } +#endif + +#if defined(BOTAN_HAS_THREEFISH_512) + if(algo == "Threefish-512") + { + return std::unique_ptr(new Threefish_512); + } +#endif + +#if defined(BOTAN_HAS_BLOWFISH) + if(algo == "Blowfish") + { + return std::unique_ptr(new Blowfish); + } +#endif + +#if defined(BOTAN_HAS_CAMELLIA) + if(algo == "Camellia-128") + { + return std::unique_ptr(new Camellia_128); + } + + if(algo == "Camellia-192") + { + return std::unique_ptr(new Camellia_192); + } + + if(algo == "Camellia-256") + { + return std::unique_ptr(new Camellia_256); + } +#endif + +#if defined(BOTAN_HAS_DES) + if(algo == "DES") + { + return std::unique_ptr(new DES); + } + + if(algo == "DESX") + { + return std::unique_ptr(new DESX); + } + + if(algo == "TripleDES" || algo == "3DES" || algo == "DES-EDE") + { + return std::unique_ptr(new TripleDES); + } +#endif + +#if defined(BOTAN_HAS_NOEKEON) + if(algo == "Noekeon") + { + return std::unique_ptr(new Noekeon); + } +#endif + +#if defined(BOTAN_HAS_CAST_128) + if(algo == "CAST-128" || algo == "CAST5") + { + return std::unique_ptr(new CAST_128); + } +#endif + +#if defined(BOTAN_HAS_CAST_256) + if(algo == "CAST-256") + { + return std::unique_ptr(new CAST_256); + } +#endif + +#if defined(BOTAN_HAS_IDEA) + if(algo == "IDEA") + { + return std::unique_ptr(new IDEA); + } +#endif + +#if defined(BOTAN_HAS_KASUMI) + if(algo == "KASUMI") + { + return std::unique_ptr(new KASUMI); + } +#endif + +#if defined(BOTAN_HAS_MISTY1) + if(algo == "MISTY1") + { + return std::unique_ptr(new MISTY1); + } +#endif + +#if defined(BOTAN_HAS_SEED) + if(algo == "SEED") + { + return std::unique_ptr(new SEED); + } +#endif + +#if defined(BOTAN_HAS_SM4) + if(algo == "SM4") + { + return std::unique_ptr(new SM4); + } +#endif + +#if defined(BOTAN_HAS_XTEA) + if(algo == "XTEA") + { + return std::unique_ptr(new XTEA); + } +#endif + + const SCAN_Name req(algo); + +#if defined(BOTAN_HAS_GOST_28147_89) + if(req.algo_name() == "GOST-28147-89") + { + return std::unique_ptr(new GOST_28147_89(req.arg(0, "R3411_94_TestParam"))); + } +#endif + +#if defined(BOTAN_HAS_CASCADE) + if(req.algo_name() == "Cascade" && req.arg_count() == 2) + { + std::unique_ptr c1(BlockCipher::create(req.arg(0))); + std::unique_ptr c2(BlockCipher::create(req.arg(1))); + + if(c1 && c2) + return std::unique_ptr(new Cascade_Cipher(c1.release(), c2.release())); + } +#endif + +#if defined(BOTAN_HAS_LION) + if(req.algo_name() == "Lion" && req.arg_count_between(2, 3)) + { + std::unique_ptr hash(HashFunction::create(req.arg(0))); + std::unique_ptr stream(StreamCipher::create(req.arg(1))); + + if(hash && stream) + { + const size_t block_size = req.arg_as_integer(2, 1024); + return std::unique_ptr(new Lion(hash.release(), stream.release(), block_size)); + } + } +#endif + + BOTAN_UNUSED(req); + BOTAN_UNUSED(provider); + + return nullptr; + } + +//static +std::unique_ptr +BlockCipher::create_or_throw(const std::string& algo, + const std::string& provider) + { + if(auto bc = BlockCipher::create(algo, provider)) + { + return bc; + } + throw Lookup_Error("Block cipher", algo, provider); + } + +std::vector BlockCipher::providers(const std::string& algo) + { + return probe_providers_of(algo, { "base", "openssl" }); + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/block/block_cipher.h b/src/libs/3rdparty/botan/src/lib/block/block_cipher.h new file mode 100644 index 0000000000..a365397fa3 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/block/block_cipher.h @@ -0,0 +1,237 @@ +/* +* Block Cipher Base Class +* (C) 1999-2009 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_BLOCK_CIPHER_H_ +#define BOTAN_BLOCK_CIPHER_H_ + +#include +#include +#include + +namespace Botan { + +/** +* This class represents a block cipher object. +*/ +class BOTAN_PUBLIC_API(2,0) BlockCipher : public SymmetricAlgorithm + { + 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 + 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 + create_or_throw(const std::string& algo_spec, + const std::string& provider = ""); + + /** + * @return list of available providers for this algorithm, empty if not available + * @param algo_spec algorithm name + */ + static std::vector providers(const std::string& algo_spec); + + /** + * @return block size of this algorithm + */ + virtual size_t block_size() const = 0; + + /** + * @return native parallelism of this cipher in blocks + */ + virtual size_t parallelism() const { return 1; } + + /** + * @return prefererred parallelism of this cipher in bytes + */ + size_t parallel_bytes() const + { + return parallelism() * block_size() * BOTAN_BLOCK_CIPHER_PAR_MULT; + } + + /** + * @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"; } + + /** + * Encrypt a block. + * @param in The plaintext block to be encrypted as a byte array. + * Must be of length block_size(). + * @param out The byte array designated to hold the encrypted block. + * Must be of length block_size(). + */ + void encrypt(const uint8_t in[], uint8_t out[]) const + { encrypt_n(in, out, 1); } + + /** + * Decrypt a block. + * @param in The ciphertext block to be decypted as a byte array. + * Must be of length block_size(). + * @param out The byte array designated to hold the decrypted block. + * Must be of length block_size(). + */ + void decrypt(const uint8_t in[], uint8_t out[]) const + { decrypt_n(in, out, 1); } + + /** + * Encrypt a block. + * @param block the plaintext block to be encrypted + * Must be of length block_size(). Will hold the result when the function + * has finished. + */ + void encrypt(uint8_t block[]) const { encrypt_n(block, block, 1); } + + /** + * Decrypt a block. + * @param block the ciphertext block to be decrypted + * Must be of length block_size(). Will hold the result when the function + * has finished. + */ + void decrypt(uint8_t block[]) const { decrypt_n(block, block, 1); } + + /** + * Encrypt one or more blocks + * @param block the input/output buffer (multiple of block_size()) + */ + template + void encrypt(std::vector& block) const + { + return encrypt_n(block.data(), block.data(), block.size() / block_size()); + } + + /** + * Decrypt one or more blocks + * @param block the input/output buffer (multiple of block_size()) + */ + template + void decrypt(std::vector& block) const + { + return decrypt_n(block.data(), block.data(), block.size() / block_size()); + } + + /** + * Encrypt one or more blocks + * @param in the input buffer (multiple of block_size()) + * @param out the output buffer (same size as in) + */ + template + void encrypt(const std::vector& in, + std::vector& out) const + { + return encrypt_n(in.data(), out.data(), in.size() / block_size()); + } + + /** + * Decrypt one or more blocks + * @param in the input buffer (multiple of block_size()) + * @param out the output buffer (same size as in) + */ + template + void decrypt(const std::vector& in, + std::vector& out) const + { + return decrypt_n(in.data(), out.data(), in.size() / block_size()); + } + + /** + * Encrypt one or more blocks + * @param in the input buffer (multiple of block_size()) + * @param out the output buffer (same size as in) + * @param blocks the number of blocks to process + */ + virtual void encrypt_n(const uint8_t in[], uint8_t out[], + size_t blocks) const = 0; + + /** + * Decrypt one or more blocks + * @param in the input buffer (multiple of block_size()) + * @param out the output buffer (same size as in) + * @param blocks the number of blocks to process + */ + virtual void decrypt_n(const uint8_t in[], uint8_t out[], + size_t blocks) const = 0; + + virtual void encrypt_n_xex(uint8_t data[], + const uint8_t mask[], + size_t blocks) const + { + const size_t BS = block_size(); + xor_buf(data, mask, blocks * BS); + encrypt_n(data, data, blocks); + xor_buf(data, mask, blocks * BS); + } + + virtual void decrypt_n_xex(uint8_t data[], + const uint8_t mask[], + size_t blocks) const + { + const size_t BS = block_size(); + xor_buf(data, mask, blocks * BS); + decrypt_n(data, data, blocks); + xor_buf(data, mask, blocks * BS); + } + + /** + * @return new object representing the same algorithm as *this + */ + virtual BlockCipher* clone() const = 0; + + virtual ~BlockCipher() = default; + }; + +/** +* Represents a block cipher with a single fixed block size +*/ +template +class Block_Cipher_Fixed_Params : public BlockCipher + { + public: + enum { BLOCK_SIZE = BS }; + size_t block_size() const 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 + { + xor_buf(data, mask, blocks * BS); + 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 + { + xor_buf(data, mask, blocks * BS); + decrypt_n(data, data, blocks); + xor_buf(data, mask, blocks * BS); + } + + Key_Length_Specification key_spec() const override + { + return Key_Length_Specification(KMIN, KMAX, KMOD); + } + }; + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/block/des/des.cpp b/src/libs/3rdparty/botan/src/lib/block/des/des.cpp new file mode 100644 index 0000000000..885daa05ca --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/block/des/des.cpp @@ -0,0 +1,381 @@ +/* +* DES +* (C) 1999-2008,2018 Jack Lloyd +* +* Based on a public domain implemenation by Phil Karn (who in turn +* credited Richard Outerbridge and Jim Gillogly) +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include + +namespace Botan { + +namespace { + +/* +* DES Key Schedule +*/ +void des_key_schedule(uint32_t round_key[32], const uint8_t key[8]) + { + static const uint8_t ROT[16] = { 1, 1, 2, 2, 2, 2, 2, 2, + 1, 2, 2, 2, 2, 2, 2, 1 }; + + uint32_t C = ((key[7] & 0x80) << 20) | ((key[6] & 0x80) << 19) | + ((key[5] & 0x80) << 18) | ((key[4] & 0x80) << 17) | + ((key[3] & 0x80) << 16) | ((key[2] & 0x80) << 15) | + ((key[1] & 0x80) << 14) | ((key[0] & 0x80) << 13) | + ((key[7] & 0x40) << 13) | ((key[6] & 0x40) << 12) | + ((key[5] & 0x40) << 11) | ((key[4] & 0x40) << 10) | + ((key[3] & 0x40) << 9) | ((key[2] & 0x40) << 8) | + ((key[1] & 0x40) << 7) | ((key[0] & 0x40) << 6) | + ((key[7] & 0x20) << 6) | ((key[6] & 0x20) << 5) | + ((key[5] & 0x20) << 4) | ((key[4] & 0x20) << 3) | + ((key[3] & 0x20) << 2) | ((key[2] & 0x20) << 1) | + ((key[1] & 0x20) ) | ((key[0] & 0x20) >> 1) | + ((key[7] & 0x10) >> 1) | ((key[6] & 0x10) >> 2) | + ((key[5] & 0x10) >> 3) | ((key[4] & 0x10) >> 4); + uint32_t D = ((key[7] & 0x02) << 26) | ((key[6] & 0x02) << 25) | + ((key[5] & 0x02) << 24) | ((key[4] & 0x02) << 23) | + ((key[3] & 0x02) << 22) | ((key[2] & 0x02) << 21) | + ((key[1] & 0x02) << 20) | ((key[0] & 0x02) << 19) | + ((key[7] & 0x04) << 17) | ((key[6] & 0x04) << 16) | + ((key[5] & 0x04) << 15) | ((key[4] & 0x04) << 14) | + ((key[3] & 0x04) << 13) | ((key[2] & 0x04) << 12) | + ((key[1] & 0x04) << 11) | ((key[0] & 0x04) << 10) | + ((key[7] & 0x08) << 8) | ((key[6] & 0x08) << 7) | + ((key[5] & 0x08) << 6) | ((key[4] & 0x08) << 5) | + ((key[3] & 0x08) << 4) | ((key[2] & 0x08) << 3) | + ((key[1] & 0x08) << 2) | ((key[0] & 0x08) << 1) | + ((key[3] & 0x10) >> 1) | ((key[2] & 0x10) >> 2) | + ((key[1] & 0x10) >> 3) | ((key[0] & 0x10) >> 4); + + for(size_t i = 0; i != 16; ++i) + { + C = ((C << ROT[i]) | (C >> (28-ROT[i]))) & 0x0FFFFFFF; + D = ((D << ROT[i]) | (D >> (28-ROT[i]))) & 0x0FFFFFFF; + round_key[2*i ] = ((C & 0x00000010) << 22) | ((C & 0x00000800) << 17) | + ((C & 0x00000020) << 16) | ((C & 0x00004004) << 15) | + ((C & 0x00000200) << 11) | ((C & 0x00020000) << 10) | + ((C & 0x01000000) >> 6) | ((C & 0x00100000) >> 4) | + ((C & 0x00010000) << 3) | ((C & 0x08000000) >> 2) | + ((C & 0x00800000) << 1) | ((D & 0x00000010) << 8) | + ((D & 0x00000002) << 7) | ((D & 0x00000001) << 2) | + ((D & 0x00000200) ) | ((D & 0x00008000) >> 2) | + ((D & 0x00000088) >> 3) | ((D & 0x00001000) >> 7) | + ((D & 0x00080000) >> 9) | ((D & 0x02020000) >> 14) | + ((D & 0x00400000) >> 21); + round_key[2*i+1] = ((C & 0x00000001) << 28) | ((C & 0x00000082) << 18) | + ((C & 0x00002000) << 14) | ((C & 0x00000100) << 10) | + ((C & 0x00001000) << 9) | ((C & 0x00040000) << 6) | + ((C & 0x02400000) << 4) | ((C & 0x00008000) << 2) | + ((C & 0x00200000) >> 1) | ((C & 0x04000000) >> 10) | + ((D & 0x00000020) << 6) | ((D & 0x00000100) ) | + ((D & 0x00000800) >> 1) | ((D & 0x00000040) >> 3) | + ((D & 0x00010000) >> 4) | ((D & 0x00000400) >> 5) | + ((D & 0x00004000) >> 10) | ((D & 0x04000000) >> 13) | + ((D & 0x00800000) >> 14) | ((D & 0x00100000) >> 18) | + ((D & 0x01000000) >> 24) | ((D & 0x08000000) >> 26); + } + } + +inline uint32_t spbox(uint32_t T0, uint32_t T1) + { + return DES_SPBOX1[get_byte(0, T0)] ^ DES_SPBOX2[get_byte(0, T1)] ^ + DES_SPBOX3[get_byte(1, T0)] ^ DES_SPBOX4[get_byte(1, T1)] ^ + DES_SPBOX5[get_byte(2, T0)] ^ DES_SPBOX6[get_byte(2, T1)] ^ + DES_SPBOX7[get_byte(3, T0)] ^ DES_SPBOX8[get_byte(3, T1)]; + } + +/* +* DES Encryption +*/ +inline void des_encrypt(uint32_t& Lr, uint32_t& Rr, + const uint32_t round_key[32]) + { + uint32_t L = Lr; + uint32_t R = Rr; + for(size_t i = 0; i != 16; i += 2) + { + L ^= spbox(rotr<4>(R) ^ round_key[2*i ], R ^ round_key[2*i+1]); + R ^= spbox(rotr<4>(L) ^ round_key[2*i+2], L ^ round_key[2*i+3]); + } + + Lr = L; + Rr = R; + } + +inline void des_encrypt_x2(uint32_t& L0r, uint32_t& R0r, + uint32_t& L1r, uint32_t& R1r, + const uint32_t round_key[32]) + { + uint32_t L0 = L0r; + uint32_t R0 = R0r; + uint32_t L1 = L1r; + uint32_t R1 = R1r; + + for(size_t i = 0; i != 16; i += 2) + { + L0 ^= spbox(rotr<4>(R0) ^ round_key[2*i ], R0 ^ round_key[2*i+1]); + L1 ^= spbox(rotr<4>(R1) ^ round_key[2*i ], R1 ^ round_key[2*i+1]); + + R0 ^= spbox(rotr<4>(L0) ^ round_key[2*i+2], L0 ^ round_key[2*i+3]); + R1 ^= spbox(rotr<4>(L1) ^ round_key[2*i+2], L1 ^ round_key[2*i+3]); + } + + L0r = L0; + R0r = R0; + L1r = L1; + R1r = R1; + } + +/* +* DES Decryption +*/ +inline void des_decrypt(uint32_t& Lr, uint32_t& Rr, + const uint32_t round_key[32]) + { + uint32_t L = Lr; + uint32_t R = Rr; + for(size_t i = 16; i != 0; i -= 2) + { + L ^= spbox(rotr<4>(R) ^ round_key[2*i - 2], R ^ round_key[2*i - 1]); + R ^= spbox(rotr<4>(L) ^ round_key[2*i - 4], L ^ round_key[2*i - 3]); + } + Lr = L; + Rr = R; + } + +inline void des_decrypt_x2(uint32_t& L0r, uint32_t& R0r, + uint32_t& L1r, uint32_t& R1r, + const uint32_t round_key[32]) + { + uint32_t L0 = L0r; + uint32_t R0 = R0r; + uint32_t L1 = L1r; + uint32_t R1 = R1r; + + for(size_t i = 16; i != 0; i -= 2) + { + L0 ^= spbox(rotr<4>(R0) ^ round_key[2*i - 2], R0 ^ round_key[2*i - 1]); + L1 ^= spbox(rotr<4>(R1) ^ round_key[2*i - 2], R1 ^ round_key[2*i - 1]); + + R0 ^= spbox(rotr<4>(L0) ^ round_key[2*i - 4], L0 ^ round_key[2*i - 3]); + R1 ^= spbox(rotr<4>(L1) ^ round_key[2*i - 4], L1 ^ round_key[2*i - 3]); + } + + L0r = L0; + R0r = R0; + L1r = L1; + R1r = R1; + } + +inline void des_IP(uint32_t& L, uint32_t& R, const uint8_t block[]) + { + uint64_t T = (DES_IPTAB1[block[0]] ) | (DES_IPTAB1[block[1]] << 1) | + (DES_IPTAB1[block[2]] << 2) | (DES_IPTAB1[block[3]] << 3) | + (DES_IPTAB1[block[4]] << 4) | (DES_IPTAB1[block[5]] << 5) | + (DES_IPTAB1[block[6]] << 6) | (DES_IPTAB2[block[7]] ); + + L = static_cast(T >> 32); + R = static_cast(T); + } + +inline void des_FP(uint32_t L, uint32_t R, uint8_t out[]) + { + uint64_t T = (DES_FPTAB1[get_byte(0, L)] << 5) | (DES_FPTAB1[get_byte(1, L)] << 3) | + (DES_FPTAB1[get_byte(2, L)] << 1) | (DES_FPTAB2[get_byte(3, L)] << 1) | + (DES_FPTAB1[get_byte(0, R)] << 4) | (DES_FPTAB1[get_byte(1, R)] << 2) | + (DES_FPTAB1[get_byte(2, R)] ) | (DES_FPTAB2[get_byte(3, R)] ); + T = rotl<32>(T); + + store_be(T, out); + } + +} + +/* +* DES Encryption +*/ +void DES::encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const + { + verify_key_set(m_round_key.empty() == false); + + while(blocks >= 2) + { + uint32_t L0, R0; + uint32_t L1, R1; + + des_IP(L0, R0, in); + des_IP(L1, R1, in + BLOCK_SIZE); + + des_encrypt_x2(L0, R0, L1, R1, m_round_key.data()); + + des_FP(L0, R0, out); + des_FP(L1, R1, out + BLOCK_SIZE); + + in += 2*BLOCK_SIZE; + out += 2*BLOCK_SIZE; + blocks -= 2; + } + + for(size_t i = 0; i < blocks; ++i) + { + uint32_t L, R; + des_IP(L, R, in + BLOCK_SIZE*i); + des_encrypt(L, R, m_round_key.data()); + des_FP(L, R, out + BLOCK_SIZE*i); + } + } + +/* +* DES Decryption +*/ +void DES::decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const + { + verify_key_set(m_round_key.empty() == false); + + while(blocks >= 2) + { + uint32_t L0, R0; + uint32_t L1, R1; + + des_IP(L0, R0, in); + des_IP(L1, R1, in + BLOCK_SIZE); + + des_decrypt_x2(L0, R0, L1, R1, m_round_key.data()); + + des_FP(L0, R0, out); + des_FP(L1, R1, out + BLOCK_SIZE); + + in += 2*BLOCK_SIZE; + out += 2*BLOCK_SIZE; + blocks -= 2; + } + + for(size_t i = 0; i < blocks; ++i) + { + uint32_t L, R; + des_IP(L, R, in + BLOCK_SIZE*i); + des_decrypt(L, R, m_round_key.data()); + des_FP(L, R, out + BLOCK_SIZE*i); + } + } + +/* +* DES Key Schedule +*/ +void DES::key_schedule(const uint8_t key[], size_t) + { + m_round_key.resize(32); + des_key_schedule(m_round_key.data(), key); + } + +void DES::clear() + { + zap(m_round_key); + } + +/* +* TripleDES Encryption +*/ +void TripleDES::encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const + { + verify_key_set(m_round_key.empty() == false); + + while(blocks >= 2) + { + uint32_t L0, R0; + uint32_t L1, R1; + + des_IP(L0, R0, in); + des_IP(L1, R1, in + BLOCK_SIZE); + + des_encrypt_x2(L0, R0, L1, R1, &m_round_key[0]); + des_decrypt_x2(R0, L0, R1, L1, &m_round_key[32]); + des_encrypt_x2(L0, R0, L1, R1, &m_round_key[64]); + + des_FP(L0, R0, out); + des_FP(L1, R1, out + BLOCK_SIZE); + + in += 2*BLOCK_SIZE; + out += 2*BLOCK_SIZE; + blocks -= 2; + } + + for(size_t i = 0; i != blocks; ++i) + { + uint32_t L, R; + des_IP(L, R, in + BLOCK_SIZE*i); + + des_encrypt(L, R, &m_round_key[0]); + des_decrypt(R, L, &m_round_key[32]); + des_encrypt(L, R, &m_round_key[64]); + + des_FP(L, R, out + BLOCK_SIZE*i); + } + } + +/* +* TripleDES Decryption +*/ +void TripleDES::decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const + { + verify_key_set(m_round_key.empty() == false); + + while(blocks >= 2) + { + uint32_t L0, R0; + uint32_t L1, R1; + + des_IP(L0, R0, in); + des_IP(L1, R1, in + BLOCK_SIZE); + + des_decrypt_x2(L0, R0, L1, R1, &m_round_key[64]); + des_encrypt_x2(R0, L0, R1, L1, &m_round_key[32]); + des_decrypt_x2(L0, R0, L1, R1, &m_round_key[0]); + + des_FP(L0, R0, out); + des_FP(L1, R1, out + BLOCK_SIZE); + + in += 2*BLOCK_SIZE; + out += 2*BLOCK_SIZE; + blocks -= 2; + } + + for(size_t i = 0; i != blocks; ++i) + { + uint32_t L, R; + des_IP(L, R, in + BLOCK_SIZE*i); + + des_decrypt(L, R, &m_round_key[64]); + des_encrypt(R, L, &m_round_key[32]); + des_decrypt(L, R, &m_round_key[0]); + + des_FP(L, R, out + BLOCK_SIZE*i); + } + } + +/* +* TripleDES Key Schedule +*/ +void TripleDES::key_schedule(const uint8_t key[], size_t length) + { + m_round_key.resize(3*32); + des_key_schedule(&m_round_key[0], key); + des_key_schedule(&m_round_key[32], key + 8); + + if(length == 24) + des_key_schedule(&m_round_key[64], key + 16); + else + copy_mem(&m_round_key[64], &m_round_key[0], 32); + } + +void TripleDES::clear() + { + zap(m_round_key); + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/block/des/des.h b/src/libs/3rdparty/botan/src/lib/block/des/des.h new file mode 100644 index 0000000000..bdedeff642 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/block/des/des.h @@ -0,0 +1,70 @@ +/* +* DES +* (C) 1999-2007 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_DES_H_ +#define BOTAN_DES_H_ + +#include + +namespace Botan { + +/** +* DES +*/ +class BOTAN_PUBLIC_API(2,0) DES final : public Block_Cipher_Fixed_Params<8, 8> + { + public: + void encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override; + void decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override; + + void clear() override; + std::string name() const override { return "DES"; } + BlockCipher* clone() const override { return new DES; } + private: + void key_schedule(const uint8_t[], size_t) override; + + secure_vector m_round_key; + }; + +/** +* Triple DES +*/ +class BOTAN_PUBLIC_API(2,0) TripleDES final : public Block_Cipher_Fixed_Params<8, 16, 24, 8> + { + public: + void encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override; + void decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override; + + void clear() override; + std::string name() const override { return "TripleDES"; } + BlockCipher* clone() const override { return new TripleDES; } + private: + void key_schedule(const uint8_t[], size_t) override; + + secure_vector m_round_key; + }; + +/* +* DES Tables +*/ +extern const uint32_t DES_SPBOX1[256]; +extern const uint32_t DES_SPBOX2[256]; +extern const uint32_t DES_SPBOX3[256]; +extern const uint32_t DES_SPBOX4[256]; +extern const uint32_t DES_SPBOX5[256]; +extern const uint32_t DES_SPBOX6[256]; +extern const uint32_t DES_SPBOX7[256]; +extern const uint32_t DES_SPBOX8[256]; + +extern const uint64_t DES_IPTAB1[256]; +extern const uint64_t DES_IPTAB2[256]; +extern const uint64_t DES_FPTAB1[256]; +extern const uint64_t DES_FPTAB2[256]; + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/block/des/des_tab.cpp b/src/libs/3rdparty/botan/src/lib/block/des/des_tab.cpp new file mode 100644 index 0000000000..c64b6baf62 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/block/des/des_tab.cpp @@ -0,0 +1,636 @@ +/* +* Substitution/Permutation Tables for DES +* (C) 1999-2007 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include + +namespace Botan { + +const uint32_t DES_SPBOX1[256] = { + 0x01010400, 0x00000000, 0x00010000, 0x01010404, 0x01010004, 0x00010404, + 0x00000004, 0x00010000, 0x00000400, 0x01010400, 0x01010404, 0x00000400, + 0x01000404, 0x01010004, 0x01000000, 0x00000004, 0x00000404, 0x01000400, + 0x01000400, 0x00010400, 0x00010400, 0x01010000, 0x01010000, 0x01000404, + 0x00010004, 0x01000004, 0x01000004, 0x00010004, 0x00000000, 0x00000404, + 0x00010404, 0x01000000, 0x00010000, 0x01010404, 0x00000004, 0x01010000, + 0x01010400, 0x01000000, 0x01000000, 0x00000400, 0x01010004, 0x00010000, + 0x00010400, 0x01000004, 0x00000400, 0x00000004, 0x01000404, 0x00010404, + 0x01010404, 0x00010004, 0x01010000, 0x01000404, 0x01000004, 0x00000404, + 0x00010404, 0x01010400, 0x00000404, 0x01000400, 0x01000400, 0x00000000, + 0x00010004, 0x00010400, 0x00000000, 0x01010004, 0x01010400, 0x00000000, + 0x00010000, 0x01010404, 0x01010004, 0x00010404, 0x00000004, 0x00010000, + 0x00000400, 0x01010400, 0x01010404, 0x00000400, 0x01000404, 0x01010004, + 0x01000000, 0x00000004, 0x00000404, 0x01000400, 0x01000400, 0x00010400, + 0x00010400, 0x01010000, 0x01010000, 0x01000404, 0x00010004, 0x01000004, + 0x01000004, 0x00010004, 0x00000000, 0x00000404, 0x00010404, 0x01000000, + 0x00010000, 0x01010404, 0x00000004, 0x01010000, 0x01010400, 0x01000000, + 0x01000000, 0x00000400, 0x01010004, 0x00010000, 0x00010400, 0x01000004, + 0x00000400, 0x00000004, 0x01000404, 0x00010404, 0x01010404, 0x00010004, + 0x01010000, 0x01000404, 0x01000004, 0x00000404, 0x00010404, 0x01010400, + 0x00000404, 0x01000400, 0x01000400, 0x00000000, 0x00010004, 0x00010400, + 0x00000000, 0x01010004, 0x01010400, 0x00000000, 0x00010000, 0x01010404, + 0x01010004, 0x00010404, 0x00000004, 0x00010000, 0x00000400, 0x01010400, + 0x01010404, 0x00000400, 0x01000404, 0x01010004, 0x01000000, 0x00000004, + 0x00000404, 0x01000400, 0x01000400, 0x00010400, 0x00010400, 0x01010000, + 0x01010000, 0x01000404, 0x00010004, 0x01000004, 0x01000004, 0x00010004, + 0x00000000, 0x00000404, 0x00010404, 0x01000000, 0x00010000, 0x01010404, + 0x00000004, 0x01010000, 0x01010400, 0x01000000, 0x01000000, 0x00000400, + 0x01010004, 0x00010000, 0x00010400, 0x01000004, 0x00000400, 0x00000004, + 0x01000404, 0x00010404, 0x01010404, 0x00010004, 0x01010000, 0x01000404, + 0x01000004, 0x00000404, 0x00010404, 0x01010400, 0x00000404, 0x01000400, + 0x01000400, 0x00000000, 0x00010004, 0x00010400, 0x00000000, 0x01010004, + 0x01010400, 0x00000000, 0x00010000, 0x01010404, 0x01010004, 0x00010404, + 0x00000004, 0x00010000, 0x00000400, 0x01010400, 0x01010404, 0x00000400, + 0x01000404, 0x01010004, 0x01000000, 0x00000004, 0x00000404, 0x01000400, + 0x01000400, 0x00010400, 0x00010400, 0x01010000, 0x01010000, 0x01000404, + 0x00010004, 0x01000004, 0x01000004, 0x00010004, 0x00000000, 0x00000404, + 0x00010404, 0x01000000, 0x00010000, 0x01010404, 0x00000004, 0x01010000, + 0x01010400, 0x01000000, 0x01000000, 0x00000400, 0x01010004, 0x00010000, + 0x00010400, 0x01000004, 0x00000400, 0x00000004, 0x01000404, 0x00010404, + 0x01010404, 0x00010004, 0x01010000, 0x01000404, 0x01000004, 0x00000404, + 0x00010404, 0x01010400, 0x00000404, 0x01000400, 0x01000400, 0x00000000, + 0x00010004, 0x00010400, 0x00000000, 0x01010004 }; + +const uint32_t DES_SPBOX2[256] = { + 0x80108020, 0x80008000, 0x00008000, 0x00108020, 0x00100000, 0x00000020, + 0x80100020, 0x80008020, 0x80000020, 0x80108020, 0x80108000, 0x80000000, + 0x80008000, 0x00100000, 0x00000020, 0x80100020, 0x00108000, 0x00100020, + 0x80008020, 0x00000000, 0x80000000, 0x00008000, 0x00108020, 0x80100000, + 0x00100020, 0x80000020, 0x00000000, 0x00108000, 0x00008020, 0x80108000, + 0x80100000, 0x00008020, 0x00000000, 0x00108020, 0x80100020, 0x00100000, + 0x80008020, 0x80100000, 0x80108000, 0x00008000, 0x80100000, 0x80008000, + 0x00000020, 0x80108020, 0x00108020, 0x00000020, 0x00008000, 0x80000000, + 0x00008020, 0x80108000, 0x00100000, 0x80000020, 0x00100020, 0x80008020, + 0x80000020, 0x00100020, 0x00108000, 0x00000000, 0x80008000, 0x00008020, + 0x80000000, 0x80100020, 0x80108020, 0x00108000, 0x80108020, 0x80008000, + 0x00008000, 0x00108020, 0x00100000, 0x00000020, 0x80100020, 0x80008020, + 0x80000020, 0x80108020, 0x80108000, 0x80000000, 0x80008000, 0x00100000, + 0x00000020, 0x80100020, 0x00108000, 0x00100020, 0x80008020, 0x00000000, + 0x80000000, 0x00008000, 0x00108020, 0x80100000, 0x00100020, 0x80000020, + 0x00000000, 0x00108000, 0x00008020, 0x80108000, 0x80100000, 0x00008020, + 0x00000000, 0x00108020, 0x80100020, 0x00100000, 0x80008020, 0x80100000, + 0x80108000, 0x00008000, 0x80100000, 0x80008000, 0x00000020, 0x80108020, + 0x00108020, 0x00000020, 0x00008000, 0x80000000, 0x00008020, 0x80108000, + 0x00100000, 0x80000020, 0x00100020, 0x80008020, 0x80000020, 0x00100020, + 0x00108000, 0x00000000, 0x80008000, 0x00008020, 0x80000000, 0x80100020, + 0x80108020, 0x00108000, 0x80108020, 0x80008000, 0x00008000, 0x00108020, + 0x00100000, 0x00000020, 0x80100020, 0x80008020, 0x80000020, 0x80108020, + 0x80108000, 0x80000000, 0x80008000, 0x00100000, 0x00000020, 0x80100020, + 0x00108000, 0x00100020, 0x80008020, 0x00000000, 0x80000000, 0x00008000, + 0x00108020, 0x80100000, 0x00100020, 0x80000020, 0x00000000, 0x00108000, + 0x00008020, 0x80108000, 0x80100000, 0x00008020, 0x00000000, 0x00108020, + 0x80100020, 0x00100000, 0x80008020, 0x80100000, 0x80108000, 0x00008000, + 0x80100000, 0x80008000, 0x00000020, 0x80108020, 0x00108020, 0x00000020, + 0x00008000, 0x80000000, 0x00008020, 0x80108000, 0x00100000, 0x80000020, + 0x00100020, 0x80008020, 0x80000020, 0x00100020, 0x00108000, 0x00000000, + 0x80008000, 0x00008020, 0x80000000, 0x80100020, 0x80108020, 0x00108000, + 0x80108020, 0x80008000, 0x00008000, 0x00108020, 0x00100000, 0x00000020, + 0x80100020, 0x80008020, 0x80000020, 0x80108020, 0x80108000, 0x80000000, + 0x80008000, 0x00100000, 0x00000020, 0x80100020, 0x00108000, 0x00100020, + 0x80008020, 0x00000000, 0x80000000, 0x00008000, 0x00108020, 0x80100000, + 0x00100020, 0x80000020, 0x00000000, 0x00108000, 0x00008020, 0x80108000, + 0x80100000, 0x00008020, 0x00000000, 0x00108020, 0x80100020, 0x00100000, + 0x80008020, 0x80100000, 0x80108000, 0x00008000, 0x80100000, 0x80008000, + 0x00000020, 0x80108020, 0x00108020, 0x00000020, 0x00008000, 0x80000000, + 0x00008020, 0x80108000, 0x00100000, 0x80000020, 0x00100020, 0x80008020, + 0x80000020, 0x00100020, 0x00108000, 0x00000000, 0x80008000, 0x00008020, + 0x80000000, 0x80100020, 0x80108020, 0x00108000 }; + +const uint32_t DES_SPBOX3[256] = { + 0x00000208, 0x08020200, 0x00000000, 0x08020008, 0x08000200, 0x00000000, + 0x00020208, 0x08000200, 0x00020008, 0x08000008, 0x08000008, 0x00020000, + 0x08020208, 0x00020008, 0x08020000, 0x00000208, 0x08000000, 0x00000008, + 0x08020200, 0x00000200, 0x00020200, 0x08020000, 0x08020008, 0x00020208, + 0x08000208, 0x00020200, 0x00020000, 0x08000208, 0x00000008, 0x08020208, + 0x00000200, 0x08000000, 0x08020200, 0x08000000, 0x00020008, 0x00000208, + 0x00020000, 0x08020200, 0x08000200, 0x00000000, 0x00000200, 0x00020008, + 0x08020208, 0x08000200, 0x08000008, 0x00000200, 0x00000000, 0x08020008, + 0x08000208, 0x00020000, 0x08000000, 0x08020208, 0x00000008, 0x00020208, + 0x00020200, 0x08000008, 0x08020000, 0x08000208, 0x00000208, 0x08020000, + 0x00020208, 0x00000008, 0x08020008, 0x00020200, 0x00000208, 0x08020200, + 0x00000000, 0x08020008, 0x08000200, 0x00000000, 0x00020208, 0x08000200, + 0x00020008, 0x08000008, 0x08000008, 0x00020000, 0x08020208, 0x00020008, + 0x08020000, 0x00000208, 0x08000000, 0x00000008, 0x08020200, 0x00000200, + 0x00020200, 0x08020000, 0x08020008, 0x00020208, 0x08000208, 0x00020200, + 0x00020000, 0x08000208, 0x00000008, 0x08020208, 0x00000200, 0x08000000, + 0x08020200, 0x08000000, 0x00020008, 0x00000208, 0x00020000, 0x08020200, + 0x08000200, 0x00000000, 0x00000200, 0x00020008, 0x08020208, 0x08000200, + 0x08000008, 0x00000200, 0x00000000, 0x08020008, 0x08000208, 0x00020000, + 0x08000000, 0x08020208, 0x00000008, 0x00020208, 0x00020200, 0x08000008, + 0x08020000, 0x08000208, 0x00000208, 0x08020000, 0x00020208, 0x00000008, + 0x08020008, 0x00020200, 0x00000208, 0x08020200, 0x00000000, 0x08020008, + 0x08000200, 0x00000000, 0x00020208, 0x08000200, 0x00020008, 0x08000008, + 0x08000008, 0x00020000, 0x08020208, 0x00020008, 0x08020000, 0x00000208, + 0x08000000, 0x00000008, 0x08020200, 0x00000200, 0x00020200, 0x08020000, + 0x08020008, 0x00020208, 0x08000208, 0x00020200, 0x00020000, 0x08000208, + 0x00000008, 0x08020208, 0x00000200, 0x08000000, 0x08020200, 0x08000000, + 0x00020008, 0x00000208, 0x00020000, 0x08020200, 0x08000200, 0x00000000, + 0x00000200, 0x00020008, 0x08020208, 0x08000200, 0x08000008, 0x00000200, + 0x00000000, 0x08020008, 0x08000208, 0x00020000, 0x08000000, 0x08020208, + 0x00000008, 0x00020208, 0x00020200, 0x08000008, 0x08020000, 0x08000208, + 0x00000208, 0x08020000, 0x00020208, 0x00000008, 0x08020008, 0x00020200, + 0x00000208, 0x08020200, 0x00000000, 0x08020008, 0x08000200, 0x00000000, + 0x00020208, 0x08000200, 0x00020008, 0x08000008, 0x08000008, 0x00020000, + 0x08020208, 0x00020008, 0x08020000, 0x00000208, 0x08000000, 0x00000008, + 0x08020200, 0x00000200, 0x00020200, 0x08020000, 0x08020008, 0x00020208, + 0x08000208, 0x00020200, 0x00020000, 0x08000208, 0x00000008, 0x08020208, + 0x00000200, 0x08000000, 0x08020200, 0x08000000, 0x00020008, 0x00000208, + 0x00020000, 0x08020200, 0x08000200, 0x00000000, 0x00000200, 0x00020008, + 0x08020208, 0x08000200, 0x08000008, 0x00000200, 0x00000000, 0x08020008, + 0x08000208, 0x00020000, 0x08000000, 0x08020208, 0x00000008, 0x00020208, + 0x00020200, 0x08000008, 0x08020000, 0x08000208, 0x00000208, 0x08020000, + 0x00020208, 0x00000008, 0x08020008, 0x00020200 }; + +const uint32_t DES_SPBOX4[256] = { + 0x00802001, 0x00002081, 0x00002081, 0x00000080, 0x00802080, 0x00800081, + 0x00800001, 0x00002001, 0x00000000, 0x00802000, 0x00802000, 0x00802081, + 0x00000081, 0x00000000, 0x00800080, 0x00800001, 0x00000001, 0x00002000, + 0x00800000, 0x00802001, 0x00000080, 0x00800000, 0x00002001, 0x00002080, + 0x00800081, 0x00000001, 0x00002080, 0x00800080, 0x00002000, 0x00802080, + 0x00802081, 0x00000081, 0x00800080, 0x00800001, 0x00802000, 0x00802081, + 0x00000081, 0x00000000, 0x00000000, 0x00802000, 0x00002080, 0x00800080, + 0x00800081, 0x00000001, 0x00802001, 0x00002081, 0x00002081, 0x00000080, + 0x00802081, 0x00000081, 0x00000001, 0x00002000, 0x00800001, 0x00002001, + 0x00802080, 0x00800081, 0x00002001, 0x00002080, 0x00800000, 0x00802001, + 0x00000080, 0x00800000, 0x00002000, 0x00802080, 0x00802001, 0x00002081, + 0x00002081, 0x00000080, 0x00802080, 0x00800081, 0x00800001, 0x00002001, + 0x00000000, 0x00802000, 0x00802000, 0x00802081, 0x00000081, 0x00000000, + 0x00800080, 0x00800001, 0x00000001, 0x00002000, 0x00800000, 0x00802001, + 0x00000080, 0x00800000, 0x00002001, 0x00002080, 0x00800081, 0x00000001, + 0x00002080, 0x00800080, 0x00002000, 0x00802080, 0x00802081, 0x00000081, + 0x00800080, 0x00800001, 0x00802000, 0x00802081, 0x00000081, 0x00000000, + 0x00000000, 0x00802000, 0x00002080, 0x00800080, 0x00800081, 0x00000001, + 0x00802001, 0x00002081, 0x00002081, 0x00000080, 0x00802081, 0x00000081, + 0x00000001, 0x00002000, 0x00800001, 0x00002001, 0x00802080, 0x00800081, + 0x00002001, 0x00002080, 0x00800000, 0x00802001, 0x00000080, 0x00800000, + 0x00002000, 0x00802080, 0x00802001, 0x00002081, 0x00002081, 0x00000080, + 0x00802080, 0x00800081, 0x00800001, 0x00002001, 0x00000000, 0x00802000, + 0x00802000, 0x00802081, 0x00000081, 0x00000000, 0x00800080, 0x00800001, + 0x00000001, 0x00002000, 0x00800000, 0x00802001, 0x00000080, 0x00800000, + 0x00002001, 0x00002080, 0x00800081, 0x00000001, 0x00002080, 0x00800080, + 0x00002000, 0x00802080, 0x00802081, 0x00000081, 0x00800080, 0x00800001, + 0x00802000, 0x00802081, 0x00000081, 0x00000000, 0x00000000, 0x00802000, + 0x00002080, 0x00800080, 0x00800081, 0x00000001, 0x00802001, 0x00002081, + 0x00002081, 0x00000080, 0x00802081, 0x00000081, 0x00000001, 0x00002000, + 0x00800001, 0x00002001, 0x00802080, 0x00800081, 0x00002001, 0x00002080, + 0x00800000, 0x00802001, 0x00000080, 0x00800000, 0x00002000, 0x00802080, + 0x00802001, 0x00002081, 0x00002081, 0x00000080, 0x00802080, 0x00800081, + 0x00800001, 0x00002001, 0x00000000, 0x00802000, 0x00802000, 0x00802081, + 0x00000081, 0x00000000, 0x00800080, 0x00800001, 0x00000001, 0x00002000, + 0x00800000, 0x00802001, 0x00000080, 0x00800000, 0x00002001, 0x00002080, + 0x00800081, 0x00000001, 0x00002080, 0x00800080, 0x00002000, 0x00802080, + 0x00802081, 0x00000081, 0x00800080, 0x00800001, 0x00802000, 0x00802081, + 0x00000081, 0x00000000, 0x00000000, 0x00802000, 0x00002080, 0x00800080, + 0x00800081, 0x00000001, 0x00802001, 0x00002081, 0x00002081, 0x00000080, + 0x00802081, 0x00000081, 0x00000001, 0x00002000, 0x00800001, 0x00002001, + 0x00802080, 0x00800081, 0x00002001, 0x00002080, 0x00800000, 0x00802001, + 0x00000080, 0x00800000, 0x00002000, 0x00802080 }; + +const uint32_t DES_SPBOX5[256] = { + 0x00000100, 0x02080100, 0x02080000, 0x42000100, 0x00080000, 0x00000100, + 0x40000000, 0x02080000, 0x40080100, 0x00080000, 0x02000100, 0x40080100, + 0x42000100, 0x42080000, 0x00080100, 0x40000000, 0x02000000, 0x40080000, + 0x40080000, 0x00000000, 0x40000100, 0x42080100, 0x42080100, 0x02000100, + 0x42080000, 0x40000100, 0x00000000, 0x42000000, 0x02080100, 0x02000000, + 0x42000000, 0x00080100, 0x00080000, 0x42000100, 0x00000100, 0x02000000, + 0x40000000, 0x02080000, 0x42000100, 0x40080100, 0x02000100, 0x40000000, + 0x42080000, 0x02080100, 0x40080100, 0x00000100, 0x02000000, 0x42080000, + 0x42080100, 0x00080100, 0x42000000, 0x42080100, 0x02080000, 0x00000000, + 0x40080000, 0x42000000, 0x00080100, 0x02000100, 0x40000100, 0x00080000, + 0x00000000, 0x40080000, 0x02080100, 0x40000100, 0x00000100, 0x02080100, + 0x02080000, 0x42000100, 0x00080000, 0x00000100, 0x40000000, 0x02080000, + 0x40080100, 0x00080000, 0x02000100, 0x40080100, 0x42000100, 0x42080000, + 0x00080100, 0x40000000, 0x02000000, 0x40080000, 0x40080000, 0x00000000, + 0x40000100, 0x42080100, 0x42080100, 0x02000100, 0x42080000, 0x40000100, + 0x00000000, 0x42000000, 0x02080100, 0x02000000, 0x42000000, 0x00080100, + 0x00080000, 0x42000100, 0x00000100, 0x02000000, 0x40000000, 0x02080000, + 0x42000100, 0x40080100, 0x02000100, 0x40000000, 0x42080000, 0x02080100, + 0x40080100, 0x00000100, 0x02000000, 0x42080000, 0x42080100, 0x00080100, + 0x42000000, 0x42080100, 0x02080000, 0x00000000, 0x40080000, 0x42000000, + 0x00080100, 0x02000100, 0x40000100, 0x00080000, 0x00000000, 0x40080000, + 0x02080100, 0x40000100, 0x00000100, 0x02080100, 0x02080000, 0x42000100, + 0x00080000, 0x00000100, 0x40000000, 0x02080000, 0x40080100, 0x00080000, + 0x02000100, 0x40080100, 0x42000100, 0x42080000, 0x00080100, 0x40000000, + 0x02000000, 0x40080000, 0x40080000, 0x00000000, 0x40000100, 0x42080100, + 0x42080100, 0x02000100, 0x42080000, 0x40000100, 0x00000000, 0x42000000, + 0x02080100, 0x02000000, 0x42000000, 0x00080100, 0x00080000, 0x42000100, + 0x00000100, 0x02000000, 0x40000000, 0x02080000, 0x42000100, 0x40080100, + 0x02000100, 0x40000000, 0x42080000, 0x02080100, 0x40080100, 0x00000100, + 0x02000000, 0x42080000, 0x42080100, 0x00080100, 0x42000000, 0x42080100, + 0x02080000, 0x00000000, 0x40080000, 0x42000000, 0x00080100, 0x02000100, + 0x40000100, 0x00080000, 0x00000000, 0x40080000, 0x02080100, 0x40000100, + 0x00000100, 0x02080100, 0x02080000, 0x42000100, 0x00080000, 0x00000100, + 0x40000000, 0x02080000, 0x40080100, 0x00080000, 0x02000100, 0x40080100, + 0x42000100, 0x42080000, 0x00080100, 0x40000000, 0x02000000, 0x40080000, + 0x40080000, 0x00000000, 0x40000100, 0x42080100, 0x42080100, 0x02000100, + 0x42080000, 0x40000100, 0x00000000, 0x42000000, 0x02080100, 0x02000000, + 0x42000000, 0x00080100, 0x00080000, 0x42000100, 0x00000100, 0x02000000, + 0x40000000, 0x02080000, 0x42000100, 0x40080100, 0x02000100, 0x40000000, + 0x42080000, 0x02080100, 0x40080100, 0x00000100, 0x02000000, 0x42080000, + 0x42080100, 0x00080100, 0x42000000, 0x42080100, 0x02080000, 0x00000000, + 0x40080000, 0x42000000, 0x00080100, 0x02000100, 0x40000100, 0x00080000, + 0x00000000, 0x40080000, 0x02080100, 0x40000100 }; + +const uint32_t DES_SPBOX6[256] = { + 0x20000010, 0x20400000, 0x00004000, 0x20404010, 0x20400000, 0x00000010, + 0x20404010, 0x00400000, 0x20004000, 0x00404010, 0x00400000, 0x20000010, + 0x00400010, 0x20004000, 0x20000000, 0x00004010, 0x00000000, 0x00400010, + 0x20004010, 0x00004000, 0x00404000, 0x20004010, 0x00000010, 0x20400010, + 0x20400010, 0x00000000, 0x00404010, 0x20404000, 0x00004010, 0x00404000, + 0x20404000, 0x20000000, 0x20004000, 0x00000010, 0x20400010, 0x00404000, + 0x20404010, 0x00400000, 0x00004010, 0x20000010, 0x00400000, 0x20004000, + 0x20000000, 0x00004010, 0x20000010, 0x20404010, 0x00404000, 0x20400000, + 0x00404010, 0x20404000, 0x00000000, 0x20400010, 0x00000010, 0x00004000, + 0x20400000, 0x00404010, 0x00004000, 0x00400010, 0x20004010, 0x00000000, + 0x20404000, 0x20000000, 0x00400010, 0x20004010, 0x20000010, 0x20400000, + 0x00004000, 0x20404010, 0x20400000, 0x00000010, 0x20404010, 0x00400000, + 0x20004000, 0x00404010, 0x00400000, 0x20000010, 0x00400010, 0x20004000, + 0x20000000, 0x00004010, 0x00000000, 0x00400010, 0x20004010, 0x00004000, + 0x00404000, 0x20004010, 0x00000010, 0x20400010, 0x20400010, 0x00000000, + 0x00404010, 0x20404000, 0x00004010, 0x00404000, 0x20404000, 0x20000000, + 0x20004000, 0x00000010, 0x20400010, 0x00404000, 0x20404010, 0x00400000, + 0x00004010, 0x20000010, 0x00400000, 0x20004000, 0x20000000, 0x00004010, + 0x20000010, 0x20404010, 0x00404000, 0x20400000, 0x00404010, 0x20404000, + 0x00000000, 0x20400010, 0x00000010, 0x00004000, 0x20400000, 0x00404010, + 0x00004000, 0x00400010, 0x20004010, 0x00000000, 0x20404000, 0x20000000, + 0x00400010, 0x20004010, 0x20000010, 0x20400000, 0x00004000, 0x20404010, + 0x20400000, 0x00000010, 0x20404010, 0x00400000, 0x20004000, 0x00404010, + 0x00400000, 0x20000010, 0x00400010, 0x20004000, 0x20000000, 0x00004010, + 0x00000000, 0x00400010, 0x20004010, 0x00004000, 0x00404000, 0x20004010, + 0x00000010, 0x20400010, 0x20400010, 0x00000000, 0x00404010, 0x20404000, + 0x00004010, 0x00404000, 0x20404000, 0x20000000, 0x20004000, 0x00000010, + 0x20400010, 0x00404000, 0x20404010, 0x00400000, 0x00004010, 0x20000010, + 0x00400000, 0x20004000, 0x20000000, 0x00004010, 0x20000010, 0x20404010, + 0x00404000, 0x20400000, 0x00404010, 0x20404000, 0x00000000, 0x20400010, + 0x00000010, 0x00004000, 0x20400000, 0x00404010, 0x00004000, 0x00400010, + 0x20004010, 0x00000000, 0x20404000, 0x20000000, 0x00400010, 0x20004010, + 0x20000010, 0x20400000, 0x00004000, 0x20404010, 0x20400000, 0x00000010, + 0x20404010, 0x00400000, 0x20004000, 0x00404010, 0x00400000, 0x20000010, + 0x00400010, 0x20004000, 0x20000000, 0x00004010, 0x00000000, 0x00400010, + 0x20004010, 0x00004000, 0x00404000, 0x20004010, 0x00000010, 0x20400010, + 0x20400010, 0x00000000, 0x00404010, 0x20404000, 0x00004010, 0x00404000, + 0x20404000, 0x20000000, 0x20004000, 0x00000010, 0x20400010, 0x00404000, + 0x20404010, 0x00400000, 0x00004010, 0x20000010, 0x00400000, 0x20004000, + 0x20000000, 0x00004010, 0x20000010, 0x20404010, 0x00404000, 0x20400000, + 0x00404010, 0x20404000, 0x00000000, 0x20400010, 0x00000010, 0x00004000, + 0x20400000, 0x00404010, 0x00004000, 0x00400010, 0x20004010, 0x00000000, + 0x20404000, 0x20000000, 0x00400010, 0x20004010 }; + +const uint32_t DES_SPBOX7[256] = { + 0x00200000, 0x04200002, 0x04000802, 0x00000000, 0x00000800, 0x04000802, + 0x00200802, 0x04200800, 0x04200802, 0x00200000, 0x00000000, 0x04000002, + 0x00000002, 0x04000000, 0x04200002, 0x00000802, 0x04000800, 0x00200802, + 0x00200002, 0x04000800, 0x04000002, 0x04200000, 0x04200800, 0x00200002, + 0x04200000, 0x00000800, 0x00000802, 0x04200802, 0x00200800, 0x00000002, + 0x04000000, 0x00200800, 0x04000000, 0x00200800, 0x00200000, 0x04000802, + 0x04000802, 0x04200002, 0x04200002, 0x00000002, 0x00200002, 0x04000000, + 0x04000800, 0x00200000, 0x04200800, 0x00000802, 0x00200802, 0x04200800, + 0x00000802, 0x04000002, 0x04200802, 0x04200000, 0x00200800, 0x00000000, + 0x00000002, 0x04200802, 0x00000000, 0x00200802, 0x04200000, 0x00000800, + 0x04000002, 0x04000800, 0x00000800, 0x00200002, 0x00200000, 0x04200002, + 0x04000802, 0x00000000, 0x00000800, 0x04000802, 0x00200802, 0x04200800, + 0x04200802, 0x00200000, 0x00000000, 0x04000002, 0x00000002, 0x04000000, + 0x04200002, 0x00000802, 0x04000800, 0x00200802, 0x00200002, 0x04000800, + 0x04000002, 0x04200000, 0x04200800, 0x00200002, 0x04200000, 0x00000800, + 0x00000802, 0x04200802, 0x00200800, 0x00000002, 0x04000000, 0x00200800, + 0x04000000, 0x00200800, 0x00200000, 0x04000802, 0x04000802, 0x04200002, + 0x04200002, 0x00000002, 0x00200002, 0x04000000, 0x04000800, 0x00200000, + 0x04200800, 0x00000802, 0x00200802, 0x04200800, 0x00000802, 0x04000002, + 0x04200802, 0x04200000, 0x00200800, 0x00000000, 0x00000002, 0x04200802, + 0x00000000, 0x00200802, 0x04200000, 0x00000800, 0x04000002, 0x04000800, + 0x00000800, 0x00200002, 0x00200000, 0x04200002, 0x04000802, 0x00000000, + 0x00000800, 0x04000802, 0x00200802, 0x04200800, 0x04200802, 0x00200000, + 0x00000000, 0x04000002, 0x00000002, 0x04000000, 0x04200002, 0x00000802, + 0x04000800, 0x00200802, 0x00200002, 0x04000800, 0x04000002, 0x04200000, + 0x04200800, 0x00200002, 0x04200000, 0x00000800, 0x00000802, 0x04200802, + 0x00200800, 0x00000002, 0x04000000, 0x00200800, 0x04000000, 0x00200800, + 0x00200000, 0x04000802, 0x04000802, 0x04200002, 0x04200002, 0x00000002, + 0x00200002, 0x04000000, 0x04000800, 0x00200000, 0x04200800, 0x00000802, + 0x00200802, 0x04200800, 0x00000802, 0x04000002, 0x04200802, 0x04200000, + 0x00200800, 0x00000000, 0x00000002, 0x04200802, 0x00000000, 0x00200802, + 0x04200000, 0x00000800, 0x04000002, 0x04000800, 0x00000800, 0x00200002, + 0x00200000, 0x04200002, 0x04000802, 0x00000000, 0x00000800, 0x04000802, + 0x00200802, 0x04200800, 0x04200802, 0x00200000, 0x00000000, 0x04000002, + 0x00000002, 0x04000000, 0x04200002, 0x00000802, 0x04000800, 0x00200802, + 0x00200002, 0x04000800, 0x04000002, 0x04200000, 0x04200800, 0x00200002, + 0x04200000, 0x00000800, 0x00000802, 0x04200802, 0x00200800, 0x00000002, + 0x04000000, 0x00200800, 0x04000000, 0x00200800, 0x00200000, 0x04000802, + 0x04000802, 0x04200002, 0x04200002, 0x00000002, 0x00200002, 0x04000000, + 0x04000800, 0x00200000, 0x04200800, 0x00000802, 0x00200802, 0x04200800, + 0x00000802, 0x04000002, 0x04200802, 0x04200000, 0x00200800, 0x00000000, + 0x00000002, 0x04200802, 0x00000000, 0x00200802, 0x04200000, 0x00000800, + 0x04000002, 0x04000800, 0x00000800, 0x00200002 }; + +const uint32_t DES_SPBOX8[256] = { + 0x10001040, 0x00001000, 0x00040000, 0x10041040, 0x10000000, 0x10001040, + 0x00000040, 0x10000000, 0x00040040, 0x10040000, 0x10041040, 0x00041000, + 0x10041000, 0x00041040, 0x00001000, 0x00000040, 0x10040000, 0x10000040, + 0x10001000, 0x00001040, 0x00041000, 0x00040040, 0x10040040, 0x10041000, + 0x00001040, 0x00000000, 0x00000000, 0x10040040, 0x10000040, 0x10001000, + 0x00041040, 0x00040000, 0x00041040, 0x00040000, 0x10041000, 0x00001000, + 0x00000040, 0x10040040, 0x00001000, 0x00041040, 0x10001000, 0x00000040, + 0x10000040, 0x10040000, 0x10040040, 0x10000000, 0x00040000, 0x10001040, + 0x00000000, 0x10041040, 0x00040040, 0x10000040, 0x10040000, 0x10001000, + 0x10001040, 0x00000000, 0x10041040, 0x00041000, 0x00041000, 0x00001040, + 0x00001040, 0x00040040, 0x10000000, 0x10041000, 0x10001040, 0x00001000, + 0x00040000, 0x10041040, 0x10000000, 0x10001040, 0x00000040, 0x10000000, + 0x00040040, 0x10040000, 0x10041040, 0x00041000, 0x10041000, 0x00041040, + 0x00001000, 0x00000040, 0x10040000, 0x10000040, 0x10001000, 0x00001040, + 0x00041000, 0x00040040, 0x10040040, 0x10041000, 0x00001040, 0x00000000, + 0x00000000, 0x10040040, 0x10000040, 0x10001000, 0x00041040, 0x00040000, + 0x00041040, 0x00040000, 0x10041000, 0x00001000, 0x00000040, 0x10040040, + 0x00001000, 0x00041040, 0x10001000, 0x00000040, 0x10000040, 0x10040000, + 0x10040040, 0x10000000, 0x00040000, 0x10001040, 0x00000000, 0x10041040, + 0x00040040, 0x10000040, 0x10040000, 0x10001000, 0x10001040, 0x00000000, + 0x10041040, 0x00041000, 0x00041000, 0x00001040, 0x00001040, 0x00040040, + 0x10000000, 0x10041000, 0x10001040, 0x00001000, 0x00040000, 0x10041040, + 0x10000000, 0x10001040, 0x00000040, 0x10000000, 0x00040040, 0x10040000, + 0x10041040, 0x00041000, 0x10041000, 0x00041040, 0x00001000, 0x00000040, + 0x10040000, 0x10000040, 0x10001000, 0x00001040, 0x00041000, 0x00040040, + 0x10040040, 0x10041000, 0x00001040, 0x00000000, 0x00000000, 0x10040040, + 0x10000040, 0x10001000, 0x00041040, 0x00040000, 0x00041040, 0x00040000, + 0x10041000, 0x00001000, 0x00000040, 0x10040040, 0x00001000, 0x00041040, + 0x10001000, 0x00000040, 0x10000040, 0x10040000, 0x10040040, 0x10000000, + 0x00040000, 0x10001040, 0x00000000, 0x10041040, 0x00040040, 0x10000040, + 0x10040000, 0x10001000, 0x10001040, 0x00000000, 0x10041040, 0x00041000, + 0x00041000, 0x00001040, 0x00001040, 0x00040040, 0x10000000, 0x10041000, + 0x10001040, 0x00001000, 0x00040000, 0x10041040, 0x10000000, 0x10001040, + 0x00000040, 0x10000000, 0x00040040, 0x10040000, 0x10041040, 0x00041000, + 0x10041000, 0x00041040, 0x00001000, 0x00000040, 0x10040000, 0x10000040, + 0x10001000, 0x00001040, 0x00041000, 0x00040040, 0x10040040, 0x10041000, + 0x00001040, 0x00000000, 0x00000000, 0x10040040, 0x10000040, 0x10001000, + 0x00041040, 0x00040000, 0x00041040, 0x00040000, 0x10041000, 0x00001000, + 0x00000040, 0x10040040, 0x00001000, 0x00041040, 0x10001000, 0x00000040, + 0x10000040, 0x10040000, 0x10040040, 0x10000000, 0x00040000, 0x10001040, + 0x00000000, 0x10041040, 0x00040040, 0x10000040, 0x10040000, 0x10001000, + 0x10001040, 0x00000000, 0x10041040, 0x00041000, 0x00041000, 0x00001040, + 0x00001040, 0x00040040, 0x10000000, 0x10041000 }; + +const uint64_t DES_IPTAB1[256] = { +0x0000000000000000, 0x0000000200000000, 0x0000000000000002, 0x0000000200000002, +0x0000020000000000, 0x0000020200000000, 0x0000020000000002, 0x0000020200000002, +0x0000000000000200, 0x0000000200000200, 0x0000000000000202, 0x0000000200000202, +0x0000020000000200, 0x0000020200000200, 0x0000020000000202, 0x0000020200000202, +0x0002000000000000, 0x0002000200000000, 0x0002000000000002, 0x0002000200000002, +0x0002020000000000, 0x0002020200000000, 0x0002020000000002, 0x0002020200000002, +0x0002000000000200, 0x0002000200000200, 0x0002000000000202, 0x0002000200000202, +0x0002020000000200, 0x0002020200000200, 0x0002020000000202, 0x0002020200000202, +0x0000000000020000, 0x0000000200020000, 0x0000000000020002, 0x0000000200020002, +0x0000020000020000, 0x0000020200020000, 0x0000020000020002, 0x0000020200020002, +0x0000000000020200, 0x0000000200020200, 0x0000000000020202, 0x0000000200020202, +0x0000020000020200, 0x0000020200020200, 0x0000020000020202, 0x0000020200020202, +0x0002000000020000, 0x0002000200020000, 0x0002000000020002, 0x0002000200020002, +0x0002020000020000, 0x0002020200020000, 0x0002020000020002, 0x0002020200020002, +0x0002000000020200, 0x0002000200020200, 0x0002000000020202, 0x0002000200020202, +0x0002020000020200, 0x0002020200020200, 0x0002020000020202, 0x0002020200020202, +0x0200000000000000, 0x0200000200000000, 0x0200000000000002, 0x0200000200000002, +0x0200020000000000, 0x0200020200000000, 0x0200020000000002, 0x0200020200000002, +0x0200000000000200, 0x0200000200000200, 0x0200000000000202, 0x0200000200000202, +0x0200020000000200, 0x0200020200000200, 0x0200020000000202, 0x0200020200000202, +0x0202000000000000, 0x0202000200000000, 0x0202000000000002, 0x0202000200000002, +0x0202020000000000, 0x0202020200000000, 0x0202020000000002, 0x0202020200000002, +0x0202000000000200, 0x0202000200000200, 0x0202000000000202, 0x0202000200000202, +0x0202020000000200, 0x0202020200000200, 0x0202020000000202, 0x0202020200000202, +0x0200000000020000, 0x0200000200020000, 0x0200000000020002, 0x0200000200020002, +0x0200020000020000, 0x0200020200020000, 0x0200020000020002, 0x0200020200020002, +0x0200000000020200, 0x0200000200020200, 0x0200000000020202, 0x0200000200020202, +0x0200020000020200, 0x0200020200020200, 0x0200020000020202, 0x0200020200020202, +0x0202000000020000, 0x0202000200020000, 0x0202000000020002, 0x0202000200020002, +0x0202020000020000, 0x0202020200020000, 0x0202020000020002, 0x0202020200020002, +0x0202000000020200, 0x0202000200020200, 0x0202000000020202, 0x0202000200020202, +0x0202020000020200, 0x0202020200020200, 0x0202020000020202, 0x0202020200020202, +0x0000000002000000, 0x0000000202000000, 0x0000000002000002, 0x0000000202000002, +0x0000020002000000, 0x0000020202000000, 0x0000020002000002, 0x0000020202000002, +0x0000000002000200, 0x0000000202000200, 0x0000000002000202, 0x0000000202000202, +0x0000020002000200, 0x0000020202000200, 0x0000020002000202, 0x0000020202000202, +0x0002000002000000, 0x0002000202000000, 0x0002000002000002, 0x0002000202000002, +0x0002020002000000, 0x0002020202000000, 0x0002020002000002, 0x0002020202000002, +0x0002000002000200, 0x0002000202000200, 0x0002000002000202, 0x0002000202000202, +0x0002020002000200, 0x0002020202000200, 0x0002020002000202, 0x0002020202000202, +0x0000000002020000, 0x0000000202020000, 0x0000000002020002, 0x0000000202020002, +0x0000020002020000, 0x0000020202020000, 0x0000020002020002, 0x0000020202020002, +0x0000000002020200, 0x0000000202020200, 0x0000000002020202, 0x0000000202020202, +0x0000020002020200, 0x0000020202020200, 0x0000020002020202, 0x0000020202020202, +0x0002000002020000, 0x0002000202020000, 0x0002000002020002, 0x0002000202020002, +0x0002020002020000, 0x0002020202020000, 0x0002020002020002, 0x0002020202020002, +0x0002000002020200, 0x0002000202020200, 0x0002000002020202, 0x0002000202020202, +0x0002020002020200, 0x0002020202020200, 0x0002020002020202, 0x0002020202020202, +0x0200000002000000, 0x0200000202000000, 0x0200000002000002, 0x0200000202000002, +0x0200020002000000, 0x0200020202000000, 0x0200020002000002, 0x0200020202000002, +0x0200000002000200, 0x0200000202000200, 0x0200000002000202, 0x0200000202000202, +0x0200020002000200, 0x0200020202000200, 0x0200020002000202, 0x0200020202000202, +0x0202000002000000, 0x0202000202000000, 0x0202000002000002, 0x0202000202000002, +0x0202020002000000, 0x0202020202000000, 0x0202020002000002, 0x0202020202000002, +0x0202000002000200, 0x0202000202000200, 0x0202000002000202, 0x0202000202000202, +0x0202020002000200, 0x0202020202000200, 0x0202020002000202, 0x0202020202000202, +0x0200000002020000, 0x0200000202020000, 0x0200000002020002, 0x0200000202020002, +0x0200020002020000, 0x0200020202020000, 0x0200020002020002, 0x0200020202020002, +0x0200000002020200, 0x0200000202020200, 0x0200000002020202, 0x0200000202020202, +0x0200020002020200, 0x0200020202020200, 0x0200020002020202, 0x0200020202020202, +0x0202000002020000, 0x0202000202020000, 0x0202000002020002, 0x0202000202020002, +0x0202020002020000, 0x0202020202020000, 0x0202020002020002, 0x0202020202020002, +0x0202000002020200, 0x0202000202020200, 0x0202000002020202, 0x0202000202020202, +0x0202020002020200, 0x0202020202020200, 0x0202020002020202, 0x0202020202020202 }; + +const uint64_t DES_IPTAB2[256] = { +0x0000000000000000, 0x0000010000000000, 0x0000000000000100, 0x0000010000000100, +0x0001000000000000, 0x0001010000000000, 0x0001000000000100, 0x0001010000000100, +0x0000000000010000, 0x0000010000010000, 0x0000000000010100, 0x0000010000010100, +0x0001000000010000, 0x0001010000010000, 0x0001000000010100, 0x0001010000010100, +0x0100000000000000, 0x0100010000000000, 0x0100000000000100, 0x0100010000000100, +0x0101000000000000, 0x0101010000000000, 0x0101000000000100, 0x0101010000000100, +0x0100000000010000, 0x0100010000010000, 0x0100000000010100, 0x0100010000010100, +0x0101000000010000, 0x0101010000010000, 0x0101000000010100, 0x0101010000010100, +0x0000000001000000, 0x0000010001000000, 0x0000000001000100, 0x0000010001000100, +0x0001000001000000, 0x0001010001000000, 0x0001000001000100, 0x0001010001000100, +0x0000000001010000, 0x0000010001010000, 0x0000000001010100, 0x0000010001010100, +0x0001000001010000, 0x0001010001010000, 0x0001000001010100, 0x0001010001010100, +0x0100000001000000, 0x0100010001000000, 0x0100000001000100, 0x0100010001000100, +0x0101000001000000, 0x0101010001000000, 0x0101000001000100, 0x0101010001000100, +0x0100000001010000, 0x0100010001010000, 0x0100000001010100, 0x0100010001010100, +0x0101000001010000, 0x0101010001010000, 0x0101000001010100, 0x0101010001010100, +0x0000000100000000, 0x0000010100000000, 0x0000000100000100, 0x0000010100000100, +0x0001000100000000, 0x0001010100000000, 0x0001000100000100, 0x0001010100000100, +0x0000000100010000, 0x0000010100010000, 0x0000000100010100, 0x0000010100010100, +0x0001000100010000, 0x0001010100010000, 0x0001000100010100, 0x0001010100010100, +0x0100000100000000, 0x0100010100000000, 0x0100000100000100, 0x0100010100000100, +0x0101000100000000, 0x0101010100000000, 0x0101000100000100, 0x0101010100000100, +0x0100000100010000, 0x0100010100010000, 0x0100000100010100, 0x0100010100010100, +0x0101000100010000, 0x0101010100010000, 0x0101000100010100, 0x0101010100010100, +0x0000000101000000, 0x0000010101000000, 0x0000000101000100, 0x0000010101000100, +0x0001000101000000, 0x0001010101000000, 0x0001000101000100, 0x0001010101000100, +0x0000000101010000, 0x0000010101010000, 0x0000000101010100, 0x0000010101010100, +0x0001000101010000, 0x0001010101010000, 0x0001000101010100, 0x0001010101010100, +0x0100000101000000, 0x0100010101000000, 0x0100000101000100, 0x0100010101000100, +0x0101000101000000, 0x0101010101000000, 0x0101000101000100, 0x0101010101000100, +0x0100000101010000, 0x0100010101010000, 0x0100000101010100, 0x0100010101010100, +0x0101000101010000, 0x0101010101010000, 0x0101000101010100, 0x0101010101010100, +0x0000000000000001, 0x0000010000000001, 0x0000000000000101, 0x0000010000000101, +0x0001000000000001, 0x0001010000000001, 0x0001000000000101, 0x0001010000000101, +0x0000000000010001, 0x0000010000010001, 0x0000000000010101, 0x0000010000010101, +0x0001000000010001, 0x0001010000010001, 0x0001000000010101, 0x0001010000010101, +0x0100000000000001, 0x0100010000000001, 0x0100000000000101, 0x0100010000000101, +0x0101000000000001, 0x0101010000000001, 0x0101000000000101, 0x0101010000000101, +0x0100000000010001, 0x0100010000010001, 0x0100000000010101, 0x0100010000010101, +0x0101000000010001, 0x0101010000010001, 0x0101000000010101, 0x0101010000010101, +0x0000000001000001, 0x0000010001000001, 0x0000000001000101, 0x0000010001000101, +0x0001000001000001, 0x0001010001000001, 0x0001000001000101, 0x0001010001000101, +0x0000000001010001, 0x0000010001010001, 0x0000000001010101, 0x0000010001010101, +0x0001000001010001, 0x0001010001010001, 0x0001000001010101, 0x0001010001010101, +0x0100000001000001, 0x0100010001000001, 0x0100000001000101, 0x0100010001000101, +0x0101000001000001, 0x0101010001000001, 0x0101000001000101, 0x0101010001000101, +0x0100000001010001, 0x0100010001010001, 0x0100000001010101, 0x0100010001010101, +0x0101000001010001, 0x0101010001010001, 0x0101000001010101, 0x0101010001010101, +0x0000000100000001, 0x0000010100000001, 0x0000000100000101, 0x0000010100000101, +0x0001000100000001, 0x0001010100000001, 0x0001000100000101, 0x0001010100000101, +0x0000000100010001, 0x0000010100010001, 0x0000000100010101, 0x0000010100010101, +0x0001000100010001, 0x0001010100010001, 0x0001000100010101, 0x0001010100010101, +0x0100000100000001, 0x0100010100000001, 0x0100000100000101, 0x0100010100000101, +0x0101000100000001, 0x0101010100000001, 0x0101000100000101, 0x0101010100000101, +0x0100000100010001, 0x0100010100010001, 0x0100000100010101, 0x0100010100010101, +0x0101000100010001, 0x0101010100010001, 0x0101000100010101, 0x0101010100010101, +0x0000000101000001, 0x0000010101000001, 0x0000000101000101, 0x0000010101000101, +0x0001000101000001, 0x0001010101000001, 0x0001000101000101, 0x0001010101000101, +0x0000000101010001, 0x0000010101010001, 0x0000000101010101, 0x0000010101010101, +0x0001000101010001, 0x0001010101010001, 0x0001000101010101, 0x0001010101010101, +0x0100000101000001, 0x0100010101000001, 0x0100000101000101, 0x0100010101000101, +0x0101000101000001, 0x0101010101000001, 0x0101000101000101, 0x0101010101000101, +0x0100000101010001, 0x0100010101010001, 0x0100000101010101, 0x0100010101010101, +0x0101000101010001, 0x0101010101010001, 0x0101000101010101, 0x0101010101010101 }; + +const uint64_t DES_FPTAB1[256] = { +0x0000000000000000, 0x0000000100000000, 0x0000000004000000, 0x0000000104000000, +0x0000000000040000, 0x0000000100040000, 0x0000000004040000, 0x0000000104040000, +0x0000000000000400, 0x0000000100000400, 0x0000000004000400, 0x0000000104000400, +0x0000000000040400, 0x0000000100040400, 0x0000000004040400, 0x0000000104040400, +0x0000000000000004, 0x0000000100000004, 0x0000000004000004, 0x0000000104000004, +0x0000000000040004, 0x0000000100040004, 0x0000000004040004, 0x0000000104040004, +0x0000000000000404, 0x0000000100000404, 0x0000000004000404, 0x0000000104000404, +0x0000000000040404, 0x0000000100040404, 0x0000000004040404, 0x0000000104040404, +0x0400000000000000, 0x0400000100000000, 0x0400000004000000, 0x0400000104000000, +0x0400000000040000, 0x0400000100040000, 0x0400000004040000, 0x0400000104040000, +0x0400000000000400, 0x0400000100000400, 0x0400000004000400, 0x0400000104000400, +0x0400000000040400, 0x0400000100040400, 0x0400000004040400, 0x0400000104040400, +0x0400000000000004, 0x0400000100000004, 0x0400000004000004, 0x0400000104000004, +0x0400000000040004, 0x0400000100040004, 0x0400000004040004, 0x0400000104040004, +0x0400000000000404, 0x0400000100000404, 0x0400000004000404, 0x0400000104000404, +0x0400000000040404, 0x0400000100040404, 0x0400000004040404, 0x0400000104040404, +0x0004000000000000, 0x0004000100000000, 0x0004000004000000, 0x0004000104000000, +0x0004000000040000, 0x0004000100040000, 0x0004000004040000, 0x0004000104040000, +0x0004000000000400, 0x0004000100000400, 0x0004000004000400, 0x0004000104000400, +0x0004000000040400, 0x0004000100040400, 0x0004000004040400, 0x0004000104040400, +0x0004000000000004, 0x0004000100000004, 0x0004000004000004, 0x0004000104000004, +0x0004000000040004, 0x0004000100040004, 0x0004000004040004, 0x0004000104040004, +0x0004000000000404, 0x0004000100000404, 0x0004000004000404, 0x0004000104000404, +0x0004000000040404, 0x0004000100040404, 0x0004000004040404, 0x0004000104040404, +0x0404000000000000, 0x0404000100000000, 0x0404000004000000, 0x0404000104000000, +0x0404000000040000, 0x0404000100040000, 0x0404000004040000, 0x0404000104040000, +0x0404000000000400, 0x0404000100000400, 0x0404000004000400, 0x0404000104000400, +0x0404000000040400, 0x0404000100040400, 0x0404000004040400, 0x0404000104040400, +0x0404000000000004, 0x0404000100000004, 0x0404000004000004, 0x0404000104000004, +0x0404000000040004, 0x0404000100040004, 0x0404000004040004, 0x0404000104040004, +0x0404000000000404, 0x0404000100000404, 0x0404000004000404, 0x0404000104000404, +0x0404000000040404, 0x0404000100040404, 0x0404000004040404, 0x0404000104040404, +0x0000040000000000, 0x0000040100000000, 0x0000040004000000, 0x0000040104000000, +0x0000040000040000, 0x0000040100040000, 0x0000040004040000, 0x0000040104040000, +0x0000040000000400, 0x0000040100000400, 0x0000040004000400, 0x0000040104000400, +0x0000040000040400, 0x0000040100040400, 0x0000040004040400, 0x0000040104040400, +0x0000040000000004, 0x0000040100000004, 0x0000040004000004, 0x0000040104000004, +0x0000040000040004, 0x0000040100040004, 0x0000040004040004, 0x0000040104040004, +0x0000040000000404, 0x0000040100000404, 0x0000040004000404, 0x0000040104000404, +0x0000040000040404, 0x0000040100040404, 0x0000040004040404, 0x0000040104040404, +0x0400040000000000, 0x0400040100000000, 0x0400040004000000, 0x0400040104000000, +0x0400040000040000, 0x0400040100040000, 0x0400040004040000, 0x0400040104040000, +0x0400040000000400, 0x0400040100000400, 0x0400040004000400, 0x0400040104000400, +0x0400040000040400, 0x0400040100040400, 0x0400040004040400, 0x0400040104040400, +0x0400040000000004, 0x0400040100000004, 0x0400040004000004, 0x0400040104000004, +0x0400040000040004, 0x0400040100040004, 0x0400040004040004, 0x0400040104040004, +0x0400040000000404, 0x0400040100000404, 0x0400040004000404, 0x0400040104000404, +0x0400040000040404, 0x0400040100040404, 0x0400040004040404, 0x0400040104040404, +0x0004040000000000, 0x0004040100000000, 0x0004040004000000, 0x0004040104000000, +0x0004040000040000, 0x0004040100040000, 0x0004040004040000, 0x0004040104040000, +0x0004040000000400, 0x0004040100000400, 0x0004040004000400, 0x0004040104000400, +0x0004040000040400, 0x0004040100040400, 0x0004040004040400, 0x0004040104040400, +0x0004040000000004, 0x0004040100000004, 0x0004040004000004, 0x0004040104000004, +0x0004040000040004, 0x0004040100040004, 0x0004040004040004, 0x0004040104040004, +0x0004040000000404, 0x0004040100000404, 0x0004040004000404, 0x0004040104000404, +0x0004040000040404, 0x0004040100040404, 0x0004040004040404, 0x0004040104040404, +0x0404040000000000, 0x0404040100000000, 0x0404040004000000, 0x0404040104000000, +0x0404040000040000, 0x0404040100040000, 0x0404040004040000, 0x0404040104040000, +0x0404040000000400, 0x0404040100000400, 0x0404040004000400, 0x0404040104000400, +0x0404040000040400, 0x0404040100040400, 0x0404040004040400, 0x0404040104040400, +0x0404040000000004, 0x0404040100000004, 0x0404040004000004, 0x0404040104000004, +0x0404040000040004, 0x0404040100040004, 0x0404040004040004, 0x0404040104040004, +0x0404040000000404, 0x0404040100000404, 0x0404040004000404, 0x0404040104000404, +0x0404040000040404, 0x0404040100040404, 0x0404040004040404, 0x0404040104040404 }; + +const uint64_t DES_FPTAB2[256] = { +0x0000000000000000, 0x0000004000000000, 0x0000000001000000, 0x0000004001000000, +0x0000000000010000, 0x0000004000010000, 0x0000000001010000, 0x0000004001010000, +0x0000000000000100, 0x0000004000000100, 0x0000000001000100, 0x0000004001000100, +0x0000000000010100, 0x0000004000010100, 0x0000000001010100, 0x0000004001010100, +0x0000000000000001, 0x0000004000000001, 0x0000000001000001, 0x0000004001000001, +0x0000000000010001, 0x0000004000010001, 0x0000000001010001, 0x0000004001010001, +0x0000000000000101, 0x0000004000000101, 0x0000000001000101, 0x0000004001000101, +0x0000000000010101, 0x0000004000010101, 0x0000000001010101, 0x0000004001010101, +0x0100000000000000, 0x0100004000000000, 0x0100000001000000, 0x0100004001000000, +0x0100000000010000, 0x0100004000010000, 0x0100000001010000, 0x0100004001010000, +0x0100000000000100, 0x0100004000000100, 0x0100000001000100, 0x0100004001000100, +0x0100000000010100, 0x0100004000010100, 0x0100000001010100, 0x0100004001010100, +0x0100000000000001, 0x0100004000000001, 0x0100000001000001, 0x0100004001000001, +0x0100000000010001, 0x0100004000010001, 0x0100000001010001, 0x0100004001010001, +0x0100000000000101, 0x0100004000000101, 0x0100000001000101, 0x0100004001000101, +0x0100000000010101, 0x0100004000010101, 0x0100000001010101, 0x0100004001010101, +0x0001000000000000, 0x0001004000000000, 0x0001000001000000, 0x0001004001000000, +0x0001000000010000, 0x0001004000010000, 0x0001000001010000, 0x0001004001010000, +0x0001000000000100, 0x0001004000000100, 0x0001000001000100, 0x0001004001000100, +0x0001000000010100, 0x0001004000010100, 0x0001000001010100, 0x0001004001010100, +0x0001000000000001, 0x0001004000000001, 0x0001000001000001, 0x0001004001000001, +0x0001000000010001, 0x0001004000010001, 0x0001000001010001, 0x0001004001010001, +0x0001000000000101, 0x0001004000000101, 0x0001000001000101, 0x0001004001000101, +0x0001000000010101, 0x0001004000010101, 0x0001000001010101, 0x0001004001010101, +0x0101000000000000, 0x0101004000000000, 0x0101000001000000, 0x0101004001000000, +0x0101000000010000, 0x0101004000010000, 0x0101000001010000, 0x0101004001010000, +0x0101000000000100, 0x0101004000000100, 0x0101000001000100, 0x0101004001000100, +0x0101000000010100, 0x0101004000010100, 0x0101000001010100, 0x0101004001010100, +0x0101000000000001, 0x0101004000000001, 0x0101000001000001, 0x0101004001000001, +0x0101000000010001, 0x0101004000010001, 0x0101000001010001, 0x0101004001010001, +0x0101000000000101, 0x0101004000000101, 0x0101000001000101, 0x0101004001000101, +0x0101000000010101, 0x0101004000010101, 0x0101000001010101, 0x0101004001010101, +0x0000010000000000, 0x0000014000000000, 0x0000010001000000, 0x0000014001000000, +0x0000010000010000, 0x0000014000010000, 0x0000010001010000, 0x0000014001010000, +0x0000010000000100, 0x0000014000000100, 0x0000010001000100, 0x0000014001000100, +0x0000010000010100, 0x0000014000010100, 0x0000010001010100, 0x0000014001010100, +0x0000010000000001, 0x0000014000000001, 0x0000010001000001, 0x0000014001000001, +0x0000010000010001, 0x0000014000010001, 0x0000010001010001, 0x0000014001010001, +0x0000010000000101, 0x0000014000000101, 0x0000010001000101, 0x0000014001000101, +0x0000010000010101, 0x0000014000010101, 0x0000010001010101, 0x0000014001010101, +0x0100010000000000, 0x0100014000000000, 0x0100010001000000, 0x0100014001000000, +0x0100010000010000, 0x0100014000010000, 0x0100010001010000, 0x0100014001010000, +0x0100010000000100, 0x0100014000000100, 0x0100010001000100, 0x0100014001000100, +0x0100010000010100, 0x0100014000010100, 0x0100010001010100, 0x0100014001010100, +0x0100010000000001, 0x0100014000000001, 0x0100010001000001, 0x0100014001000001, +0x0100010000010001, 0x0100014000010001, 0x0100010001010001, 0x0100014001010001, +0x0100010000000101, 0x0100014000000101, 0x0100010001000101, 0x0100014001000101, +0x0100010000010101, 0x0100014000010101, 0x0100010001010101, 0x0100014001010101, +0x0001010000000000, 0x0001014000000000, 0x0001010001000000, 0x0001014001000000, +0x0001010000010000, 0x0001014000010000, 0x0001010001010000, 0x0001014001010000, +0x0001010000000100, 0x0001014000000100, 0x0001010001000100, 0x0001014001000100, +0x0001010000010100, 0x0001014000010100, 0x0001010001010100, 0x0001014001010100, +0x0001010000000001, 0x0001014000000001, 0x0001010001000001, 0x0001014001000001, +0x0001010000010001, 0x0001014000010001, 0x0001010001010001, 0x0001014001010001, +0x0001010000000101, 0x0001014000000101, 0x0001010001000101, 0x0001014001000101, +0x0001010000010101, 0x0001014000010101, 0x0001010001010101, 0x0001014001010101, +0x0101010000000000, 0x0101014000000000, 0x0101010001000000, 0x0101014001000000, +0x0101010000010000, 0x0101014000010000, 0x0101010001010000, 0x0101014001010000, +0x0101010000000100, 0x0101014000000100, 0x0101010001000100, 0x0101014001000100, +0x0101010000010100, 0x0101014000010100, 0x0101010001010100, 0x0101014001010100, +0x0101010000000001, 0x0101014000000001, 0x0101010001000001, 0x0101014001000001, +0x0101010000010001, 0x0101014000010001, 0x0101010001010001, 0x0101014001010001, +0x0101010000000101, 0x0101014000000101, 0x0101010001000101, 0x0101014001000101, +0x0101010000010101, 0x0101014000010101, 0x0101010001010101, 0x0101014001010101 }; + +} diff --git a/src/libs/3rdparty/botan/src/lib/block/des/desx.cpp b/src/libs/3rdparty/botan/src/lib/block/des/desx.cpp new file mode 100644 index 0000000000..e869b3ebf8 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/block/des/desx.cpp @@ -0,0 +1,65 @@ +/* +* DES +* (C) 1999-2007 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include + +namespace Botan { + +/* +* DESX Encryption +*/ +void DESX::encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const + { + verify_key_set(m_K1.empty() == false); + + for(size_t i = 0; i != blocks; ++i) + { + xor_buf(out, in, m_K1.data(), BLOCK_SIZE); + m_des.encrypt(out); + xor_buf(out, m_K2.data(), BLOCK_SIZE); + + in += BLOCK_SIZE; + out += BLOCK_SIZE; + } + } + +/* +* DESX Decryption +*/ +void DESX::decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const + { + verify_key_set(m_K1.empty() == false); + + for(size_t i = 0; i != blocks; ++i) + { + xor_buf(out, in, m_K2.data(), BLOCK_SIZE); + m_des.decrypt(out); + xor_buf(out, m_K1.data(), BLOCK_SIZE); + + in += BLOCK_SIZE; + out += BLOCK_SIZE; + } + } + +/* +* DESX Key Schedule +*/ +void DESX::key_schedule(const uint8_t key[], size_t) + { + m_K1.assign(key, key + 8); + m_des.set_key(key + 8, 8); + m_K2.assign(key + 16, key + 24); + } + +void DESX::clear() + { + m_des.clear(); + zap(m_K1); + zap(m_K2); + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/block/des/desx.h b/src/libs/3rdparty/botan/src/lib/block/des/desx.h new file mode 100644 index 0000000000..fa9a996631 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/block/des/desx.h @@ -0,0 +1,35 @@ +/* +* DESX +* (C) 1999-2007 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_DESX_H_ +#define BOTAN_DESX_H_ + +#include + +namespace Botan { + +/** +* DESX +*/ +class BOTAN_PUBLIC_API(2,0) DESX final : public Block_Cipher_Fixed_Params<8, 24> + { + public: + void encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override; + void decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override; + + void clear() override; + std::string name() const override { return "DESX"; } + BlockCipher* clone() const override { return new DESX; } + private: + void key_schedule(const uint8_t[], size_t) override; + secure_vector m_K1, m_K2; + DES m_des; + }; + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/block/des/info.txt b/src/libs/3rdparty/botan/src/lib/block/des/info.txt new file mode 100644 index 0000000000..05f85b523c --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/block/des/info.txt @@ -0,0 +1,3 @@ + +DES -> 20131128 + diff --git a/src/libs/3rdparty/botan/src/lib/block/info.txt b/src/libs/3rdparty/botan/src/lib/block/info.txt new file mode 100644 index 0000000000..b03a8c8f59 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/block/info.txt @@ -0,0 +1,7 @@ + +BLOCK_CIPHER -> 20131128 + + + +block_cipher.h + diff --git a/src/libs/3rdparty/botan/src/lib/codec/base64/base64.cpp b/src/libs/3rdparty/botan/src/lib/codec/base64/base64.cpp new file mode 100644 index 0000000000..7f52fb5afb --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/codec/base64/base64.cpp @@ -0,0 +1,261 @@ +/* +* Base64 Encoding and Decoding +* (C) 2010,2015 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include + +namespace Botan { + +namespace { + +static const uint8_t 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]) + { + 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]; + } + +} + +size_t base64_encode(char out[], + const uint8_t in[], + size_t input_length, + 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; + } + +std::string base64_encode(const uint8_t input[], + size_t 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) + { + 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"); + + return output; + } + +size_t base64_decode(uint8_t output[], + const char input[], + 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(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(input[input_consumed])] == 0x80) + { + ++input_consumed; + } + + size_t written = (out_ptr - output) - final_truncate; + + return written; + } + +size_t base64_decode(uint8_t output[], + const char input[], + size_t input_length, + bool ignore_ws) + { + size_t consumed = 0; + size_t written = base64_decode(output, input, input_length, + consumed, true, ignore_ws); + + if(consumed != input_length) + throw Invalid_Argument("base64_decode: input did not have full bytes"); + + return written; + } + +size_t base64_decode(uint8_t output[], + const std::string& input, + bool ignore_ws) + { + return base64_decode(output, input.data(), input.length(), ignore_ws); + } + +secure_vector base64_decode(const char input[], + size_t input_length, + bool ignore_ws) + { + const size_t output_length = base64_decode_max_output(input_length); + secure_vector bin(output_length); + + size_t written = base64_decode(bin.data(), + input, + input_length, + ignore_ws); + + bin.resize(written); + return bin; + } + +secure_vector base64_decode(const std::string& input, + 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; + } + +size_t base64_decode_max_output(size_t input_length) + { + return (round_up(input_length, 4) * 3) / 4; + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/codec/base64/base64.h b/src/libs/3rdparty/botan/src/lib/codec/base64/base64.h new file mode 100644 index 0000000000..a20d03b0f7 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/codec/base64/base64.h @@ -0,0 +1,141 @@ +/* +* Base64 Encoding and Decoding +* (C) 2010 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_BASE64_CODEC_H_ +#define BOTAN_BASE64_CODEC_H_ + +#include +#include + +namespace Botan { + +/** +* Perform base64 encoding +* @param output an array of at least base64_encode_max_output bytes +* @param input is some binary data +* @param input_length length of input in bytes +* @param input_consumed is an output parameter which says how many +* bytes of input were actually consumed. If less than +* input_length, then the range input[consumed:length] +* should be passed in later along with more input. +* @param final_inputs true iff this is the last input, in which case + padding chars will be applied if needed +* @return number of bytes written to output +*/ +size_t BOTAN_PUBLIC_API(2,0) base64_encode(char output[], + const uint8_t input[], + size_t input_length, + size_t& input_consumed, + bool final_inputs); + +/** +* Perform base64 encoding +* @param input some input +* @param input_length length of input in bytes +* @return base64adecimal representation of input +*/ +std::string BOTAN_PUBLIC_API(2,0) base64_encode(const uint8_t input[], + size_t input_length); + +/** +* Perform base64 encoding +* @param input some input +* @return base64adecimal representation of input +*/ +template +std::string base64_encode(const std::vector& input) + { + return base64_encode(input.data(), input.size()); + } + +/** +* Perform base64 decoding +* @param output an array of at least base64_decode_max_output bytes +* @param input some base64 input +* @param input_length length of input in bytes +* @param input_consumed is an output parameter which says how many +* bytes of input were actually consumed. If less than +* input_length, then the range input[consumed:length] +* should be passed in later along with more input. +* @param final_inputs true iff this is the last input, in which case + padding is allowed +* @param ignore_ws ignore whitespace on input; if false, throw an + exception if whitespace is encountered +* @return number of bytes written to output +*/ +size_t BOTAN_PUBLIC_API(2,0) base64_decode(uint8_t output[], + const char input[], + size_t input_length, + size_t& input_consumed, + bool final_inputs, + bool ignore_ws = true); + +/** +* Perform base64 decoding +* @param output an array of at least base64_decode_max_output bytes +* @param input some base64 input +* @param input_length length of input in bytes +* @param ignore_ws ignore whitespace on input; if false, throw an + exception if whitespace is encountered +* @return number of bytes written to output +*/ +size_t BOTAN_PUBLIC_API(2,0) base64_decode(uint8_t output[], + const char input[], + size_t input_length, + bool ignore_ws = true); + +/** +* Perform base64 decoding +* @param output an array of at least base64_decode_max_output bytes +* @param input some base64 input +* @param ignore_ws ignore whitespace on input; if false, throw an + exception if whitespace is encountered +* @return number of bytes written to output +*/ +size_t BOTAN_PUBLIC_API(2,0) base64_decode(uint8_t output[], + const std::string& input, + bool ignore_ws = true); + +/** +* Perform base64 decoding +* @param input some base64 input +* @param input_length the length of input in bytes +* @param ignore_ws ignore whitespace on input; if false, throw an + exception if whitespace is encountered +* @return decoded base64 output +*/ +secure_vector BOTAN_PUBLIC_API(2,0) base64_decode(const char input[], + size_t input_length, + bool ignore_ws = true); + +/** +* Perform base64 decoding +* @param input some base64 input +* @param ignore_ws ignore whitespace on input; if false, throw an + exception if whitespace is encountered +* @return decoded base64 output +*/ +secure_vector BOTAN_PUBLIC_API(2,0) base64_decode(const std::string& input, + bool ignore_ws = true); + +/** +* Calculate the size of output buffer for base64_encode +* @param input_length the length of input in bytes +* @return the size of output buffer in bytes +*/ +size_t BOTAN_PUBLIC_API(2,1) base64_encode_max_output(size_t input_length); + +/** +* Calculate the size of output buffer for base64_decode +* @param input_length the length of input in bytes +* @return the size of output buffer in bytes +*/ +size_t BOTAN_PUBLIC_API(2,1) base64_decode_max_output(size_t input_length); + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/codec/base64/info.txt b/src/libs/3rdparty/botan/src/lib/codec/base64/info.txt new file mode 100644 index 0000000000..ceed636053 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/codec/base64/info.txt @@ -0,0 +1,3 @@ + +BASE64_CODEC -> 20131128 + diff --git a/src/libs/3rdparty/botan/src/lib/codec/hex/hex.cpp b/src/libs/3rdparty/botan/src/lib/codec/hex/hex.cpp new file mode 100644 index 0000000000..6bbd7c28e2 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/codec/hex/hex.cpp @@ -0,0 +1,207 @@ +/* +* Hex Encoding and Decoding +* (C) 2010 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include + +namespace Botan { + +void hex_encode(char output[], + const uint8_t input[], + size_t input_length, + bool uppercase) + { + static const uint8_t BIN_TO_HEX_UPPER[16] = { + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + 'A', 'B', 'C', 'D', 'E', 'F' }; + + static const uint8_t BIN_TO_HEX_LOWER[16] = { + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + 'a', 'b', 'c', 'd', 'e', 'f' }; + + const uint8_t* tbl = uppercase ? BIN_TO_HEX_UPPER : BIN_TO_HEX_LOWER; + + for(size_t i = 0; i != input_length; ++i) + { + uint8_t x = input[i]; + output[2*i ] = tbl[(x >> 4) & 0x0F]; + output[2*i+1] = tbl[(x ) & 0x0F]; + } + } + +std::string hex_encode(const uint8_t input[], + size_t input_length, + bool uppercase) + { + std::string output(2 * input_length, 0); + + if(input_length) + hex_encode(&output.front(), input, input_length, uppercase); + + return output; + } + +size_t hex_decode(uint8_t output[], + const char input[], + size_t input_length, + size_t& input_consumed, + bool ignore_ws) + { + /* + * Mapping of hex characters to either their binary equivalent + * or to an error code. + * If valid hex (0-9 A-F a-f), the value. + * If whitespace, then 0x80 + * Otherwise 0xFF + * Warning: this table assumes ASCII character encodings + */ + + static const uint8_t HEX_TO_BIN[256] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, + 0x80, 0xFF, 0xFF, 0xFF, 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, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, + 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, + 0x0F, 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, 0x0A, 0x0B, 0x0C, + 0x0D, 0x0E, 0x0F, 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, 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; + bool top_nibble = true; + + clear_mem(output, input_length / 2); + + for(size_t i = 0; i != input_length; ++i) + { + const uint8_t bin = HEX_TO_BIN[static_cast(input[i])]; + + if(bin >= 0x10) + { + if(bin == 0x80 && ignore_ws) + continue; + + std::string bad_char(1, input[i]); + if(bad_char == "\t") + bad_char = "\\t"; + else if(bad_char == "\n") + bad_char = "\\n"; + + throw Invalid_Argument( + std::string("hex_decode: invalid hex character '") + + bad_char + "'"); + } + + if(top_nibble) + *out_ptr |= bin << 4; + else + *out_ptr |= bin; + + top_nibble = !top_nibble; + if(top_nibble) + ++out_ptr; + } + + input_consumed = input_length; + size_t written = (out_ptr - output); + + /* + * We only got half of a uint8_t at the end; zap the half-written + * output and mark it as unread + */ + if(!top_nibble) + { + *out_ptr = 0; + input_consumed -= 1; + } + + return written; + } + +size_t hex_decode(uint8_t output[], + const char input[], + size_t input_length, + bool ignore_ws) + { + size_t consumed = 0; + size_t written = hex_decode(output, input, input_length, + consumed, ignore_ws); + + if(consumed != input_length) + throw Invalid_Argument("hex_decode: input did not have full bytes"); + + return written; + } + +size_t hex_decode(uint8_t output[], + const std::string& input, + bool ignore_ws) + { + return hex_decode(output, input.data(), input.length(), ignore_ws); + } + +secure_vector hex_decode_locked(const char input[], + size_t input_length, + bool ignore_ws) + { + secure_vector bin(1 + input_length / 2); + + size_t written = hex_decode(bin.data(), + input, + input_length, + ignore_ws); + + bin.resize(written); + return bin; + } + +secure_vector hex_decode_locked(const std::string& input, + bool ignore_ws) + { + return hex_decode_locked(input.data(), input.size(), ignore_ws); + } + +std::vector hex_decode(const char input[], + size_t input_length, + bool ignore_ws) + { + std::vector bin(1 + input_length / 2); + + size_t written = hex_decode(bin.data(), + input, + input_length, + ignore_ws); + + bin.resize(written); + return bin; + } + +std::vector hex_decode(const std::string& input, + bool ignore_ws) + { + return hex_decode(input.data(), input.size(), ignore_ws); + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/codec/hex/hex.h b/src/libs/3rdparty/botan/src/lib/codec/hex/hex.h new file mode 100644 index 0000000000..330d8a69a5 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/codec/hex/hex.h @@ -0,0 +1,148 @@ +/* +* Hex Encoding and Decoding +* (C) 2010 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_HEX_CODEC_H_ +#define BOTAN_HEX_CODEC_H_ + +#include +#include + +namespace Botan { + +/** +* Perform hex encoding +* @param output an array of at least input_length*2 bytes +* @param input is some binary data +* @param input_length length of input in bytes +* @param uppercase should output be upper or lower case? +*/ +void BOTAN_PUBLIC_API(2,0) hex_encode(char output[], + const uint8_t input[], + size_t input_length, + bool uppercase = true); + +/** +* Perform hex encoding +* @param input some input +* @param input_length length of input in bytes +* @param uppercase should output be upper or lower case? +* @return hexadecimal representation of input +*/ +std::string BOTAN_PUBLIC_API(2,0) hex_encode(const uint8_t input[], + size_t input_length, + bool uppercase = true); + +/** +* Perform hex encoding +* @param input some input +* @param uppercase should output be upper or lower case? +* @return hexadecimal representation of input +*/ +template +std::string hex_encode(const std::vector& input, + bool uppercase = true) + { + return hex_encode(input.data(), input.size(), uppercase); + } + +/** +* Perform hex decoding +* @param output an array of at least input_length/2 bytes +* @param input some hex input +* @param input_length length of input in bytes +* @param input_consumed is an output parameter which says how many +* bytes of input were actually consumed. If less than +* input_length, then the range input[consumed:length] +* should be passed in later along with more input. +* @param ignore_ws ignore whitespace on input; if false, throw an + exception if whitespace is encountered +* @return number of bytes written to output +*/ +size_t BOTAN_PUBLIC_API(2,0) hex_decode(uint8_t output[], + const char input[], + size_t input_length, + size_t& input_consumed, + bool ignore_ws = true); + +/** +* Perform hex decoding +* @param output an array of at least input_length/2 bytes +* @param input some hex input +* @param input_length length of input in bytes +* @param ignore_ws ignore whitespace on input; if false, throw an + exception if whitespace is encountered +* @return number of bytes written to output +*/ +size_t BOTAN_PUBLIC_API(2,0) hex_decode(uint8_t output[], + const char input[], + size_t input_length, + bool ignore_ws = true); + +/** +* Perform hex decoding +* @param output an array of at least input_length/2 bytes +* @param input some hex input +* @param ignore_ws ignore whitespace on input; if false, throw an + exception if whitespace is encountered +* @return number of bytes written to output +*/ +size_t BOTAN_PUBLIC_API(2,0) hex_decode(uint8_t output[], + const std::string& input, + bool ignore_ws = true); + +/** +* Perform hex decoding +* @param input some hex input +* @param input_length the length of input in bytes +* @param ignore_ws ignore whitespace on input; if false, throw an + exception if whitespace is encountered +* @return decoded hex output +*/ +std::vector BOTAN_PUBLIC_API(2,0) +hex_decode(const char input[], + size_t input_length, + bool ignore_ws = true); + +/** +* Perform hex decoding +* @param input some hex input +* @param ignore_ws ignore whitespace on input; if false, throw an + exception if whitespace is encountered +* @return decoded hex output +*/ +std::vector BOTAN_PUBLIC_API(2,0) +hex_decode(const std::string& input, + bool ignore_ws = true); + + +/** +* Perform hex decoding +* @param input some hex input +* @param input_length the length of input in bytes +* @param ignore_ws ignore whitespace on input; if false, throw an + exception if whitespace is encountered +* @return decoded hex output +*/ +secure_vector BOTAN_PUBLIC_API(2,0) +hex_decode_locked(const char input[], + size_t input_length, + bool ignore_ws = true); + +/** +* Perform hex decoding +* @param input some hex input +* @param ignore_ws ignore whitespace on input; if false, throw an + exception if whitespace is encountered +* @return decoded hex output +*/ +secure_vector BOTAN_PUBLIC_API(2,0) +hex_decode_locked(const std::string& input, + bool ignore_ws = true); + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/codec/hex/info.txt b/src/libs/3rdparty/botan/src/lib/codec/hex/info.txt new file mode 100644 index 0000000000..6ee27e57c2 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/codec/hex/info.txt @@ -0,0 +1,3 @@ + +HEX_CODEC -> 20131128 + 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 new file mode 100644 index 0000000000..1e36136155 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/entropy/darwin_secrandom/darwin_secrandom.cpp @@ -0,0 +1,30 @@ +/* +* Darwin SecRandomCopyBytes EntropySource +* (C) 2015 Daniel Seither (Kullo GmbH) +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include + +namespace Botan { + +/** +* Gather entropy from SecRandomCopyBytes +*/ +size_t Darwin_SecRandom::poll(RandomNumberGenerator& rng) + { + secure_vector 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 new file mode 100644 index 0000000000..83b4da4f50 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/entropy/darwin_secrandom/darwin_secrandom.h @@ -0,0 +1,28 @@ +/* +* 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 + +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 new file mode 100644 index 0000000000..c1943a04a4 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/entropy/darwin_secrandom/info.txt @@ -0,0 +1,16 @@ + +ENTROPY_SRC_DARWIN_SECRANDOM -> 20150925 + + + +darwin_secrandom.h + + + +security_framework + + + +darwin -> Security +ios -> Security + diff --git a/src/libs/3rdparty/botan/src/lib/entropy/dev_random/dev_random.cpp b/src/libs/3rdparty/botan/src/lib/entropy/dev_random/dev_random.cpp new file mode 100644 index 0000000000..56552228a3 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/entropy/dev_random/dev_random.cpp @@ -0,0 +1,123 @@ +/* +* Reader of /dev/random and company +* (C) 1999-2009,2013 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace Botan { + +/** +Device_EntropySource constructor +Open a file descriptor to each (available) device in fsnames +*/ +Device_EntropySource::Device_EntropySource(const std::vector& fsnames) + { +#ifndef O_NONBLOCK + #define O_NONBLOCK 0 +#endif + +#ifndef O_NOCTTY + #define O_NOCTTY 0 +#endif + + const int flags = O_RDONLY | O_NONBLOCK | O_NOCTTY; + + m_max_fd = 0; + + for(auto fsname : fsnames) + { + int fd = ::open(fsname.c_str(), flags); + + if(fd < 0) + { + /* + ENOENT or EACCES is normal as some of the named devices may not exist + on this system. But any other errno value probably indicates + either a bug in the application or file descriptor exhaustion. + */ + if(errno != ENOENT && errno != EACCES) + throw Exception("Opening OS RNG device failed with errno " + + std::to_string(errno)); + } + else + { + if(fd > FD_SETSIZE) + { + ::close(fd); + throw Exception("Open of OS RNG succeeded but fd is too large for fd_set"); + } + + m_dev_fds.push_back(fd); + m_max_fd = std::max(m_max_fd, fd); + } + } + } + +/** +Device_EntropySource destructor: close all open devices +*/ +Device_EntropySource::~Device_EntropySource() + { + for(int fd : m_dev_fds) + { + // ignoring return value here, can't throw in destructor anyway + ::close(fd); + } + } + +/** +* Gather entropy from a RNG device +*/ +size_t Device_EntropySource::poll(RandomNumberGenerator& rng) + { + size_t bits = 0; + + if(m_dev_fds.size() > 0) + { + fd_set read_set; + FD_ZERO(&read_set); + + for(int dev_fd : m_dev_fds) + { + FD_SET(dev_fd, &read_set); + } + + secure_vector io_buf(BOTAN_SYSTEM_RNG_POLL_REQUEST); + + struct ::timeval timeout; + timeout.tv_sec = (BOTAN_SYSTEM_RNG_POLL_TIMEOUT_MS / 1000); + timeout.tv_usec = (BOTAN_SYSTEM_RNG_POLL_TIMEOUT_MS % 1000) * 1000; + + if(::select(m_max_fd + 1, &read_set, nullptr, nullptr, &timeout) > 0) + { + for(int dev_fd : m_dev_fds) + { + if(FD_ISSET(dev_fd, &read_set)) + { + const ssize_t got = ::read(dev_fd, io_buf.data(), io_buf.size()); + + if(got > 0) + { + rng.add_entropy(io_buf.data(), static_cast(got)); + bits += got * 8; + } + } + } + } + } + + return bits; + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/entropy/dev_random/dev_random.h b/src/libs/3rdparty/botan/src/lib/entropy/dev_random/dev_random.h new file mode 100644 index 0000000000..6195f85648 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/entropy/dev_random/dev_random.h @@ -0,0 +1,37 @@ +/* +* /dev/random EntropySource +* (C) 1999-2009 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_ENTROPY_SRC_DEVICE_H_ +#define BOTAN_ENTROPY_SRC_DEVICE_H_ + +#include +#include +#include + +namespace Botan { + +/** +* Entropy source reading from kernel devices like /dev/random +*/ +class Device_EntropySource final : public Entropy_Source + { + public: + std::string name() const override { return "dev_random"; } + + size_t poll(RandomNumberGenerator& rng) override; + + explicit Device_EntropySource(const std::vector& fsnames); + + ~Device_EntropySource(); + private: + std::vector m_dev_fds; + int m_max_fd; + }; + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/entropy/dev_random/info.txt b/src/libs/3rdparty/botan/src/lib/entropy/dev_random/info.txt new file mode 100644 index 0000000000..3872411f30 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/entropy/dev_random/info.txt @@ -0,0 +1,11 @@ + +ENTROPY_SRC_DEV_RANDOM -> 20131128 + + + +dev_random.h + + + +dev_random,posix1 + diff --git a/src/libs/3rdparty/botan/src/lib/entropy/entropy_src.h b/src/libs/3rdparty/botan/src/lib/entropy/entropy_src.h new file mode 100644 index 0000000000..56e5bd53e5 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/entropy/entropy_src.h @@ -0,0 +1,87 @@ +/* +* EntropySource +* (C) 2008,2009,2014,2015,2016 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_ENTROPY_H_ +#define BOTAN_ENTROPY_H_ + +#include +#include +#include +#include +#include +#include + +namespace Botan { + +class RandomNumberGenerator; + +/** +* Abstract interface to a source of entropy +*/ +class BOTAN_PUBLIC_API(2,0) Entropy_Source + { + public: + /** + * Return a new entropy source of a particular type, or null + * Each entropy source may require substantial resources (eg, a file handle + * or socket instance), so try to share them among multiple RNGs, or just + * use the preconfigured global list accessed by Entropy_Sources::global_sources() + */ + static std::unique_ptr create(const std::string& type); + + /** + * @return name identifying this entropy source + */ + virtual std::string name() const = 0; + + /** + * Perform an entropy gathering poll + * @param rng will be provided with entropy via calls to add_entropy + * @return conservative estimate of actual entropy added to rng during poll + */ + virtual size_t poll(RandomNumberGenerator& rng) = 0; + + Entropy_Source() = default; + Entropy_Source(const Entropy_Source& other) = delete; + Entropy_Source(Entropy_Source&& other) = delete; + Entropy_Source& operator=(const Entropy_Source& other) = delete; + + virtual ~Entropy_Source() = default; + }; + +class BOTAN_PUBLIC_API(2,0) Entropy_Sources final + { + public: + static Entropy_Sources& global_sources(); + + void add_source(std::unique_ptr src); + + std::vector enabled_sources() const; + + size_t poll(RandomNumberGenerator& rng, + size_t bits, + std::chrono::milliseconds timeout); + + /** + * Poll just a single named source. Ordinally only used for testing + */ + size_t poll_just(RandomNumberGenerator& rng, const std::string& src); + + Entropy_Sources() = default; + explicit Entropy_Sources(const std::vector& sources); + + Entropy_Sources(const Entropy_Sources& other) = delete; + Entropy_Sources(Entropy_Sources&& other) = delete; + Entropy_Sources& operator=(const Entropy_Sources& other) = delete; + + private: + std::vector> m_srcs; + }; + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/entropy/entropy_srcs.cpp b/src/libs/3rdparty/botan/src/lib/entropy/entropy_srcs.cpp new file mode 100644 index 0000000000..c04b3b5b26 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/entropy/entropy_srcs.cpp @@ -0,0 +1,198 @@ +/* +* Entropy Source Polling +* (C) 2008-2010,2015 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include + +#if defined(BOTAN_HAS_SYSTEM_RNG) + #include +#endif + +#if defined(BOTAN_HAS_ENTROPY_SRC_RDRAND) + #include +#endif + +#if defined(BOTAN_HAS_ENTROPY_SRC_RDSEED) + #include +#endif + +#if defined(BOTAN_HAS_ENTROPY_SRC_DEV_RANDOM) + #include +#endif + +#if defined(BOTAN_HAS_ENTROPY_SRC_WIN32) + #include +#endif + +#if defined(BOTAN_HAS_ENTROPY_SRC_PROC_WALKER) + #include +#endif + +#if defined(BOTAN_HAS_ENTROPY_SRC_DARWIN_SECRANDOM) + #include +#endif + +#if defined(BOTAN_HAS_ENTROPY_SRC_GETENTROPY) + #include +#endif + +namespace Botan { + +#if defined(BOTAN_HAS_SYSTEM_RNG) + +namespace { + +class System_RNG_EntropySource final : public Entropy_Source + { + public: + size_t poll(RandomNumberGenerator& rng) override + { + const size_t poll_bits = BOTAN_RNG_RESEED_POLL_BITS; + rng.reseed_from_rng(system_rng(), poll_bits); + return poll_bits; + } + + std::string name() const override { return "system_rng"; } + }; + +} + +#endif + +std::unique_ptr Entropy_Source::create(const std::string& name) + { +#if defined(BOTAN_HAS_SYSTEM_RNG) + if(name == "system_rng" || name == "win32_cryptoapi") + { + return std::unique_ptr(new System_RNG_EntropySource); + } +#endif + +#if defined(BOTAN_HAS_ENTROPY_SRC_RDRAND) + if(name == "rdrand") + { + return std::unique_ptr(new Intel_Rdrand); + } +#endif + +#if defined(BOTAN_HAS_ENTROPY_SRC_RDSEED) + if(name == "rdseed") + { + return std::unique_ptr(new Intel_Rdseed); + } +#endif + +#if defined(BOTAN_HAS_ENTROPY_SRC_DARWIN_SECRANDOM) + if(name == "darwin_secrandom") + { + return std::unique_ptr(new Darwin_SecRandom); + } +#endif + +#if defined(BOTAN_HAS_ENTROPY_SRC_GETENTROPY) + if(name == "getentropy") + { + return std::unique_ptr(new Getentropy); + } +#endif + +#if defined(BOTAN_HAS_ENTROPY_SRC_DEV_RANDOM) + if(name == "dev_random") + { + return std::unique_ptr(new Device_EntropySource(BOTAN_SYSTEM_RNG_POLL_DEVICES)); + } +#endif + +#if defined(BOTAN_HAS_ENTROPY_SRC_PROC_WALKER) + if(name == "proc_walk") + { + const std::string root_dir = BOTAN_ENTROPY_PROC_FS_PATH; + if(!root_dir.empty()) + return std::unique_ptr(new ProcWalking_EntropySource(root_dir)); + } +#endif + +#if defined(BOTAN_HAS_ENTROPY_SRC_WIN32) + if(name == "system_stats") + { + return std::unique_ptr(new Win32_EntropySource); + } +#endif + + BOTAN_UNUSED(name); + return std::unique_ptr(); + } + +void Entropy_Sources::add_source(std::unique_ptr src) + { + if(src.get()) + { + m_srcs.push_back(std::move(src)); + } + } + +std::vector Entropy_Sources::enabled_sources() const + { + std::vector sources; + for(size_t i = 0; i != m_srcs.size(); ++i) + { + sources.push_back(m_srcs[i]->name()); + } + return sources; + } + +size_t Entropy_Sources::poll(RandomNumberGenerator& rng, + size_t poll_bits, + std::chrono::milliseconds timeout) + { + typedef std::chrono::system_clock clock; + + auto deadline = clock::now() + timeout; + + size_t bits_collected = 0; + + for(size_t i = 0; i != m_srcs.size(); ++i) + { + bits_collected += m_srcs[i]->poll(rng); + + if (bits_collected >= poll_bits || clock::now() > deadline) + break; + } + + return bits_collected; + } + +size_t Entropy_Sources::poll_just(RandomNumberGenerator& rng, const std::string& the_src) + { + for(size_t i = 0; i != m_srcs.size(); ++i) + { + if(m_srcs[i]->name() == the_src) + { + return m_srcs[i]->poll(rng); + } + } + + return 0; + } + +Entropy_Sources::Entropy_Sources(const std::vector& sources) + { + for(auto&& src_name : sources) + { + add_source(Entropy_Source::create(src_name)); + } + } + +Entropy_Sources& Entropy_Sources::global_sources() + { + static Entropy_Sources global_entropy_sources(BOTAN_ENTROPY_DEFAULT_SOURCES); + + return global_entropy_sources; + } + +} + diff --git a/src/libs/3rdparty/botan/src/lib/entropy/getentropy/getentropy.cpp b/src/libs/3rdparty/botan/src/lib/entropy/getentropy/getentropy.cpp new file mode 100644 index 0000000000..15bd8abe87 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/entropy/getentropy/getentropy.cpp @@ -0,0 +1,35 @@ +/* +* System Call getentropy(2) +* (C) 2017 Alexander Bluhm (genua GmbH) +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include + +#if defined(BOTAN_TARGET_OS_IS_DARWIN) + #include +#else + #include +#endif + +namespace Botan { + +/** +* Gather 256 bytes entropy from getentropy(2). Note that maximum +* buffer size is limited to 256 bytes. On OpenBSD this does neither +* block nor fail. +*/ +size_t Getentropy::poll(RandomNumberGenerator& rng) + { + secure_vector buf(256); + + if(::getentropy(buf.data(), buf.size()) == 0) + { + rng.add_entropy(buf.data(), buf.size()); + return buf.size() * 8; + } + + return 0; + } +} diff --git a/src/libs/3rdparty/botan/src/lib/entropy/getentropy/getentropy.h b/src/libs/3rdparty/botan/src/lib/entropy/getentropy/getentropy.h new file mode 100644 index 0000000000..26783cf78a --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/entropy/getentropy/getentropy.h @@ -0,0 +1,28 @@ +/* +* Entropy Source Using OpenBSD getentropy(2) system call +* (C) 2017 Alexander Bluhm (genua GmbH) +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_ENTROPY_SRC_GETENTROPY_H_ +#define BOTAN_ENTROPY_SRC_GETENTROPY_H_ + +#include + +namespace Botan { + +/** +* Entropy source using the getentropy(2) system call first introduced in +* OpenBSD 5.6 and added to Solaris 11.3. +*/ +class Getentropy final : public Entropy_Source + { + public: + std::string name() const override { return "getentropy"; } + size_t poll(RandomNumberGenerator& rng) override; + }; + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/entropy/getentropy/info.txt b/src/libs/3rdparty/botan/src/lib/entropy/getentropy/info.txt new file mode 100644 index 0000000000..886e57151f --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/entropy/getentropy/info.txt @@ -0,0 +1,11 @@ + +ENTROPY_SRC_GETENTROPY -> 20170327 + + + +getentropy.h + + + +getentropy + diff --git a/src/libs/3rdparty/botan/src/lib/entropy/info.txt b/src/libs/3rdparty/botan/src/lib/entropy/info.txt new file mode 100644 index 0000000000..57f1930b99 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/entropy/info.txt @@ -0,0 +1,7 @@ + +ENTROPY_SOURCE -> 20151120 + + + +rng + diff --git a/src/libs/3rdparty/botan/src/lib/entropy/proc_walk/info.txt b/src/libs/3rdparty/botan/src/lib/entropy/proc_walk/info.txt new file mode 100644 index 0000000000..2bba7e276b --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/entropy/proc_walk/info.txt @@ -0,0 +1,11 @@ + +ENTROPY_SRC_PROC_WALKER -> 20131128 + + + +proc_walk.h + + + +posix1,proc_fs + diff --git a/src/libs/3rdparty/botan/src/lib/entropy/proc_walk/proc_walk.cpp b/src/libs/3rdparty/botan/src/lib/entropy/proc_walk/proc_walk.cpp new file mode 100644 index 0000000000..d780cbf739 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/entropy/proc_walk/proc_walk.cpp @@ -0,0 +1,154 @@ +/* +* Entropy source based on reading files in /proc on the assumption +* that a remote attacker will have difficulty guessing some of them. +* +* (C) 1999-2008,2012 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include + +#ifndef _POSIX_C_SOURCE + #define _POSIX_C_SOURCE 199309 +#endif + +#include +#include +#include +#include +#include + +namespace Botan { + +namespace { + +class Directory_Walker final : public File_Descriptor_Source + { + public: + explicit Directory_Walker(const std::string& root) : + m_cur_dir(std::make_pair(nullptr, "")) + { + if(DIR* root_dir = ::opendir(root.c_str())) + m_cur_dir = std::make_pair(root_dir, root); + } + + ~Directory_Walker() + { + if(m_cur_dir.first) + ::closedir(m_cur_dir.first); + } + + int next_fd() override; + private: + std::pair get_next_dirent(); + + std::pair m_cur_dir; + std::deque m_dirlist; + }; + +std::pair Directory_Walker::get_next_dirent() + { + while(m_cur_dir.first) + { + if(struct dirent* dir = ::readdir(m_cur_dir.first)) + return std::make_pair(dir, m_cur_dir.second); + + ::closedir(m_cur_dir.first); + m_cur_dir = std::make_pair(nullptr, ""); + + while(!m_dirlist.empty() && !m_cur_dir.first) + { + const std::string next_dir_name = m_dirlist[0]; + m_dirlist.pop_front(); + + if(DIR* next_dir = ::opendir(next_dir_name.c_str())) + m_cur_dir = std::make_pair(next_dir, next_dir_name); + } + } + + return std::make_pair(nullptr, ""); // nothing left + } + +int Directory_Walker::next_fd() + { + while(true) + { + std::pair entry = get_next_dirent(); + + if(!entry.first) + break; // no more dirs + + const std::string filename = entry.first->d_name; + + if(filename == "." || filename == "..") + continue; + + const std::string full_path = entry.second + "/" + filename; + + struct stat stat_buf; + if(::lstat(full_path.c_str(), &stat_buf) == -1) + continue; + + if(S_ISDIR(stat_buf.st_mode)) + { + m_dirlist.push_back(full_path); + } + else if(S_ISREG(stat_buf.st_mode) && (stat_buf.st_mode & S_IROTH)) + { + int fd = ::open(full_path.c_str(), O_RDONLY | O_NOCTTY); + + if(fd >= 0) + return fd; + } + } + + return -1; + } + +} + +size_t ProcWalking_EntropySource::poll(RandomNumberGenerator& rng) + { + const size_t MAX_FILES_READ_PER_POLL = 2048; + + lock_guard_type lock(m_mutex); + + if(!m_dir) + m_dir.reset(new Directory_Walker(m_path)); + + m_buf.resize(4096); + + size_t bits = 0; + + for(size_t i = 0; i != MAX_FILES_READ_PER_POLL; ++i) + { + int fd = m_dir->next_fd(); + + // If we've exhaused this walk of the directory, halt the poll + if(fd == -1) + { + m_dir.reset(); + break; + } + + ssize_t got = ::read(fd, m_buf.data(), m_buf.size()); + ::close(fd); + + if(got > 0) + { + rng.add_entropy(m_buf.data(), static_cast(got)); + + // Conservative estimate of 4 bits per file + bits += 4; + } + + if(bits > 128) + break; + } + + return bits; + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/entropy/proc_walk/proc_walk.h b/src/libs/3rdparty/botan/src/lib/entropy/proc_walk/proc_walk.h new file mode 100644 index 0000000000..4c5013d29c --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/entropy/proc_walk/proc_walk.h @@ -0,0 +1,45 @@ +/* +* File Tree Walking EntropySource +* (C) 1999-2008 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_ENTROPY_SRC_PROC_WALK_H_ +#define BOTAN_ENTROPY_SRC_PROC_WALK_H_ + +#include +#include + +namespace Botan { + +class File_Descriptor_Source + { + public: + virtual int next_fd() = 0; + virtual ~File_Descriptor_Source() = default; + }; + +/** +* File Tree Walking Entropy Source +*/ +class ProcWalking_EntropySource final : public Entropy_Source + { + public: + std::string name() const override { return "proc_walk"; } + + size_t poll(RandomNumberGenerator& rng) override; + + explicit ProcWalking_EntropySource(const std::string& root_dir) : + m_path(root_dir), m_dir(nullptr) {} + + private: + const std::string m_path; + mutex_type m_mutex; + std::unique_ptr m_dir; + secure_vector m_buf; + }; + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/entropy/rdrand/info.txt b/src/libs/3rdparty/botan/src/lib/entropy/rdrand/info.txt new file mode 100644 index 0000000000..6abe8765d3 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/entropy/rdrand/info.txt @@ -0,0 +1,11 @@ + +ENTROPY_SRC_RDRAND -> 20131128 + + + +rdrand_rng + + + +rdrand.h + diff --git a/src/libs/3rdparty/botan/src/lib/entropy/rdrand/rdrand.cpp b/src/libs/3rdparty/botan/src/lib/entropy/rdrand/rdrand.cpp new file mode 100644 index 0000000000..6a5b0f7c44 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/entropy/rdrand/rdrand.cpp @@ -0,0 +1,29 @@ +/* +* Entropy Source Using Intel's rdrand instruction +* (C) 2012,2015 Jack Lloyd +* (C) 2015 Daniel Neus +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include + +namespace Botan { + +size_t Intel_Rdrand::poll(RandomNumberGenerator& rng) { + if(CPUID::has_rdrand() && BOTAN_ENTROPY_INTEL_RNG_POLLS > 0) + { + RDRAND_RNG rdrand_rng; + secure_vector buf(4 * BOTAN_ENTROPY_INTEL_RNG_POLLS); + + rdrand_rng.randomize(buf.data(), buf.size()); + rng.add_entropy(buf.data(), buf.size()); + } + + // RDRAND is used but not trusted + return 0; + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/entropy/rdrand/rdrand.h b/src/libs/3rdparty/botan/src/lib/entropy/rdrand/rdrand.h new file mode 100644 index 0000000000..6544fe57f9 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/entropy/rdrand/rdrand.h @@ -0,0 +1,28 @@ +/* +* Entropy Source Using Intel's rdrand instruction +* (C) 2012 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_ENTROPY_SRC_RDRAND_H_ +#define BOTAN_ENTROPY_SRC_RDRAND_H_ + +#include + +namespace Botan { + +/** +* Entropy source using the rdrand instruction first introduced on +* Intel's Ivy Bridge architecture. +*/ +class Intel_Rdrand final : public Entropy_Source + { + public: + std::string name() const override { return "rdrand"; } + size_t poll(RandomNumberGenerator& rng) override; + }; + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/entropy/rdseed/info.txt b/src/libs/3rdparty/botan/src/lib/entropy/rdseed/info.txt new file mode 100644 index 0000000000..d4432e6c7f --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/entropy/rdseed/info.txt @@ -0,0 +1,16 @@ + +ENTROPY_SRC_RDSEED -> 20151218 + + +need_isa rdseed + + +rdseed.h + + + +gcc +clang +icc +msvc + diff --git a/src/libs/3rdparty/botan/src/lib/entropy/rdseed/rdseed.cpp b/src/libs/3rdparty/botan/src/lib/entropy/rdseed/rdseed.cpp new file mode 100644 index 0000000000..fbb8f921e7 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/entropy/rdseed/rdseed.cpp @@ -0,0 +1,48 @@ +/* +* Entropy Source Using Intel's rdseed instruction +* (C) 2015 Jack Lloyd, Daniel Neus +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include + +#if !defined(BOTAN_USE_GCC_INLINE_ASM) + #include +#endif + +namespace Botan { + +BOTAN_FUNC_ISA("rdseed") +size_t Intel_Rdseed::poll(RandomNumberGenerator& rng) { + if(CPUID::has_rdseed()) + { + for(size_t p = 0; p != BOTAN_ENTROPY_INTEL_RNG_POLLS; ++p) + { + for(size_t i = 0; i != BOTAN_ENTROPY_RDSEED_RETRIES; ++i) + { + uint32_t r = 0; + +#if defined(BOTAN_USE_GCC_INLINE_ASM) + int cf = 0; + + // Encoding of rdseed %eax + asm(".byte 0x0F, 0xC7, 0xF8; adcl $0,%1" : + "=a" (r), "=r" (cf) : "0" (r), "1" (cf) : "cc"); +#else + int cf = _rdseed32_step(&r); +#endif + if(1 == cf) + { + rng.add_entropy_T(r); + break; + } + } + } + } + + return 0; + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/entropy/rdseed/rdseed.h b/src/libs/3rdparty/botan/src/lib/entropy/rdseed/rdseed.h new file mode 100644 index 0000000000..da94bc0a10 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/entropy/rdseed/rdseed.h @@ -0,0 +1,28 @@ +/* +* Entropy Source Using Intel's rdseed instruction +* (C) 2015 Jack Lloyd, Daniel Neus +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_ENTROPY_SRC_RDSEED_H_ +#define BOTAN_ENTROPY_SRC_RDSEED_H_ + +#include + +namespace Botan { + +/** +* Entropy source using the rdseed instruction first introduced on +* Intel's Broadwell architecture. +*/ +class Intel_Rdseed final : public Entropy_Source + { + public: + std::string name() const override { return "rdseed"; } + size_t poll(RandomNumberGenerator& rng) override; + }; + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/entropy/win32_stats/es_win32.cpp b/src/libs/3rdparty/botan/src/lib/entropy/win32_stats/es_win32.cpp new file mode 100644 index 0000000000..86d1f2cafb --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/entropy/win32_stats/es_win32.cpp @@ -0,0 +1,121 @@ +/* +* Win32 EntropySource +* (C) 1999-2009,2016 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include + +#define NOMINMAX 1 +#define _WINSOCKAPI_ // stop windows.h including winsock.h +#include +#include + +namespace Botan { + +/** +* Win32 poll using stats functions including Tooltip32 +*/ +size_t Win32_EntropySource::poll(RandomNumberGenerator& rng) + { + const size_t POLL_TARGET = 128; + const size_t EST_ENTROPY_HEAP_INFO = 4; + const size_t EST_ENTROPY_THREAD_INFO = 2; + + /* + First query a bunch of basic statistical stuff + */ + rng.add_entropy_T(::GetTickCount()); + rng.add_entropy_T(::GetMessagePos()); + rng.add_entropy_T(::GetMessageTime()); + rng.add_entropy_T(::GetInputState()); + + rng.add_entropy_T(::GetCurrentProcessId()); + rng.add_entropy_T(::GetCurrentThreadId()); + + SYSTEM_INFO sys_info; + ::GetSystemInfo(&sys_info); + rng.add_entropy_T(sys_info); + + MEMORYSTATUSEX mem_info; + ::GlobalMemoryStatusEx(&mem_info); + rng.add_entropy_T(mem_info); + + POINT point; + ::GetCursorPos(&point); + rng.add_entropy_T(point); + + ::GetCaretPos(&point); + rng.add_entropy_T(point); + + /* + Now use the Tooltip library to iterate through various objects on + the system, including processes, threads, and heap objects. + */ + + HANDLE snapshot = ::CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0); + size_t collected = 0; + +#define TOOLHELP32_ITER(DATA_TYPE, FUNC_FIRST, FUNC_NEXT) \ + if(collected < POLL_TARGET) \ + { \ + DATA_TYPE info; \ + info.dwSize = sizeof(DATA_TYPE); \ + if(FUNC_FIRST(snapshot, &info)) \ + { \ + do \ + { \ + rng.add_entropy_T(info); \ + collected += EST_ENTROPY_THREAD_INFO; \ + if(collected >= POLL_TARGET) \ + break; \ + } while(FUNC_NEXT(snapshot, &info)); \ + } \ + } + + TOOLHELP32_ITER(MODULEENTRY32, ::Module32First, ::Module32Next); + TOOLHELP32_ITER(PROCESSENTRY32, ::Process32First, ::Process32Next); + TOOLHELP32_ITER(THREADENTRY32, ::Thread32First, ::Thread32Next); + +#undef TOOLHELP32_ITER + + if(collected < POLL_TARGET) + { + HEAPLIST32 heap_list; + heap_list.dwSize = sizeof(HEAPLIST32); + + if(::Heap32ListFirst(snapshot, &heap_list)) + { + do + { + rng.add_entropy_T(heap_list); + + HEAPENTRY32 heap_entry; + heap_entry.dwSize = sizeof(HEAPENTRY32); + if(::Heap32First(&heap_entry, + heap_list.th32ProcessID, + heap_list.th32HeapID)) + { + do + { + rng.add_entropy_T(heap_entry); + collected += EST_ENTROPY_HEAP_INFO; + if(collected >= POLL_TARGET) + break; + } while(::Heap32Next(&heap_entry)); + } + + if(collected >= POLL_TARGET) + break; + + } while(::Heap32ListNext(snapshot, &heap_list)); + } + } + + ::CloseHandle(snapshot); + + return collected; + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/entropy/win32_stats/es_win32.h b/src/libs/3rdparty/botan/src/lib/entropy/win32_stats/es_win32.h new file mode 100644 index 0000000000..2b11ee0801 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/entropy/win32_stats/es_win32.h @@ -0,0 +1,27 @@ +/* +* Win32 EntropySource +* (C) 1999-2009 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_ENTROPY_SRC_WIN32_H_ +#define BOTAN_ENTROPY_SRC_WIN32_H_ + +#include + +namespace Botan { + +/** +* Win32 Entropy Source +*/ +class Win32_EntropySource final : public Entropy_Source + { + public: + std::string name() const override { return "system_stats"; } + size_t poll(RandomNumberGenerator& rng) override; + }; + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/entropy/win32_stats/info.txt b/src/libs/3rdparty/botan/src/lib/entropy/win32_stats/info.txt new file mode 100644 index 0000000000..3e3268183e --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/entropy/win32_stats/info.txt @@ -0,0 +1,19 @@ + +ENTROPY_SRC_WIN32 -> 20131128 + + + +This module can cause false positives with antivirus systems + + + +es_win32.h + + + +win32 + + + +windows -> user32.lib + diff --git a/src/libs/3rdparty/botan/src/lib/filters/aead_filt.h b/src/libs/3rdparty/botan/src/lib/filters/aead_filt.h new file mode 100644 index 0000000000..f569423a69 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/filters/aead_filt.h @@ -0,0 +1,40 @@ +/* +* Filter interface for AEAD Modes +* (C) 2013 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_AEAD_FILTER_H_ +#define BOTAN_AEAD_FILTER_H_ + +#include +#include + +namespace Botan { + +/** +* Filter interface for AEAD Modes +*/ +class AEAD_Filter final : public Cipher_Mode_Filter + { + public: + AEAD_Filter(AEAD_Mode* aead) : Cipher_Mode_Filter(aead) {} + + /** + * Set associated data that is not included in the ciphertext but + * that should be authenticated. Must be called after set_key + * and before end_msg. + * + * @param ad the associated data + * @param ad_len length of add in bytes + */ + void set_associated_data(const uint8_t ad[], size_t ad_len) + { + dynamic_cast(get_transform()).set_associated_data(ad, ad_len); + } + }; + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/filters/algo_filt.cpp b/src/libs/3rdparty/botan/src/lib/filters/algo_filt.cpp new file mode 100644 index 0000000000..c944b72e5b --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/filters/algo_filt.cpp @@ -0,0 +1,96 @@ +/* +* Filters +* (C) 1999-2007,2015 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include + +namespace Botan { + +#if defined(BOTAN_HAS_STREAM_CIPHER) + +StreamCipher_Filter::StreamCipher_Filter(StreamCipher* cipher) : + m_buffer(BOTAN_DEFAULT_BUFFER_SIZE), + m_cipher(cipher) + { + } + +StreamCipher_Filter::StreamCipher_Filter(StreamCipher* cipher, const SymmetricKey& key) : + StreamCipher_Filter(cipher) + { + m_cipher->set_key(key); + } + +StreamCipher_Filter::StreamCipher_Filter(const std::string& sc_name) : + m_buffer(BOTAN_DEFAULT_BUFFER_SIZE), + m_cipher(StreamCipher::create_or_throw(sc_name)) + { + } + +StreamCipher_Filter::StreamCipher_Filter(const std::string& sc_name, const SymmetricKey& key) : + StreamCipher_Filter(sc_name) + { + m_cipher->set_key(key); + } + +void StreamCipher_Filter::write(const uint8_t input[], size_t length) + { + while(length) + { + size_t copied = std::min(length, m_buffer.size()); + m_cipher->cipher(input, m_buffer.data(), copied); + send(m_buffer, copied); + input += copied; + length -= copied; + } + } + +#endif + +#if defined(BOTAN_HAS_HASH) + +Hash_Filter::Hash_Filter(const std::string& hash_name, size_t len) : + m_hash(HashFunction::create_or_throw(hash_name)), + m_out_len(len) + { + } + +void Hash_Filter::end_msg() + { + secure_vector output = m_hash->final(); + if(m_out_len) + send(output, std::min(m_out_len, output.size())); + else + send(output); + } +#endif + +#if defined(BOTAN_HAS_MAC) + +MAC_Filter::MAC_Filter(const std::string& mac_name, size_t len) : + m_mac(MessageAuthenticationCode::create_or_throw(mac_name)), + m_out_len(len) + { + } + +MAC_Filter::MAC_Filter(const std::string& mac_name, const SymmetricKey& key, size_t len) : + MAC_Filter(mac_name, len) + { + m_mac->set_key(key); + } + +void MAC_Filter::end_msg() + { + secure_vector output = m_mac->final(); + if(m_out_len) + send(output, std::min(m_out_len, output.size())); + else + send(output); + } + +#endif + +} diff --git a/src/libs/3rdparty/botan/src/lib/filters/basefilt.cpp b/src/libs/3rdparty/botan/src/lib/filters/basefilt.cpp new file mode 100644 index 0000000000..89026f6005 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/filters/basefilt.cpp @@ -0,0 +1,70 @@ +/* +* Basic Filters +* (C) 1999-2007 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include + +namespace Botan { + +void Keyed_Filter::set_iv(const InitializationVector& iv) + { + if(iv.length() != 0) + throw Invalid_IV_Length(name(), iv.length()); + } + +/* +* Chain Constructor +*/ +Chain::Chain(Filter* f1, Filter* f2, Filter* f3, Filter* f4) + { + if(f1) { attach(f1); incr_owns(); } + if(f2) { attach(f2); incr_owns(); } + if(f3) { attach(f3); incr_owns(); } + if(f4) { attach(f4); incr_owns(); } + } + +/* +* Chain Constructor +*/ +Chain::Chain(Filter* filters[], size_t count) + { + for(size_t j = 0; j != count; ++j) + if(filters[j]) + { + attach(filters[j]); + incr_owns(); + } + } + +std::string Chain::name() const + { + return "Chain"; + } + +/* +* Fork Constructor +*/ +Fork::Fork(Filter* f1, Filter* f2, Filter* f3, Filter* f4) + { + Filter* filters[4] = { f1, f2, f3, f4 }; + set_next(filters, 4); + } + +/* +* Fork Constructor +*/ +Fork::Fork(Filter* filters[], size_t count) + { + set_next(filters, count); + } + +std::string Fork::name() const + { + return "Fork"; + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/filters/basefilt.h b/src/libs/3rdparty/botan/src/lib/filters/basefilt.h new file mode 100644 index 0000000000..922d356693 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/filters/basefilt.h @@ -0,0 +1,124 @@ +/* +* Basic Filters +* (C) 1999-2007 Jack Lloyd +* (C) 2013 Joel Low +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_BASEFILT_H_ +#define BOTAN_BASEFILT_H_ + +#include + +#if defined(BOTAN_TARGET_OS_HAS_THREADS) + #include +#endif + +namespace Botan { + +/** +* BitBucket is a filter which simply discards all inputs +*/ +class BOTAN_PUBLIC_API(2,0) BitBucket final : public Filter + { + public: + void write(const uint8_t[], size_t) override { /* discard */ } + + std::string name() const override { return "BitBucket"; } + }; + +/** +* This class represents Filter chains. A Filter chain is an ordered +* concatenation of Filters, the input to a Chain sequentially passes +* through all the Filters contained in the Chain. +*/ + +class BOTAN_PUBLIC_API(2,0) Chain final : public Fanout_Filter + { + public: + void write(const uint8_t input[], size_t length) override { send(input, length); } + + std::string name() const override; + + /** + * Construct a chain of up to four filters. The filters are set + * up in the same order as the arguments. + */ + Chain(Filter* = nullptr, Filter* = nullptr, + Filter* = nullptr, Filter* = nullptr); + + /** + * Construct a chain from range of filters + * @param filter_arr the list of filters + * @param length how many filters + */ + Chain(Filter* filter_arr[], size_t length); + }; + +/** +* This class represents a fork filter, whose purpose is to fork the +* flow of data. It causes an input message to result in n messages at +* the end of the filter, where n is the number of forks. +*/ +class BOTAN_PUBLIC_API(2,0) Fork : public Fanout_Filter + { + public: + void write(const uint8_t input[], size_t length) override { send(input, length); } + void set_port(size_t n) { Fanout_Filter::set_port(n); } + + std::string name() const override; + + /** + * Construct a Fork filter with up to four forks. + */ + Fork(Filter*, Filter*, Filter* = nullptr, Filter* = nullptr); + + /** + * Construct a Fork from range of filters + * @param filter_arr the list of filters + * @param length how many filters + */ + Fork(Filter* filter_arr[], size_t length); + }; + +#if defined(BOTAN_HAS_THREAD_UTILS) + +/** +* This class is a threaded version of the Fork filter. While this uses +* threads, the class itself is NOT thread-safe. This is meant as a drop- +* in replacement for Fork where performance gains are possible. +*/ +class BOTAN_PUBLIC_API(2,0) Threaded_Fork final : public Fork + { + public: + std::string name() const override; + + /** + * Construct a Threaded_Fork filter with up to four forks. + */ + Threaded_Fork(Filter*, Filter*, Filter* = nullptr, Filter* = nullptr); + + /** + * Construct a Threaded_Fork from range of filters + * @param filter_arr the list of filters + * @param length how many filters + */ + Threaded_Fork(Filter* filter_arr[], size_t length); + + ~Threaded_Fork(); + + private: + void set_next(Filter* f[], size_t n); + void send(const uint8_t in[], size_t length) override; + void thread_delegate_work(const uint8_t input[], size_t length); + void thread_entry(Filter* filter); + + std::vector> m_threads; + std::unique_ptr m_thread_data; + }; +#endif + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/filters/buf_filt.cpp b/src/libs/3rdparty/botan/src/lib/filters/buf_filt.cpp new file mode 100644 index 0000000000..8acc6c74f9 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/filters/buf_filt.cpp @@ -0,0 +1,103 @@ +/* +* Buffered Filter +* (C) 1999-2007 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include + +namespace Botan { + +/* +* Buffered_Filter Constructor +*/ +Buffered_Filter::Buffered_Filter(size_t b, size_t f) : + m_main_block_mod(b), m_final_minimum(f) + { + if(m_main_block_mod == 0) + throw Invalid_Argument("m_main_block_mod == 0"); + + if(m_final_minimum > m_main_block_mod) + throw Invalid_Argument("m_final_minimum > m_main_block_mod"); + + m_buffer.resize(2 * m_main_block_mod); + m_buffer_pos = 0; + } + +/* +* Buffer input into blocks, trying to minimize copying +*/ +void Buffered_Filter::write(const uint8_t input[], size_t input_size) + { + if(!input_size) + return; + + if(m_buffer_pos + input_size >= m_main_block_mod + m_final_minimum) + { + size_t to_copy = std::min(m_buffer.size() - m_buffer_pos, input_size); + + copy_mem(&m_buffer[m_buffer_pos], input, to_copy); + m_buffer_pos += to_copy; + + input += to_copy; + input_size -= to_copy; + + size_t total_to_consume = + round_down(std::min(m_buffer_pos, + m_buffer_pos + input_size - m_final_minimum), + m_main_block_mod); + + buffered_block(m_buffer.data(), total_to_consume); + + m_buffer_pos -= total_to_consume; + + copy_mem(m_buffer.data(), m_buffer.data() + total_to_consume, m_buffer_pos); + } + + if(input_size >= m_final_minimum) + { + size_t full_blocks = (input_size - m_final_minimum) / m_main_block_mod; + size_t to_copy = full_blocks * m_main_block_mod; + + if(to_copy) + { + buffered_block(input, to_copy); + + input += to_copy; + input_size -= to_copy; + } + } + + copy_mem(&m_buffer[m_buffer_pos], input, input_size); + m_buffer_pos += input_size; + } + +/* +* Finish/flush operation +*/ +void Buffered_Filter::end_msg() + { + if(m_buffer_pos < m_final_minimum) + throw Exception("Buffered filter end_msg without enough input"); + + size_t spare_blocks = (m_buffer_pos - m_final_minimum) / m_main_block_mod; + + if(spare_blocks) + { + size_t spare_bytes = m_main_block_mod * spare_blocks; + buffered_block(m_buffer.data(), spare_bytes); + buffered_final(&m_buffer[spare_bytes], m_buffer_pos - spare_bytes); + } + else + { + buffered_final(m_buffer.data(), m_buffer_pos); + } + + m_buffer_pos = 0; + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/filters/buf_filt.h b/src/libs/3rdparty/botan/src/lib/filters/buf_filt.h new file mode 100644 index 0000000000..b4cd8e6809 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/filters/buf_filt.h @@ -0,0 +1,93 @@ +/* +* Buffered Filter +* (C) 1999-2007 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_BUFFERED_FILTER_H_ +#define BOTAN_BUFFERED_FILTER_H_ + +#include + +namespace Botan { + +/** +* Filter mixin that breaks input into blocks, useful for +* cipher modes +*/ +class BOTAN_PUBLIC_API(2,0) Buffered_Filter + { + public: + /** + * Write bytes into the buffered filter, which will them emit them + * in calls to buffered_block in the subclass + * @param in the input bytes + * @param length of in in bytes + */ + void write(const uint8_t in[], size_t length); + + template + void write(const std::vector& in, size_t length) + { + write(in.data(), length); + } + + /** + * Finish a message, emitting to buffered_block and buffered_final + * Will throw an exception if less than final_minimum bytes were + * written into the filter. + */ + void end_msg(); + + /** + * Initialize a Buffered_Filter + * @param block_size the function buffered_block will be called + * with inputs which are a multiple of this size + * @param final_minimum the function buffered_final will be called + * with at least this many bytes. + */ + Buffered_Filter(size_t block_size, size_t final_minimum); + + virtual ~Buffered_Filter() = default; + protected: + /** + * The block processor, implemented by subclasses + * @param input some input bytes + * @param length the size of input, guaranteed to be a multiple + * of block_size + */ + virtual void buffered_block(const uint8_t input[], size_t length) = 0; + + /** + * The final block, implemented by subclasses + * @param input some input bytes + * @param length the size of input, guaranteed to be at least + * final_minimum bytes + */ + virtual void buffered_final(const uint8_t input[], size_t length) = 0; + + /** + * @return block size of inputs + */ + size_t buffered_block_size() const { return m_main_block_mod; } + + /** + * @return current position in the buffer + */ + size_t current_position() const { return m_buffer_pos; } + + /** + * Reset the buffer position + */ + void buffer_reset() { m_buffer_pos = 0; } + private: + size_t m_main_block_mod, m_final_minimum; + + secure_vector m_buffer; + size_t m_buffer_pos; + }; + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/filters/cipher_filter.cpp b/src/libs/3rdparty/botan/src/lib/filters/cipher_filter.cpp new file mode 100644 index 0000000000..a3e7bd1c39 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/filters/cipher_filter.cpp @@ -0,0 +1,103 @@ +/* +* Filter interface for Cipher_Modes +* (C) 2013,2014,2017 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include + +namespace Botan { + +namespace { + +size_t choose_update_size(size_t update_granularity) + { + const size_t target_size = 1024; + + if(update_granularity >= target_size) + return update_granularity; + + return round_up(target_size, update_granularity); + } + +} + +Cipher_Mode_Filter::Cipher_Mode_Filter(Cipher_Mode* mode) : + Buffered_Filter(choose_update_size(mode->update_granularity()), + mode->minimum_final_size()), + m_mode(mode), + m_nonce(mode->default_nonce_length()), + m_buffer(m_mode->update_granularity()) + { + } + +std::string Cipher_Mode_Filter::name() const + { + return m_mode->name(); + } + +void Cipher_Mode_Filter::set_iv(const InitializationVector& iv) + { + m_nonce = unlock(iv.bits_of()); + } + +void Cipher_Mode_Filter::set_key(const SymmetricKey& key) + { + m_mode->set_key(key); + } + +Key_Length_Specification Cipher_Mode_Filter::key_spec() const + { + return m_mode->key_spec(); + } + +bool Cipher_Mode_Filter::valid_iv_length(size_t length) const + { + return m_mode->valid_nonce_length(length); + } + +void Cipher_Mode_Filter::write(const uint8_t input[], size_t input_length) + { + Buffered_Filter::write(input, input_length); + } + +void Cipher_Mode_Filter::end_msg() + { + Buffered_Filter::end_msg(); + } + +void Cipher_Mode_Filter::start_msg() + { + if(m_nonce.empty() && !m_mode->valid_nonce_length(0)) + throw Invalid_State("Cipher " + m_mode->name() + " requires a fresh nonce for each message"); + + m_mode->start(m_nonce); + m_nonce.clear(); + } + +void Cipher_Mode_Filter::buffered_block(const uint8_t input[], size_t input_length) + { + while(input_length) + { + const size_t take = std::min(m_mode->update_granularity(), input_length); + + m_buffer.assign(input, input + take); + m_mode->update(m_buffer); + + send(m_buffer); + + input += take; + input_length -= take; + } + } + +void Cipher_Mode_Filter::buffered_final(const uint8_t input[], size_t input_length) + { + secure_vector buf(input, input + input_length); + m_mode->finish(buf); + send(buf); + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/filters/cipher_filter.h b/src/libs/3rdparty/botan/src/lib/filters/cipher_filter.h new file mode 100644 index 0000000000..750385d152 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/filters/cipher_filter.h @@ -0,0 +1,58 @@ +/* +* Filter interface for ciphers +* (C) 2013,2016 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_TRANSFORM_FILTER_H_ +#define BOTAN_TRANSFORM_FILTER_H_ + +#include +#include +#include + +namespace Botan { + +/** +* Filter interface for cipher modes +*/ +class BOTAN_PUBLIC_API(2,0) Cipher_Mode_Filter final : public Keyed_Filter, + private Buffered_Filter + { + public: + explicit Cipher_Mode_Filter(Cipher_Mode* t); + + explicit Cipher_Mode_Filter(std::unique_ptr t) : + Cipher_Mode_Filter(t.release()) {} + + void set_iv(const InitializationVector& iv) override; + + void set_key(const SymmetricKey& key) override; + + Key_Length_Specification key_spec() const override; + + bool valid_iv_length(size_t length) const override; + + std::string name() const override; + + private: + void write(const uint8_t input[], size_t input_length) override; + void start_msg() override; + void end_msg() override; + + void buffered_block(const uint8_t input[], size_t input_length) override; + void buffered_final(const uint8_t input[], size_t input_length) override; + + std::unique_ptr m_mode; + std::vector m_nonce; + secure_vector m_buffer; + }; + +// deprecated aliases, will be removed before 2.0 +typedef Cipher_Mode_Filter Transform_Filter; +typedef Transform_Filter Transformation_Filter; + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/filters/comp_filter.cpp b/src/libs/3rdparty/botan/src/lib/filters/comp_filter.cpp new file mode 100644 index 0000000000..2563a49077 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/filters/comp_filter.cpp @@ -0,0 +1,122 @@ +/* +* Filter interface for compression +* (C) 2014,2015,2016 Jack Lloyd +* (C) 2015 Matej Kenda +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include + +#if defined(BOTAN_HAS_COMPRESSION) + #include +#endif + +namespace Botan { + +#if defined(BOTAN_HAS_COMPRESSION) + +Compression_Filter::Compression_Filter(const std::string& type, size_t level, size_t bs) : + m_comp(make_compressor(type)), + m_buffersize(std::max(bs, 256)), + m_level(level) + { + if(!m_comp) + { + throw Invalid_Argument("Compression type '" + type + "' not found"); + } + } + +Compression_Filter::~Compression_Filter() { /* for unique_ptr */ } + +std::string Compression_Filter::name() const + { + return m_comp->name(); + } + +void Compression_Filter::start_msg() + { + m_comp->start(m_level); + } + +void Compression_Filter::write(const uint8_t input[], size_t input_length) + { + while(input_length) + { + const size_t take = std::min(m_buffersize, input_length); + BOTAN_ASSERT(take > 0, "Consumed something"); + + m_buffer.assign(input, input + take); + m_comp->update(m_buffer); + + send(m_buffer); + + input += take; + input_length -= take; + } + } + +void Compression_Filter::flush() + { + m_buffer.clear(); + m_comp->update(m_buffer, 0, true); + send(m_buffer); + } + +void Compression_Filter::end_msg() + { + m_buffer.clear(); + m_comp->finish(m_buffer); + send(m_buffer); + } + +Decompression_Filter::Decompression_Filter(const std::string& type, size_t bs) : + m_comp(make_decompressor(type)), + m_buffersize(std::max(bs, 256)) + { + if(!m_comp) + { + throw Invalid_Argument("Compression type '" + type + "' not found"); + } + } + +Decompression_Filter::~Decompression_Filter() { /* for unique_ptr */ } + +std::string Decompression_Filter::name() const + { + return m_comp->name(); + } + +void Decompression_Filter::start_msg() + { + m_comp->start(); + } + +void Decompression_Filter::write(const uint8_t input[], size_t input_length) + { + while(input_length) + { + const size_t take = std::min(m_buffersize, input_length); + BOTAN_ASSERT(take > 0, "Consumed something"); + + m_buffer.assign(input, input + take); + m_comp->update(m_buffer); + + send(m_buffer); + + input += take; + input_length -= take; + } + } + +void Decompression_Filter::end_msg() + { + m_buffer.clear(); + m_comp->finish(m_buffer); + send(m_buffer); + } + +#endif + +} diff --git a/src/libs/3rdparty/botan/src/lib/filters/comp_filter.h b/src/libs/3rdparty/botan/src/lib/filters/comp_filter.h new file mode 100644 index 0000000000..d9cc00b684 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/filters/comp_filter.h @@ -0,0 +1,71 @@ +/* +* Filter interface for compression +* (C) 2014,2015,2016 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_COMPRESSION_FILTER_H_ +#define BOTAN_COMPRESSION_FILTER_H_ + +#include + +namespace Botan { + +#if defined(BOTAN_HAS_COMPRESSION) + +class Compression_Algorithm; +class Decompression_Algorithm; + +/** +* Filter interface for compression +*/ +class BOTAN_PUBLIC_API(2,0) Compression_Filter final : public Filter + { + public: + void start_msg() override; + void write(const uint8_t input[], size_t input_length) override; + void end_msg() override; + + void flush(); + + std::string name() const override; + + Compression_Filter(const std::string& type, + size_t compression_level, + size_t buffer_size = 4096); + + ~Compression_Filter(); + private: + std::unique_ptr m_comp; + size_t m_buffersize, m_level; + secure_vector m_buffer; + }; + +/** +* Filter interface for decompression +*/ +class BOTAN_PUBLIC_API(2,0) Decompression_Filter final : public Filter + { + public: + void start_msg() override; + void write(const uint8_t input[], size_t input_length) override; + void end_msg() override; + + std::string name() const override; + + Decompression_Filter(const std::string& type, + size_t buffer_size = 4096); + + ~Decompression_Filter(); + private: + std::unique_ptr m_comp; + std::size_t m_buffersize; + secure_vector m_buffer; + }; + +#endif + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/filters/data_snk.cpp b/src/libs/3rdparty/botan/src/lib/filters/data_snk.cpp new file mode 100644 index 0000000000..9f0ddff96d --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/filters/data_snk.cpp @@ -0,0 +1,75 @@ +/* +* DataSink +* (C) 1999-2007 Jack Lloyd +* 2005 Matthew Gregan +* 2017 Philippe Lieser +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include + +#if defined(BOTAN_TARGET_OS_HAS_FILESYSTEM) + #include +#endif + +namespace Botan { + +/* +* Write to a stream +*/ +void DataSink_Stream::write(const uint8_t out[], size_t length) + { + m_sink.write(cast_uint8_ptr_to_char(out), length); + if(!m_sink.good()) + throw Stream_IO_Error("DataSink_Stream: Failure writing to " + + m_identifier); + } + +/* +* Flush the stream +*/ +void DataSink_Stream::end_msg() + { + m_sink.flush(); + } + +/* +* DataSink_Stream Constructor +*/ +DataSink_Stream::DataSink_Stream(std::ostream& out, + const std::string& name) : + m_identifier(name), + m_sink(out) + { + } + +#if defined(BOTAN_TARGET_OS_HAS_FILESYSTEM) + +/* +* DataSink_Stream Constructor +*/ +DataSink_Stream::DataSink_Stream(const std::string& path, + bool use_binary) : + m_identifier(path), + m_sink_memory(new std::ofstream(path, use_binary ? std::ios::binary : std::ios::out)), + m_sink(*m_sink_memory) + { + if(!m_sink.good()) + { + throw Stream_IO_Error("DataSink_Stream: Failure opening " + path); + } + } +#endif + +/* +* DataSink_Stream Destructor +*/ +DataSink_Stream::~DataSink_Stream() + { + // for ~unique_ptr + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/filters/data_snk.h b/src/libs/3rdparty/botan/src/lib/filters/data_snk.h new file mode 100644 index 0000000000..49484b1c1a --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/filters/data_snk.h @@ -0,0 +1,76 @@ +/* +* DataSink +* (C) 1999-2007 Jack Lloyd +* 2017 Philippe Lieser +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_DATA_SINK_H_ +#define BOTAN_DATA_SINK_H_ + +#include +#include +#include + +namespace Botan { + +/** +* This class represents abstract data sink objects. +*/ +class BOTAN_PUBLIC_API(2,0) DataSink : public Filter + { + public: + bool attachable() override { return false; } + DataSink() = default; + virtual ~DataSink() = default; + + DataSink& operator=(const DataSink&) = delete; + DataSink(const DataSink&) = delete; + }; + +/** +* This class represents a data sink which writes its output to a stream. +*/ +class BOTAN_PUBLIC_API(2,0) DataSink_Stream final : public DataSink + { + public: + /** + * Construct a DataSink_Stream from a stream. + * @param stream the stream to write to + * @param name identifier + */ + DataSink_Stream(std::ostream& stream, + const std::string& name = ""); + +#if defined(BOTAN_TARGET_OS_HAS_FILESYSTEM) + + /** + * Construct a DataSink_Stream from a filesystem path name. + * @param pathname the name of the file to open a stream to + * @param use_binary indicates whether to treat the file + * as a binary file or not + */ + DataSink_Stream(const std::string& pathname, + bool use_binary = false); +#endif + + std::string name() const override { return m_identifier; } + + void write(const uint8_t[], size_t) override; + + void end_msg() override; + + ~DataSink_Stream(); + + private: + const std::string m_identifier; + + // May be null, if m_sink was an external reference + std::unique_ptr m_sink_memory; + std::ostream& m_sink; + }; + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/filters/filter.cpp b/src/libs/3rdparty/botan/src/lib/filters/filter.cpp new file mode 100644 index 0000000000..6653fc7815 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/filters/filter.cpp @@ -0,0 +1,129 @@ +/* +* Filter +* (C) 1999-2007 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include + +namespace Botan { + +/* +* Filter Constructor +*/ +Filter::Filter() + { + m_next.resize(1); + m_port_num = 0; + m_filter_owns = 0; + m_owned = false; + } + +/* +* Send data to all ports +*/ +void Filter::send(const uint8_t input[], size_t length) + { + if(!length) + return; + + bool nothing_attached = true; + for(size_t j = 0; j != total_ports(); ++j) + if(m_next[j]) + { + if(m_write_queue.size()) + m_next[j]->write(m_write_queue.data(), m_write_queue.size()); + m_next[j]->write(input, length); + nothing_attached = false; + } + + if(nothing_attached) + m_write_queue += std::make_pair(input, length); + else + m_write_queue.clear(); + } + +/* +* Start a new message +*/ +void Filter::new_msg() + { + start_msg(); + for(size_t j = 0; j != total_ports(); ++j) + if(m_next[j]) + m_next[j]->new_msg(); + } + +/* +* End the current message +*/ +void Filter::finish_msg() + { + end_msg(); + for(size_t j = 0; j != total_ports(); ++j) + if(m_next[j]) + m_next[j]->finish_msg(); + } + +/* +* Attach a filter to the current port +*/ +void Filter::attach(Filter* new_filter) + { + if(new_filter) + { + Filter* last = this; + while(last->get_next()) + last = last->get_next(); + last->m_next[last->current_port()] = new_filter; + } + } + +/* +* Set the active port on a filter +*/ +void Filter::set_port(size_t new_port) + { + if(new_port >= total_ports()) + throw Invalid_Argument("Filter: Invalid port number"); + m_port_num = new_port; + } + +/* +* Return the next Filter in the logical chain +*/ +Filter* Filter::get_next() const + { + if(m_port_num < m_next.size()) + return m_next[m_port_num]; + return nullptr; + } + +/* +* Set the next Filters +*/ +void Filter::set_next(Filter* filters[], size_t size) + { + m_next.clear(); + + m_port_num = 0; + m_filter_owns = 0; + + while(size && filters && (filters[size-1] == nullptr)) + --size; + + if(filters && size) + m_next.assign(filters, filters + size); + } + +/* +* Return the total number of ports +*/ +size_t Filter::total_ports() const + { + return m_next.size(); + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/filters/filter.h b/src/libs/3rdparty/botan/src/lib/filters/filter.h new file mode 100644 index 0000000000..a0857c589e --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/filters/filter.h @@ -0,0 +1,183 @@ +/* +* Filter +* (C) 1999-2007 Jack Lloyd +* (C) 2013 Joel Low +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_FILTER_H_ +#define BOTAN_FILTER_H_ + +#include +#include +#include + +namespace Botan { + +/** +* This class represents general abstract filter objects. +*/ +class BOTAN_PUBLIC_API(2,0) Filter + { + public: + /** + * @return descriptive name for this filter + */ + virtual std::string name() const = 0; + + /** + * Write a portion of a message to this filter. + * @param input the input as a byte array + * @param length the length of the byte array input + */ + virtual void write(const uint8_t input[], size_t length) = 0; + + /** + * Start a new message. Must be closed by end_msg() before another + * message can be started. + */ + virtual void start_msg() { /* default empty */ } + + /** + * Notify that the current message is finished; flush buffers and + * do end-of-message processing (if any). + */ + virtual void end_msg() { /* default empty */ } + + /** + * Check whether this filter is an attachable filter. + * @return true if this filter is attachable, false otherwise + */ + virtual bool attachable() { return true; } + + virtual ~Filter() = default; + protected: + /** + * @param in some input for the filter + * @param length the length of in + */ + virtual void send(const uint8_t in[], size_t length); + + /** + * @param in some input for the filter + */ + void send(uint8_t in) { send(&in, 1); } + + /** + * @param in some input for the filter + */ + void send(const secure_vector& in) { send(in.data(), in.size()); } + + /** + * @param in some input for the filter + */ + void send(const std::vector& 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& in, size_t length) + { + send(in.data(), length); + } + + /** + * @param in some input for the filter + * @param length the number of bytes of in to send + */ + void send(const std::vector& in, size_t length) + { + send(in.data(), length); + } + + Filter(); + + Filter(const Filter&) = delete; + + Filter& operator=(const Filter&) = delete; + + private: + /** + * Start a new message in *this and all following filters. Only for + * internal use, not intended for use in client applications. + */ + void new_msg(); + + /** + * End a new message in *this and all following filters. Only for + * internal use, not intended for use in client applications. + */ + void finish_msg(); + + friend class Pipe; + friend class Fanout_Filter; + + size_t total_ports() const; + size_t current_port() const { return m_port_num; } + + /** + * Set the active port + * @param new_port the new value + */ + void set_port(size_t new_port); + + size_t owns() const { return m_filter_owns; } + + /** + * Attach another filter to this one + * @param f filter to attach + */ + void attach(Filter* f); + + /** + * @param filters the filters to set + * @param count number of items in filters + */ + void set_next(Filter* filters[], size_t count); + Filter* get_next() const; + + secure_vector m_write_queue; + std::vector m_next; // not owned + size_t m_port_num, m_filter_owns; + + // true if filter belongs to a pipe --> prohibit filter sharing! + bool m_owned; + }; + +/** +* This is the abstract Fanout_Filter base class. +**/ +class BOTAN_PUBLIC_API(2,0) Fanout_Filter : public Filter + { + protected: + /** + * Increment the number of filters past us that we own + */ + void incr_owns() { ++m_filter_owns; } + + void set_port(size_t n) { Filter::set_port(n); } + + void set_next(Filter* f[], size_t n) { Filter::set_next(f, n); } + + void attach(Filter* f) { Filter::attach(f); } + + private: + friend class Threaded_Fork; + using Filter::m_write_queue; + using Filter::total_ports; + using Filter::m_next; + }; + +/** +* The type of checking to be performed by decoders: +* NONE - no checks, IGNORE_WS - perform checks, but ignore +* whitespaces, FULL_CHECK - perform checks, also complain +* about white spaces. +*/ +enum Decoder_Checking { NONE, IGNORE_WS, FULL_CHECK }; + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/filters/filters.h b/src/libs/3rdparty/botan/src/lib/filters/filters.h new file mode 100644 index 0000000000..b4aee12078 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/filters/filters.h @@ -0,0 +1,227 @@ +/* +* Filters +* (C) 1999-2007,2015 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_FILTERS_H_ +#define BOTAN_FILTERS_H_ + +#include +#include +#include +#include + +#if defined(BOTAN_HAS_STREAM_CIPHER) + #include +#endif + +#if defined(BOTAN_HAS_HASH) + #include +#endif + +#if defined(BOTAN_HAS_MAC) + #include +#endif + +#if defined(BOTAN_HAS_CODEC_FILTERS) + #include + #include +#endif + +namespace Botan { + +#if defined(BOTAN_HAS_STREAM_CIPHER) + +/** +* Stream Cipher Filter +*/ +class BOTAN_PUBLIC_API(2,0) StreamCipher_Filter final : public Keyed_Filter + { + public: + + std::string name() const override { return m_cipher->name(); } + + /** + * Write input data + * @param input data + * @param input_len length of input in bytes + */ + void write(const uint8_t input[], size_t input_len) override; + + bool valid_iv_length(size_t iv_len) const override + { return m_cipher->valid_iv_length(iv_len); } + + /** + * Set the initialization vector for this filter. + * @param iv the initialization vector to set + */ + void set_iv(const InitializationVector& iv) override + { + m_cipher->set_iv(iv.begin(), iv.length()); + } + + /** + * Set the key of this filter. + * @param key the key to set + */ + void set_key(const SymmetricKey& key) override { m_cipher->set_key(key); } + + Key_Length_Specification key_spec() const override { return m_cipher->key_spec(); } + + /** + * Construct a stream cipher filter. + * @param cipher a cipher object to use + */ + explicit StreamCipher_Filter(StreamCipher* cipher); + + /** + * Construct a stream cipher filter. + * @param cipher a cipher object to use + * @param key the key to use inside this filter + */ + StreamCipher_Filter(StreamCipher* cipher, const SymmetricKey& key); + + /** + * Construct a stream cipher filter. + * @param cipher the name of the desired cipher + */ + explicit StreamCipher_Filter(const std::string& cipher); + + /** + * Construct a stream cipher filter. + * @param cipher the name of the desired cipher + * @param key the key to use inside this filter + */ + StreamCipher_Filter(const std::string& cipher, const SymmetricKey& key); + private: + secure_vector m_buffer; + std::unique_ptr m_cipher; + }; +#endif + +#if defined(BOTAN_HAS_HASH) + +/** +* Hash Filter. +*/ +class BOTAN_PUBLIC_API(2,0) Hash_Filter final : public Filter + { + public: + void write(const uint8_t input[], size_t len) override { m_hash->update(input, len); } + void end_msg() override; + + std::string name() const override { return m_hash->name(); } + + /** + * Construct a hash filter. + * @param hash the hash function to use + * @param len the output length of this filter. Leave the default + * value 0 if you want to use the full output of the hashfunction + * hash. Otherwise, specify a smaller value here so that the + * output of the hash algorithm will be cut off. + */ + Hash_Filter(HashFunction* hash, size_t len = 0) : + m_hash(hash), m_out_len(len) {} + + /** + * Construct a hash filter. + * @param request the name of the hash algorithm to use + * @param len the output length of this filter. Leave the default + * value 0 if you want to use the full output of the hashfunction + * hash. Otherwise, specify a smaller value here so that the + * output of the hash algorithm will be cut off. + */ + Hash_Filter(const std::string& request, size_t len = 0); + + private: + std::unique_ptr m_hash; + const size_t m_out_len; + }; +#endif + +#if defined(BOTAN_HAS_MAC) + +/** +* MessageAuthenticationCode Filter. +*/ +class BOTAN_PUBLIC_API(2,0) MAC_Filter final : public Keyed_Filter + { + public: + void write(const uint8_t input[], size_t len) override { m_mac->update(input, len); } + void end_msg() override; + + std::string name() const override { return m_mac->name(); } + + /** + * Set the key of this filter. + * @param key the key to set + */ + void set_key(const SymmetricKey& key) override { m_mac->set_key(key); } + + Key_Length_Specification key_spec() const override { return m_mac->key_spec(); } + + /** + * Construct a MAC filter. The MAC key will be left empty. + * @param mac the MAC to use + * @param out_len the output length of this filter. Leave the default + * value 0 if you want to use the full output of the + * MAC. Otherwise, specify a smaller value here so that the + * output of the MAC will be cut off. + */ + MAC_Filter(MessageAuthenticationCode* mac, + size_t out_len = 0) : + m_mac(mac), + m_out_len(out_len) + { + } + + /** + * Construct a MAC filter. + * @param mac the MAC to use + * @param key the MAC key to use + * @param out_len the output length of this filter. Leave the default + * value 0 if you want to use the full output of the + * MAC. Otherwise, specify a smaller value here so that the + * output of the MAC will be cut off. + */ + MAC_Filter(MessageAuthenticationCode* mac, + const SymmetricKey& key, + size_t out_len = 0) : + m_mac(mac), + m_out_len(out_len) + { + m_mac->set_key(key); + } + + /** + * Construct a MAC filter. The MAC key will be left empty. + * @param mac the name of the MAC to use + * @param len the output length of this filter. Leave the default + * value 0 if you want to use the full output of the + * MAC. Otherwise, specify a smaller value here so that the + * output of the MAC will be cut off. + */ + MAC_Filter(const std::string& mac, size_t len = 0); + + /** + * Construct a MAC filter. + * @param mac the name of the MAC to use + * @param key the MAC key to use + * @param len the output length of this filter. Leave the default + * value 0 if you want to use the full output of the + * MAC. Otherwise, specify a smaller value here so that the + * output of the MAC will be cut off. + */ + MAC_Filter(const std::string& mac, const SymmetricKey& key, + size_t len = 0); + private: + std::unique_ptr m_mac; + const size_t m_out_len; + }; +#endif + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/filters/info.txt b/src/libs/3rdparty/botan/src/lib/filters/info.txt new file mode 100644 index 0000000000..cfc1143536 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/filters/info.txt @@ -0,0 +1,24 @@ + +FILTERS -> 20160415 + + + +basefilt.h +buf_filt.h +data_snk.h +comp_filter.h +filter.h +filters.h +key_filt.h +pipe.h +secqueue.h +cipher_filter.h + + + +out_buf.h + + + +modes + diff --git a/src/libs/3rdparty/botan/src/lib/filters/key_filt.cpp b/src/libs/3rdparty/botan/src/lib/filters/key_filt.cpp new file mode 100644 index 0000000000..b87a8c87f3 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/filters/key_filt.cpp @@ -0,0 +1,39 @@ +/* +* (C) 2015 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include + +namespace Botan { + +Keyed_Filter* get_cipher(const std::string& algo_spec, + Cipher_Dir direction) + { + std::unique_ptr c(Cipher_Mode::create_or_throw(algo_spec, direction)); + return new Cipher_Mode_Filter(c.release()); + } + +Keyed_Filter* get_cipher(const std::string& algo_spec, + const SymmetricKey& key, + const InitializationVector& iv, + Cipher_Dir direction) + { + Keyed_Filter* cipher = get_cipher(algo_spec, key, direction); + if(iv.length()) + cipher->set_iv(iv); + return cipher; + } + +Keyed_Filter* get_cipher(const std::string& algo_spec, + const SymmetricKey& key, + Cipher_Dir direction) + { + Keyed_Filter* cipher = get_cipher(algo_spec, direction); + cipher->set_key(key); + return cipher; + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/filters/key_filt.h b/src/libs/3rdparty/botan/src/lib/filters/key_filt.h new file mode 100644 index 0000000000..67b689f998 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/filters/key_filt.h @@ -0,0 +1,109 @@ +/* +* Keyed_Filter +* (C) 1999-2007 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_KEYED_FILTER_H_ +#define BOTAN_KEYED_FILTER_H_ + +#include +#include +#include + +namespace Botan { + +/** +* This class represents keyed filters, i.e. filters that have to be +* fed with a key in order to function. +*/ +class BOTAN_PUBLIC_API(2,0) Keyed_Filter : public Filter + { + public: + /** + * Set the key of this filter + * @param key the key to use + */ + virtual void set_key(const SymmetricKey& key) = 0; + + /** + * Set the initialization vector of this filter. Note: you should + * call set_iv() only after you have called set_key() + * @param iv the initialization vector to use + */ + virtual void set_iv(const InitializationVector& iv); + + /** + * Check whether a key length is valid for this filter + * @param length the key length to be checked for validity + * @return true if the key length is valid, false otherwise + */ + bool valid_keylength(size_t length) const + { + return key_spec().valid_keylength(length); + } + + /** + * @return object describing limits on key size + */ + virtual Key_Length_Specification key_spec() const = 0; + + /** + * Check whether an IV length is valid for this filter + * @param length the IV length to be checked for validity + * @return true if the IV length is valid, false otherwise + */ + virtual bool valid_iv_length(size_t length) const + { return (length == 0); } + }; + + + +/* +* Get a cipher object +*/ + +/** +* Factory method for general symmetric cipher filters. +* @param algo_spec the name of the desired cipher +* @param key the key to be used for encryption/decryption performed by +* the filter +* @param iv the initialization vector to be used +* @param direction determines whether the filter will be an encrypting +* or decrypting filter +* @return pointer to newly allocated encryption or decryption filter +*/ +BOTAN_PUBLIC_API(2,0) Keyed_Filter* get_cipher(const std::string& algo_spec, + const SymmetricKey& key, + const InitializationVector& iv, + Cipher_Dir direction); + +/** +* Factory method for general symmetric cipher filters. +* @param algo_spec the name of the desired cipher +* @param key the key to be used for encryption/decryption performed by +* the filter +* @param direction determines whether the filter will be an encrypting +* or decrypting filter +* @return pointer to the encryption or decryption filter +*/ +BOTAN_PUBLIC_API(2,0) Keyed_Filter* get_cipher(const std::string& algo_spec, + const SymmetricKey& key, + Cipher_Dir direction); + +/** +* Factory method for general symmetric cipher filters. No key will be +* set in the filter. +* +* @param algo_spec the name of the desired cipher +* @param direction determines whether the filter will be an encrypting or +* decrypting filter +* @return pointer to the encryption or decryption filter +*/ +BOTAN_PUBLIC_API(2,0) Keyed_Filter* get_cipher(const std::string& algo_spec, + Cipher_Dir direction); + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/filters/out_buf.cpp b/src/libs/3rdparty/botan/src/lib/filters/out_buf.cpp new file mode 100644 index 0000000000..645cc08236 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/filters/out_buf.cpp @@ -0,0 +1,121 @@ +/* +* Pipe Output Buffer +* (C) 1999-2007,2011 Jack Lloyd +* 2012 Markus Wanner +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include + +namespace Botan { + +/* +* Read data from a message +*/ +size_t Output_Buffers::read(uint8_t output[], size_t length, + Pipe::message_id msg) + { + SecureQueue* q = get(msg); + if(q) + return q->read(output, length); + return 0; + } + +/* +* Peek at data in a message +*/ +size_t Output_Buffers::peek(uint8_t output[], size_t length, + size_t stream_offset, + Pipe::message_id msg) const + { + SecureQueue* q = get(msg); + if(q) + return q->peek(output, length, stream_offset); + return 0; + } + +/* +* Check available bytes in a message +*/ +size_t Output_Buffers::remaining(Pipe::message_id msg) const + { + SecureQueue* q = get(msg); + if(q) + return q->size(); + return 0; + } + +/* +* Return the total bytes of a message that have already been read. +*/ +size_t Output_Buffers::get_bytes_read(Pipe::message_id msg) const + { + SecureQueue* q = get(msg); + if (q) + return q->get_bytes_read(); + return 0; + } + +/* +* Add a new output queue +*/ +void Output_Buffers::add(SecureQueue* queue) + { + BOTAN_ASSERT(queue, "queue was provided"); + + BOTAN_ASSERT(m_buffers.size() < m_buffers.max_size(), + "Room was available in container"); + + m_buffers.push_back(std::unique_ptr(queue)); + } + +/* +* Retire old output queues +*/ +void Output_Buffers::retire() + { + for(size_t i = 0; i != m_buffers.size(); ++i) + if(m_buffers[i] && m_buffers[i]->size() == 0) + { + m_buffers[i].reset(); + } + + while(m_buffers.size() && !m_buffers[0]) + { + m_buffers.pop_front(); + m_offset = m_offset + Pipe::message_id(1); + } + } + +/* +* Get a particular output queue +*/ +SecureQueue* Output_Buffers::get(Pipe::message_id msg) const + { + if(msg < m_offset) + return nullptr; + + BOTAN_ASSERT(msg < message_count(), "Message number is in range"); + + return m_buffers[msg-m_offset].get(); + } + +/* +* Return the total number of messages +*/ +Pipe::message_id Output_Buffers::message_count() const + { + return (m_offset + m_buffers.size()); + } + +/* +* Output_Buffers Constructor +*/ +Output_Buffers::Output_Buffers() + { + m_offset = 0; + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/filters/out_buf.h b/src/libs/3rdparty/botan/src/lib/filters/out_buf.h new file mode 100644 index 0000000000..d6efbdaf27 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/filters/out_buf.h @@ -0,0 +1,44 @@ +/* +* Output Buffer +* (C) 1999-2007 Jack Lloyd +* 2012 Markus Wanner +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_OUTPUT_BUFFER_H_ +#define BOTAN_OUTPUT_BUFFER_H_ + +#include +#include +#include + +namespace Botan { + +/** +* Container of output buffers for Pipe +*/ +class Output_Buffers final + { + public: + size_t read(uint8_t[], size_t, Pipe::message_id); + size_t peek(uint8_t[], size_t, size_t, Pipe::message_id) const; + size_t get_bytes_read(Pipe::message_id) const; + size_t remaining(Pipe::message_id) const; + + void add(class SecureQueue*); + void retire(); + + Pipe::message_id message_count() const; + + Output_Buffers(); + private: + class SecureQueue* get(Pipe::message_id) const; + + std::deque> m_buffers; + Pipe::message_id m_offset; + }; + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/filters/pipe.cpp b/src/libs/3rdparty/botan/src/lib/filters/pipe.cpp new file mode 100644 index 0000000000..0bba81bf2d --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/filters/pipe.cpp @@ -0,0 +1,311 @@ +/* +* Pipe +* (C) 1999-2007 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include + +namespace Botan { + +namespace { + +/* +* A Filter that does nothing +*/ +class Null_Filter final : public Filter + { + public: + void write(const uint8_t input[], size_t length) override + { send(input, length); } + + std::string name() const override { return "Null"; } + }; + +} + +/* +* Pipe Constructor +*/ +Pipe::Pipe(Filter* f1, Filter* f2, Filter* f3, Filter* f4) : + Pipe({f1,f2,f3,f4}) + { + } + +/* +* Pipe Constructor +*/ +Pipe::Pipe(std::initializer_list args) + { + m_outputs.reset(new Output_Buffers); + m_pipe = nullptr; + m_default_read = 0; + m_inside_msg = false; + + for(auto i = args.begin(); i != args.end(); ++i) + do_append(*i); + } + +/* +* Pipe Destructor +*/ +Pipe::~Pipe() + { + destruct(m_pipe); + } + +/* +* Reset the Pipe +*/ +void Pipe::reset() + { + destruct(m_pipe); + m_pipe = nullptr; + m_inside_msg = false; + } + +/* +* Destroy the Pipe +*/ +void Pipe::destruct(Filter* to_kill) + { + if(!to_kill || dynamic_cast(to_kill)) + return; + for(size_t j = 0; j != to_kill->total_ports(); ++j) + destruct(to_kill->m_next[j]); + delete to_kill; + } + +/* +* Test if the Pipe has any data in it +*/ +bool Pipe::end_of_data() const + { + return (remaining() == 0); + } + +/* +* Set the default read message +*/ +void Pipe::set_default_msg(message_id msg) + { + if(msg >= message_count()) + throw Invalid_Argument("Pipe::set_default_msg: msg number is too high"); + m_default_read = msg; + } + +/* +* Process a full message at once +*/ +void Pipe::process_msg(const uint8_t input[], size_t length) + { + start_msg(); + write(input, length); + end_msg(); + } + +/* +* Process a full message at once +*/ +void Pipe::process_msg(const secure_vector& input) + { + process_msg(input.data(), input.size()); + } + +void Pipe::process_msg(const std::vector& input) + { + process_msg(input.data(), input.size()); + } + +/* +* Process a full message at once +*/ +void Pipe::process_msg(const std::string& input) + { + process_msg(cast_char_ptr_to_uint8(input.data()), input.length()); + } + +/* +* Process a full message at once +*/ +void Pipe::process_msg(DataSource& input) + { + start_msg(); + write(input); + end_msg(); + } + +/* +* Start a new message +*/ +void Pipe::start_msg() + { + if(m_inside_msg) + throw Invalid_State("Pipe::start_msg: Message was already started"); + if(m_pipe == nullptr) + m_pipe = new Null_Filter; + find_endpoints(m_pipe); + m_pipe->new_msg(); + m_inside_msg = true; + } + +/* +* End the current message +*/ +void Pipe::end_msg() + { + if(!m_inside_msg) + throw Invalid_State("Pipe::end_msg: Message was already ended"); + m_pipe->finish_msg(); + clear_endpoints(m_pipe); + if(dynamic_cast(m_pipe)) + { + delete m_pipe; + m_pipe = nullptr; + } + m_inside_msg = false; + + m_outputs->retire(); + } + +/* +* Find the endpoints of the Pipe +*/ +void Pipe::find_endpoints(Filter* f) + { + for(size_t j = 0; j != f->total_ports(); ++j) + if(f->m_next[j] && !dynamic_cast(f->m_next[j])) + find_endpoints(f->m_next[j]); + else + { + SecureQueue* q = new SecureQueue; + f->m_next[j] = q; + m_outputs->add(q); + } + } + +/* +* Remove the SecureQueues attached to the Filter +*/ +void Pipe::clear_endpoints(Filter* f) + { + if(!f) return; + for(size_t j = 0; j != f->total_ports(); ++j) + { + if(f->m_next[j] && dynamic_cast(f->m_next[j])) + f->m_next[j] = nullptr; + clear_endpoints(f->m_next[j]); + } + } + +void Pipe::append(Filter* filter) + { + do_append(filter); + } + +void Pipe::append_filter(Filter* filter) + { + if(m_outputs->message_count() != 0) + throw Invalid_State("Cannot call Pipe::append_filter after start_msg"); + + do_append(filter); + } + +void Pipe::prepend(Filter* filter) + { + do_prepend(filter); + } + +void Pipe::prepend_filter(Filter* filter) + { + if(m_outputs->message_count() != 0) + throw Invalid_State("Cannot call Pipe::prepend_filter after start_msg"); + + do_prepend(filter); + } + +/* +* Append a Filter to the Pipe +*/ +void Pipe::do_append(Filter* filter) + { + if(!filter) + return; + if(dynamic_cast(filter)) + throw Invalid_Argument("Pipe::append: SecureQueue cannot be used"); + if(filter->m_owned) + throw Invalid_Argument("Filters cannot be shared among multiple Pipes"); + + if(m_inside_msg) + throw Invalid_State("Cannot append to a Pipe while it is processing"); + + filter->m_owned = true; + + if(!m_pipe) m_pipe = filter; + else m_pipe->attach(filter); + } + +/* +* Prepend a Filter to the Pipe +*/ +void Pipe::do_prepend(Filter* filter) + { + if(m_inside_msg) + throw Invalid_State("Cannot prepend to a Pipe while it is processing"); + if(!filter) + return; + if(dynamic_cast(filter)) + throw Invalid_Argument("Pipe::prepend: SecureQueue cannot be used"); + if(filter->m_owned) + throw Invalid_Argument("Filters cannot be shared among multiple Pipes"); + + filter->m_owned = true; + + if(m_pipe) filter->attach(m_pipe); + m_pipe = filter; + } + +/* +* Pop a Filter off the Pipe +*/ +void Pipe::pop() + { + if(m_inside_msg) + throw Invalid_State("Cannot pop off a Pipe while it is processing"); + + if(!m_pipe) + return; + + if(m_pipe->total_ports() > 1) + throw Invalid_State("Cannot pop off a Filter with multiple ports"); + + size_t to_remove = m_pipe->owns() + 1; + + while(to_remove--) + { + std::unique_ptr to_destroy(m_pipe); + m_pipe = m_pipe->m_next[0]; + } + } + +/* +* Return the number of messages in this Pipe +*/ +Pipe::message_id Pipe::message_count() const + { + return m_outputs->message_count(); + } + +/* +* Static Member Variables +*/ +const Pipe::message_id Pipe::LAST_MESSAGE = + static_cast(-2); + +const Pipe::message_id Pipe::DEFAULT_MESSAGE = + static_cast(-1); + +} diff --git a/src/libs/3rdparty/botan/src/lib/filters/pipe.h b/src/libs/3rdparty/botan/src/lib/filters/pipe.h new file mode 100644 index 0000000000..03b5160835 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/filters/pipe.h @@ -0,0 +1,379 @@ +/* +* Pipe +* (C) 1999-2007 Jack Lloyd +* 2012 Markus Wanner +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_PIPE_H_ +#define BOTAN_PIPE_H_ + +#include +#include +#include +#include + +namespace Botan { + +class Filter; +class Output_Buffers; + +/** +* This class represents pipe objects. +* A set of filters can be placed into a pipe, and information flows +* through the pipe until it reaches the end, where the output is +* collected for retrieval. If you're familiar with the Unix shell +* environment, this design will sound quite familiar. +*/ +class BOTAN_PUBLIC_API(2,0) Pipe final : public DataSource + { + public: + /** + * An opaque type that identifies a message in this Pipe + */ + typedef size_t message_id; + + /** + * Exception if you use an invalid message as an argument to + * read, remaining, etc + */ + class BOTAN_PUBLIC_API(2,0) Invalid_Message_Number final : public Invalid_Argument + { + public: + /** + * @param where the error occurred + * @param msg the invalid message id that was used + */ + Invalid_Message_Number(const std::string& where, message_id msg) : + Invalid_Argument("Pipe::" + where + ": Invalid message number " + + std::to_string(msg)) + {} + }; + + /** + * A meta-id for whatever the last message is + */ + static const message_id LAST_MESSAGE; + + /** + * A meta-id for the default message (set with set_default_msg) + */ + static const message_id DEFAULT_MESSAGE; + + /** + * Write input to the pipe, i.e. to its first filter. + * @param in the byte array to write + * @param length the length of the byte array in + */ + void write(const uint8_t in[], size_t length); + + /** + * Write input to the pipe, i.e. to its first filter. + * @param in the secure_vector containing the data to write + */ + void write(const secure_vector& in) + { write(in.data(), in.size()); } + + /** + * Write input to the pipe, i.e. to its first filter. + * @param in the std::vector containing the data to write + */ + void write(const std::vector& in) + { write(in.data(), in.size()); } + + /** + * Write input to the pipe, i.e. to its first filter. + * @param in the string containing the data to write + */ + void write(const std::string& in); + + /** + * Write input to the pipe, i.e. to its first filter. + * @param in the DataSource to read the data from + */ + void write(DataSource& in); + + /** + * Write input to the pipe, i.e. to its first filter. + * @param in a single byte to be written + */ + void write(uint8_t in); + + /** + * Perform start_msg(), write() and end_msg() sequentially. + * @param in the byte array containing the data to write + * @param length the length of the byte array to write + */ + void process_msg(const uint8_t in[], size_t length); + + /** + * Perform start_msg(), write() and end_msg() sequentially. + * @param in the secure_vector containing the data to write + */ + void process_msg(const secure_vector& in); + + /** + * Perform start_msg(), write() and end_msg() sequentially. + * @param in the secure_vector containing the data to write + */ + void process_msg(const std::vector& in); + + /** + * Perform start_msg(), write() and end_msg() sequentially. + * @param in the string containing the data to write + */ + void process_msg(const std::string& in); + + /** + * Perform start_msg(), write() and end_msg() sequentially. + * @param in the DataSource providing the data to write + */ + void process_msg(DataSource& in); + + /** + * Find out how many bytes are ready to read. + * @param msg the number identifying the message + * for which the information is desired + * @return number of bytes that can still be read + */ + size_t remaining(message_id msg = DEFAULT_MESSAGE) const BOTAN_WARN_UNUSED_RESULT; + + /** + * Read the default message from the pipe. Moves the internal + * offset so that every call to read will return a new portion of + * the message. + * + * @param output the byte array to write the read bytes to + * @param length the length of the byte array output + * @return number of bytes actually read into output + */ + size_t read(uint8_t output[], size_t length) override BOTAN_WARN_UNUSED_RESULT; + + /** + * Read a specified message from the pipe. Moves the internal + * offset so that every call to read will return a new portion of + * the message. + * @param output the byte array to write the read bytes to + * @param length the length of the byte array output + * @param msg the number identifying the message to read from + * @return number of bytes actually read into output + */ + size_t read(uint8_t output[], size_t length, message_id msg) BOTAN_WARN_UNUSED_RESULT; + + /** + * Read a single byte from the pipe. Moves the internal offset so + * that every call to read will return a new portion of the + * message. + * + * @param output the byte to write the result to + * @param msg the message to read from + * @return number of bytes actually read into output + */ + size_t read(uint8_t& output, message_id msg = DEFAULT_MESSAGE) BOTAN_WARN_UNUSED_RESULT; + + /** + * Read the full contents of the pipe. + * @param msg the number identifying the message to read from + * @return secure_vector holding the contents of the pipe + */ + secure_vector read_all(message_id msg = DEFAULT_MESSAGE) BOTAN_WARN_UNUSED_RESULT; + + /** + * Read the full contents of the pipe. + * @param msg the number identifying the message to read from + * @return string holding the contents of the pipe + */ + std::string read_all_as_string(message_id msg = DEFAULT_MESSAGE) BOTAN_WARN_UNUSED_RESULT; + + /** + * Read from the default message but do not modify the internal + * offset. Consecutive calls to peek() will return portions of + * the message starting at the same position. + * @param output the byte array to write the peeked message part to + * @param length the length of the byte array output + * @param offset the offset from the current position in message + * @return number of bytes actually peeked and written into output + */ + size_t peek(uint8_t output[], size_t length, size_t offset) const override BOTAN_WARN_UNUSED_RESULT; + + /** Read from the specified message but do not modify the + * internal offset. Consecutive calls to peek() will return + * portions of the message starting at the same position. + * @param output the byte array to write the peeked message part to + * @param length the length of the byte array output + * @param offset the offset from the current position in message + * @param msg the number identifying the message to peek from + * @return number of bytes actually peeked and written into output + */ + size_t peek(uint8_t output[], size_t length, + size_t offset, message_id msg) const BOTAN_WARN_UNUSED_RESULT; + + /** Read a single byte from the specified message but do not + * modify the internal offset. Consecutive calls to peek() will + * return portions of the message starting at the same position. + * @param output the byte to write the peeked message byte to + * @param offset the offset from the current position in message + * @param msg the number identifying the message to peek from + * @return number of bytes actually peeked and written into output + */ + size_t peek(uint8_t& output, size_t offset, + message_id msg = DEFAULT_MESSAGE) const BOTAN_WARN_UNUSED_RESULT; + + /** + * @return the number of bytes read from the default message. + */ + size_t get_bytes_read() const override; + + /** + * @return the number of bytes read from the specified message. + */ + size_t get_bytes_read(message_id msg) const; + + bool check_available(size_t n) override; + bool check_available_msg(size_t n, message_id msg); + + /** + * @return currently set default message + */ + size_t default_msg() const { return m_default_read; } + + /** + * Set the default message + * @param msg the number identifying the message which is going to + * be the new default message + */ + void set_default_msg(message_id msg); + + /** + * Get the number of messages the are in this pipe. + * @return number of messages the are in this pipe + */ + message_id message_count() const; + + /** + * Test whether this pipe has any data that can be read from. + * @return true if there is more data to read, false otherwise + */ + bool end_of_data() const override; + + /** + * Start a new message in the pipe. A potential other message in this pipe + * must be closed with end_msg() before this function may be called. + */ + void start_msg(); + + /** + * End the current message. + */ + void end_msg(); + + /** + * Insert a new filter at the front of the pipe + * Deprecated because runtime modification of Pipes is deprecated. + * You can instead use prepend_filter which only works before the first + * message is processed. + * @param filt the new filter to insert + */ + BOTAN_DEPRECATED("Runtime modification of Pipe deprecated") + void prepend(Filter* filt); + + /** + * Insert a new filter at the back of the pipe + * Deprecated because runtime modification of Pipes is deprecated. + * You can instead use append_filter which only works before the first + * message is processed. + * @param filt the new filter to insert + */ + BOTAN_DEPRECATED("Runtime modification of Pipe deprecated") + void append(Filter* filt); + + /** + * Remove the first filter at the front of the pipe. + */ + BOTAN_DEPRECATED("Runtime modification of Pipe deprecated") + void pop(); + + /** + * Reset this pipe to an empty pipe. + */ + BOTAN_DEPRECATED("Runtime modification of Pipe deprecated") + void reset(); + + /** + * Append a new filter onto the filter sequence. This may only be + * called immediately after initial construction, before _any_ + * calls to start_msg have been made. + * + * This function (unlike append) is not deprecated, as it allows + * only modification of the pipe at initialization (before use) + * rather than after messages have been processed. + */ + void append_filter(Filter* filt); + + /** + * Prepend a new filter onto the filter sequence. This may only be + * called immediately after initial construction, before _any_ + * calls to start_msg have been made. + * + * This function (unlike prepend) is not deprecated, as it allows + * only modification of the pipe at initialization (before use) + * rather than after messages have been processed. + */ + void prepend_filter(Filter* filt); + + /** + * Construct a Pipe of up to four filters. The filters are set up + * in the same order as the arguments. + */ + Pipe(Filter* = nullptr, Filter* = nullptr, + Filter* = nullptr, Filter* = nullptr); + + /** + * Construct a Pipe from a list of filters + * @param filters the set of filters to use + */ + explicit Pipe(std::initializer_list filters); + + Pipe(const Pipe&) = delete; + Pipe& operator=(const Pipe&) = delete; + + ~Pipe(); + private: + void destruct(Filter*); + void do_append(Filter* filt); + void do_prepend(Filter* filt); + void find_endpoints(Filter*); + void clear_endpoints(Filter*); + + message_id get_message_no(const std::string&, message_id) const; + + Filter* m_pipe; + std::unique_ptr m_outputs; + message_id m_default_read; + bool m_inside_msg; + }; + +/** +* Stream output operator; dumps the results from pipe's default +* message to the output stream. +* @param out an output stream +* @param pipe the pipe +*/ +BOTAN_PUBLIC_API(2,0) std::ostream& operator<<(std::ostream& out, Pipe& pipe); + +/** +* Stream input operator; dumps the remaining bytes of input +* to the (assumed open) pipe message. +* @param in the input stream +* @param pipe the pipe +*/ +BOTAN_PUBLIC_API(2,0) std::istream& operator>>(std::istream& in, Pipe& pipe); + +} + +#if defined(BOTAN_HAS_PIPE_UNIXFD_IO) + #include +#endif + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/filters/pipe_io.cpp b/src/libs/3rdparty/botan/src/lib/filters/pipe_io.cpp new file mode 100644 index 0000000000..a909cba725 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/filters/pipe_io.cpp @@ -0,0 +1,47 @@ +/* +* Pipe I/O +* (C) 1999-2007 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include + +namespace Botan { + +/* +* Write data from a pipe into an ostream +*/ +std::ostream& operator<<(std::ostream& stream, Pipe& pipe) + { + secure_vector buffer(BOTAN_DEFAULT_BUFFER_SIZE); + while(stream.good() && pipe.remaining()) + { + const size_t got = pipe.read(buffer.data(), buffer.size()); + stream.write(cast_uint8_ptr_to_char(buffer.data()), got); + } + if(!stream.good()) + throw Stream_IO_Error("Pipe output operator (iostream) has failed"); + return stream; + } + +/* +* Read data from an istream into a pipe +*/ +std::istream& operator>>(std::istream& stream, Pipe& pipe) + { + secure_vector buffer(BOTAN_DEFAULT_BUFFER_SIZE); + while(stream.good()) + { + stream.read(cast_uint8_ptr_to_char(buffer.data()), buffer.size()); + const size_t got = static_cast(stream.gcount()); + pipe.write(buffer.data(), got); + } + if(stream.bad() || (stream.fail() && !stream.eof())) + throw Stream_IO_Error("Pipe input operator (iostream) has failed"); + return stream; + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/filters/pipe_rw.cpp b/src/libs/3rdparty/botan/src/lib/filters/pipe_rw.cpp new file mode 100644 index 0000000000..dc7b973727 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/filters/pipe_rw.cpp @@ -0,0 +1,181 @@ +/* +* Pipe Reading/Writing +* (C) 1999-2007 Jack Lloyd +* 2012 Markus Wanner +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include + +namespace Botan { + +/* +* Look up the canonical ID for a queue +*/ +Pipe::message_id Pipe::get_message_no(const std::string& func_name, + message_id msg) const + { + if(msg == DEFAULT_MESSAGE) + msg = default_msg(); + else if(msg == LAST_MESSAGE) + msg = message_count() - 1; + + if(msg >= message_count()) + throw Invalid_Message_Number(func_name, msg); + + return msg; + } + +/* +* Write into a Pipe +*/ +void Pipe::write(const uint8_t input[], size_t length) + { + if(!m_inside_msg) + throw Invalid_State("Cannot write to a Pipe while it is not processing"); + m_pipe->write(input, length); + } + +/* +* Write a string into a Pipe +*/ +void Pipe::write(const std::string& str) + { + write(cast_char_ptr_to_uint8(str.data()), str.size()); + } + +/* +* Write a single byte into a Pipe +*/ +void Pipe::write(uint8_t input) + { + write(&input, 1); + } + +/* +* Write the contents of a DataSource into a Pipe +*/ +void Pipe::write(DataSource& source) + { + secure_vector buffer(BOTAN_DEFAULT_BUFFER_SIZE); + while(!source.end_of_data()) + { + size_t got = source.read(buffer.data(), buffer.size()); + write(buffer.data(), got); + } + } + +/* +* Read some data from the pipe +*/ +size_t Pipe::read(uint8_t output[], size_t length, message_id msg) + { + return m_outputs->read(output, length, get_message_no("read", msg)); + } + +/* +* Read some data from the pipe +*/ +size_t Pipe::read(uint8_t output[], size_t length) + { + return read(output, length, DEFAULT_MESSAGE); + } + +/* +* Read a single byte from the pipe +*/ +size_t Pipe::read(uint8_t& out, message_id msg) + { + return read(&out, 1, msg); + } + +/* +* Return all data in the pipe +*/ +secure_vector Pipe::read_all(message_id msg) + { + msg = ((msg != DEFAULT_MESSAGE) ? msg : default_msg()); + secure_vector buffer(remaining(msg)); + size_t got = read(buffer.data(), buffer.size(), msg); + buffer.resize(got); + return buffer; + } + +/* +* Return all data in the pipe as a string +*/ +std::string Pipe::read_all_as_string(message_id msg) + { + msg = ((msg != DEFAULT_MESSAGE) ? msg : default_msg()); + secure_vector buffer(BOTAN_DEFAULT_BUFFER_SIZE); + std::string str; + str.reserve(remaining(msg)); + + while(true) + { + size_t got = read(buffer.data(), buffer.size(), msg); + if(got == 0) + break; + str.append(cast_uint8_ptr_to_char(buffer.data()), got); + } + + return str; + } + +/* +* Find out how many bytes are ready to read +*/ +size_t Pipe::remaining(message_id msg) const + { + return m_outputs->remaining(get_message_no("remaining", msg)); + } + +/* +* Peek at some data in the pipe +*/ +size_t Pipe::peek(uint8_t output[], size_t length, + size_t offset, message_id msg) const + { + return m_outputs->peek(output, length, offset, get_message_no("peek", msg)); + } + +/* +* Peek at some data in the pipe +*/ +size_t Pipe::peek(uint8_t output[], size_t length, size_t offset) const + { + return peek(output, length, offset, DEFAULT_MESSAGE); + } + +/* +* Peek at a byte in the pipe +*/ +size_t Pipe::peek(uint8_t& out, size_t offset, message_id msg) const + { + return peek(&out, 1, offset, msg); + } + +size_t Pipe::get_bytes_read() const + { + return m_outputs->get_bytes_read(default_msg()); + } + +size_t Pipe::get_bytes_read(message_id msg) const + { + return m_outputs->get_bytes_read(msg); + } + +bool Pipe::check_available(size_t n) + { + return (n <= remaining(default_msg())); + } + +bool Pipe::check_available_msg(size_t n, message_id msg) + { + return (n <= remaining(msg)); + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/filters/secqueue.cpp b/src/libs/3rdparty/botan/src/lib/filters/secqueue.cpp new file mode 100644 index 0000000000..1c8d281493 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/filters/secqueue.cpp @@ -0,0 +1,232 @@ +/* +* SecureQueue +* (C) 1999-2007 Jack Lloyd +* 2012 Markus Wanner +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include + +namespace Botan { + +/** +* A node in a SecureQueue +*/ +class SecureQueueNode final + { + public: + SecureQueueNode() : m_buffer(BOTAN_DEFAULT_BUFFER_SIZE) + { m_next = nullptr; m_start = m_end = 0; } + + ~SecureQueueNode() { m_next = nullptr; m_start = m_end = 0; } + + size_t write(const uint8_t input[], size_t length) + { + size_t copied = std::min(length, m_buffer.size() - m_end); + copy_mem(m_buffer.data() + m_end, input, copied); + m_end += copied; + return copied; + } + + size_t read(uint8_t output[], size_t length) + { + size_t copied = std::min(length, m_end - m_start); + copy_mem(output, m_buffer.data() + m_start, copied); + m_start += copied; + return copied; + } + + size_t peek(uint8_t output[], size_t length, size_t offset = 0) + { + const size_t left = m_end - m_start; + if(offset >= left) return 0; + size_t copied = std::min(length, left - offset); + copy_mem(output, m_buffer.data() + m_start + offset, copied); + return copied; + } + + size_t size() const { return (m_end - m_start); } + private: + friend class SecureQueue; + SecureQueueNode* m_next; + secure_vector m_buffer; + size_t m_start, m_end; + }; + +/* +* Create a SecureQueue +*/ +SecureQueue::SecureQueue() + { + m_bytes_read = 0; + set_next(nullptr, 0); + m_head = m_tail = new SecureQueueNode; + } + +/* +* Copy a SecureQueue +*/ +SecureQueue::SecureQueue(const SecureQueue& input) : + Fanout_Filter(), DataSource() + { + m_bytes_read = 0; + set_next(nullptr, 0); + + m_head = m_tail = new SecureQueueNode; + SecureQueueNode* temp = input.m_head; + while(temp) + { + write(&temp->m_buffer[temp->m_start], temp->m_end - temp->m_start); + temp = temp->m_next; + } + } + +/* +* Destroy this SecureQueue +*/ +void SecureQueue::destroy() + { + SecureQueueNode* temp = m_head; + while(temp) + { + SecureQueueNode* holder = temp->m_next; + delete temp; + temp = holder; + } + m_head = m_tail = nullptr; + } + +/* +* Copy a SecureQueue +*/ +SecureQueue& SecureQueue::operator=(const SecureQueue& input) + { + if(this == &input) + return *this; + + destroy(); + m_bytes_read = input.get_bytes_read(); + m_head = m_tail = new SecureQueueNode; + SecureQueueNode* temp = input.m_head; + while(temp) + { + write(&temp->m_buffer[temp->m_start], temp->m_end - temp->m_start); + temp = temp->m_next; + } + return (*this); + } + +/* +* Add some bytes to the queue +*/ +void SecureQueue::write(const uint8_t input[], size_t length) + { + if(!m_head) + m_head = m_tail = new SecureQueueNode; + while(length) + { + const size_t n = m_tail->write(input, length); + input += n; + length -= n; + if(length) + { + m_tail->m_next = new SecureQueueNode; + m_tail = m_tail->m_next; + } + } + } + +/* +* Read some bytes from the queue +*/ +size_t SecureQueue::read(uint8_t output[], size_t length) + { + size_t got = 0; + while(length && m_head) + { + const size_t n = m_head->read(output, length); + output += n; + got += n; + length -= n; + if(m_head->size() == 0) + { + SecureQueueNode* holder = m_head->m_next; + delete m_head; + m_head = holder; + } + } + m_bytes_read += got; + return got; + } + +/* +* Read data, but do not remove it from queue +*/ +size_t SecureQueue::peek(uint8_t output[], size_t length, size_t offset) const + { + SecureQueueNode* current = m_head; + + while(offset && current) + { + if(offset >= current->size()) + { + offset -= current->size(); + current = current->m_next; + } + else + break; + } + + size_t got = 0; + while(length && current) + { + const size_t n = current->peek(output, length, offset); + offset = 0; + output += n; + got += n; + length -= n; + current = current->m_next; + } + return got; + } + +/** +* Return how many bytes have been read so far. +*/ +size_t SecureQueue::get_bytes_read() const + { + return m_bytes_read; + } + +/* +* Return how many bytes the queue holds +*/ +size_t SecureQueue::size() const + { + SecureQueueNode* current = m_head; + size_t count = 0; + + while(current) + { + count += current->size(); + current = current->m_next; + } + return count; + } + +/* +* Test if the queue has any data in it +*/ +bool SecureQueue::end_of_data() const + { + return (size() == 0); + } + +bool SecureQueue::empty() const + { + return (size() == 0); + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/filters/secqueue.h b/src/libs/3rdparty/botan/src/lib/filters/secqueue.h new file mode 100644 index 0000000000..00616f5cf5 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/filters/secqueue.h @@ -0,0 +1,72 @@ +/* +* SecureQueue +* (C) 1999-2007 Jack Lloyd +* 2012 Markus Wanner +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_SECURE_QUEUE_H_ +#define BOTAN_SECURE_QUEUE_H_ + +#include +#include + +namespace Botan { + +/** +* A queue that knows how to zeroize itself +*/ +class BOTAN_PUBLIC_API(2,0) SecureQueue final : public Fanout_Filter, public DataSource + { + public: + std::string name() const override { return "Queue"; } + + void write(const uint8_t[], size_t) override; + + size_t read(uint8_t[], size_t) override; + size_t peek(uint8_t[], size_t, size_t = 0) const override; + size_t get_bytes_read() const override; + + bool end_of_data() const override; + + bool empty() const; + + bool check_available(size_t n) override { return n <= size(); } + + /** + * @return number of bytes available in the queue + */ + size_t size() const; + + bool attachable() override { return false; } + + /** + * SecureQueue assignment + * @param other the queue to copy + */ + SecureQueue& operator=(const SecureQueue& other); + + /** + * SecureQueue default constructor (creates empty queue) + */ + SecureQueue(); + + /** + * SecureQueue copy constructor + * @param other the queue to copy + */ + SecureQueue(const SecureQueue& other); + + ~SecureQueue() { destroy(); } + + private: + void destroy(); + size_t m_bytes_read; + class SecureQueueNode* m_head; + class SecureQueueNode* m_tail; + }; + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/filters/threaded_fork.cpp b/src/libs/3rdparty/botan/src/lib/filters/threaded_fork.cpp new file mode 100644 index 0000000000..35ea941095 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/filters/threaded_fork.cpp @@ -0,0 +1,153 @@ +/* +* Threaded Fork +* (C) 2013 Joel Low +* 2013 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include + +#if defined(BOTAN_HAS_THREAD_UTILS) + +#include +#include +#include + +namespace Botan { + +struct Threaded_Fork_Data + { + /* + * Semaphore for indicating that there is work to be done (or to + * quit) + */ + Semaphore m_input_ready_semaphore; + + /* + * Synchronises all threads to complete processing data in lock-step. + */ + Barrier m_input_complete_barrier; + + /* + * The work that needs to be done. This should be only when the threads + * are NOT running (i.e. before notifying the work condition, after + * the input_complete_barrier has reset.) + */ + const uint8_t* m_input = nullptr; + + /* + * The length of the work that needs to be done. + */ + size_t m_input_length = 0; + }; + +/* +* Threaded_Fork constructor +*/ +Threaded_Fork::Threaded_Fork(Filter* f1, Filter* f2, Filter* f3, Filter* f4) : + Fork(nullptr, static_cast(0)), + m_thread_data(new Threaded_Fork_Data) + { + Filter* filters[4] = { f1, f2, f3, f4 }; + set_next(filters, 4); + } + +/* +* Threaded_Fork constructor +*/ +Threaded_Fork::Threaded_Fork(Filter* filters[], size_t count) : + Fork(nullptr, static_cast(0)), + m_thread_data(new Threaded_Fork_Data) + { + set_next(filters, count); + } + +Threaded_Fork::~Threaded_Fork() + { + m_thread_data->m_input = nullptr; + m_thread_data->m_input_length = 0; + + m_thread_data->m_input_ready_semaphore.release(m_threads.size()); + + for(auto& thread : m_threads) + thread->join(); + } + +std::string Threaded_Fork::name() const + { + return "Threaded Fork"; + } + +void Threaded_Fork::set_next(Filter* f[], size_t n) + { + Fork::set_next(f, n); + n = m_next.size(); + + if(n < m_threads.size()) + m_threads.resize(n); + else + { + m_threads.reserve(n); + for(size_t i = m_threads.size(); i != n; ++i) + { + m_threads.push_back( + std::shared_ptr( + new std::thread( + std::bind(&Threaded_Fork::thread_entry, this, m_next[i])))); + } + } + } + +void Threaded_Fork::send(const uint8_t input[], size_t length) + { + if(m_write_queue.size()) + thread_delegate_work(m_write_queue.data(), m_write_queue.size()); + thread_delegate_work(input, length); + + bool nothing_attached = true; + for(size_t j = 0; j != total_ports(); ++j) + if(m_next[j]) + nothing_attached = false; + + if(nothing_attached) + m_write_queue += std::make_pair(input, length); + else + m_write_queue.clear(); + } + +void Threaded_Fork::thread_delegate_work(const uint8_t input[], size_t length) + { + //Set the data to do. + m_thread_data->m_input = input; + m_thread_data->m_input_length = length; + + //Let the workers start processing. + m_thread_data->m_input_complete_barrier.wait(total_ports() + 1); + m_thread_data->m_input_ready_semaphore.release(total_ports()); + + //Wait for all the filters to finish processing. + m_thread_data->m_input_complete_barrier.sync(); + + //Reset the thread data + m_thread_data->m_input = nullptr; + m_thread_data->m_input_length = 0; + } + +void Threaded_Fork::thread_entry(Filter* filter) + { + while(true) + { + m_thread_data->m_input_ready_semaphore.acquire(); + + if(!m_thread_data->m_input) + break; + + filter->write(m_thread_data->m_input, m_thread_data->m_input_length); + m_thread_data->m_input_complete_barrier.sync(); + } + } + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/hash/hash.cpp b/src/libs/3rdparty/botan/src/lib/hash/hash.cpp new file mode 100644 index 0000000000..e30d000802 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/hash/hash.cpp @@ -0,0 +1,361 @@ +/* +* Hash Functions +* (C) 2015 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include + +#if defined(BOTAN_HAS_ADLER32) + #include +#endif + +#if defined(BOTAN_HAS_CRC24) + #include +#endif + +#if defined(BOTAN_HAS_CRC32) + #include +#endif + +#if defined(BOTAN_HAS_GOST_34_11) + #include +#endif + +#if defined(BOTAN_HAS_KECCAK) + #include +#endif + +#if defined(BOTAN_HAS_MD4) + #include +#endif + +#if defined(BOTAN_HAS_MD5) + #include +#endif + +#if defined(BOTAN_HAS_RIPEMD_160) + #include +#endif + +#if defined(BOTAN_HAS_SHA1) + #include +#endif + +#if defined(BOTAN_HAS_SHA2_32) + #include +#endif + +#if defined(BOTAN_HAS_SHA2_64) + #include +#endif + +#if defined(BOTAN_HAS_SHA3) + #include +#endif + +#if defined(BOTAN_HAS_SHAKE) + #include +#endif + +#if defined(BOTAN_HAS_SKEIN_512) + #include +#endif + +#if defined(BOTAN_HAS_STREEBOG) + #include +#endif + +#if defined(BOTAN_HAS_SM3) + #include +#endif + +#if defined(BOTAN_HAS_TIGER) + #include +#endif + +#if defined(BOTAN_HAS_WHIRLPOOL) + #include +#endif + +#if defined(BOTAN_HAS_PARALLEL_HASH) + #include +#endif + +#if defined(BOTAN_HAS_COMB4P) + #include +#endif + +#if defined(BOTAN_HAS_BLAKE2B) + #include +#endif + +#if defined(BOTAN_HAS_BEARSSL) + #include +#endif + +#if defined(BOTAN_HAS_OPENSSL) + #include +#endif + +namespace Botan { + +std::unique_ptr HashFunction::create(const std::string& algo_spec, + const std::string& provider) + { +#if defined(BOTAN_HAS_OPENSSL) + if(provider.empty() || provider == "openssl") + { + if(auto hash = make_openssl_hash(algo_spec)) + return hash; + + if(!provider.empty()) + return nullptr; + } +#endif + +#if defined(BOTAN_HAS_BEARSSL) + if(provider.empty() || provider == "bearssl") + { + if(auto hash = make_bearssl_hash(algo_spec)) + return hash; + + if(!provider.empty()) + return nullptr; + } +#endif + + // TODO: CommonCrypto hashes + + if(provider.empty() == false && provider != "base") + return nullptr; // unknown provider + +#if defined(BOTAN_HAS_SHA1) + if(algo_spec == "SHA-160" || + algo_spec == "SHA-1" || + algo_spec == "SHA1") + { + return std::unique_ptr(new SHA_160); + } +#endif + +#if defined(BOTAN_HAS_SHA2_32) + if(algo_spec == "SHA-224") + { + return std::unique_ptr(new SHA_224); + } + + if(algo_spec == "SHA-256") + { + return std::unique_ptr(new SHA_256); + } +#endif + +#if defined(BOTAN_HAS_SHA2_64) + if(algo_spec == "SHA-384") + { + return std::unique_ptr(new SHA_384); + } + + if(algo_spec == "SHA-512") + { + return std::unique_ptr(new SHA_512); + } + + if(algo_spec == "SHA-512-256") + { + return std::unique_ptr(new SHA_512_256); + } +#endif + +#if defined(BOTAN_HAS_RIPEMD_160) + if(algo_spec == "RIPEMD-160") + { + return std::unique_ptr(new RIPEMD_160); + } +#endif + +#if defined(BOTAN_HAS_WHIRLPOOL) + if(algo_spec == "Whirlpool") + { + return std::unique_ptr(new Whirlpool); + } +#endif + +#if defined(BOTAN_HAS_MD5) + if(algo_spec == "MD5") + { + return std::unique_ptr(new MD5); + } +#endif + +#if defined(BOTAN_HAS_MD4) + if(algo_spec == "MD4") + { + return std::unique_ptr(new MD4); + } +#endif + +#if defined(BOTAN_HAS_GOST_34_11) + if(algo_spec == "GOST-R-34.11-94" || algo_spec == "GOST-34.11") + { + return std::unique_ptr(new GOST_34_11); + } +#endif + +#if defined(BOTAN_HAS_ADLER32) + if(algo_spec == "Adler32") + { + return std::unique_ptr(new Adler32); + } +#endif + +#if defined(BOTAN_HAS_CRC24) + if(algo_spec == "CRC24") + { + return std::unique_ptr(new CRC24); + } +#endif + +#if defined(BOTAN_HAS_CRC32) + if(algo_spec == "CRC32") + { + return std::unique_ptr(new CRC32); + } +#endif + + const SCAN_Name req(algo_spec); + +#if defined(BOTAN_HAS_TIGER) + if(req.algo_name() == "Tiger") + { + return std::unique_ptr( + new Tiger(req.arg_as_integer(0, 24), + req.arg_as_integer(1, 3))); + } +#endif + +#if defined(BOTAN_HAS_SKEIN_512) + if(req.algo_name() == "Skein-512") + { + return std::unique_ptr( + new Skein_512(req.arg_as_integer(0, 512), req.arg(1, ""))); + } +#endif + +#if defined(BOTAN_HAS_BLAKE2B) + if(req.algo_name() == "Blake2b") + { + return std::unique_ptr( + new Blake2b(req.arg_as_integer(0, 512))); + } +#endif + +#if defined(BOTAN_HAS_KECCAK) + if(req.algo_name() == "Keccak-1600") + { + return std::unique_ptr( + new Keccak_1600(req.arg_as_integer(0, 512))); + } +#endif + +#if defined(BOTAN_HAS_SHA3) + if(req.algo_name() == "SHA-3") + { + return std::unique_ptr( + new SHA_3(req.arg_as_integer(0, 512))); + } +#endif + +#if defined(BOTAN_HAS_SHAKE) + if(req.algo_name() == "SHAKE-128") + { + return std::unique_ptr(new SHAKE_128(req.arg_as_integer(0, 128))); + } + if(req.algo_name() == "SHAKE-256") + { + return std::unique_ptr(new SHAKE_256(req.arg_as_integer(0, 256))); + } +#endif + +#if defined(BOTAN_HAS_STREEBOG) + if(algo_spec == "Streebog-256") + { + return std::unique_ptr(new Streebog_256); + } + if(algo_spec == "Streebog-512") + { + return std::unique_ptr(new Streebog_512); + } +#endif + +#if defined(BOTAN_HAS_SM3) + if(algo_spec == "SM3") + { + return std::unique_ptr(new SM3); + } +#endif + +#if defined(BOTAN_HAS_WHIRLPOOL) + if(req.algo_name() == "Whirlpool") + { + return std::unique_ptr(new Whirlpool); + } +#endif + +#if defined(BOTAN_HAS_PARALLEL_HASH) + if(req.algo_name() == "Parallel") + { + std::vector> hashes; + + for(size_t i = 0; i != req.arg_count(); ++i) + { + auto h = HashFunction::create(req.arg(i)); + if(!h) + { + return nullptr; + } + hashes.push_back(std::move(h)); + } + + return std::unique_ptr(new Parallel(hashes)); + } +#endif + +#if defined(BOTAN_HAS_COMB4P) + if(req.algo_name() == "Comb4P" && req.arg_count() == 2) + { + std::unique_ptr h1(HashFunction::create(req.arg(0))); + std::unique_ptr h2(HashFunction::create(req.arg(1))); + + if(h1 && h2) + return std::unique_ptr(new Comb4P(h1.release(), h2.release())); + } +#endif + + + return nullptr; + } + +//static +std::unique_ptr +HashFunction::create_or_throw(const std::string& algo, + const std::string& provider) + { + if(auto hash = HashFunction::create(algo, provider)) + { + return hash; + } + throw Lookup_Error("Hash", algo, provider); + } + +std::vector HashFunction::providers(const std::string& algo_spec) + { + return probe_providers_of(algo_spec, {"base", "bearssl", "openssl"}); + } + +} + diff --git a/src/libs/3rdparty/botan/src/lib/hash/hash.h b/src/libs/3rdparty/botan/src/lib/hash/hash.h new file mode 100644 index 0000000000..8c6440e650 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/hash/hash.h @@ -0,0 +1,91 @@ +/* +* Hash Function Base Class +* (C) 1999-2008 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_HASH_FUNCTION_BASE_CLASS_H_ +#define BOTAN_HASH_FUNCTION_BASE_CLASS_H_ + +#include +#include +#include + +namespace Botan { + +/** +* This class represents hash function (message digest) objects +*/ +class BOTAN_PUBLIC_API(2,0) HashFunction : public Buffered_Computation + { + public: + /** + * Create an instance based on a name, or return null if the + * algo/provider combination cannot be found. If provider is + * empty then best available is chosen. + */ + static std::unique_ptr + create(const std::string& algo_spec, + const std::string& provider = ""); + + /** + * 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 use + * Throws Lookup_Error if not found. + */ + static std::unique_ptr + create_or_throw(const std::string& algo_spec, + const std::string& provider = ""); + + /** + * @return list of available providers for this algorithm, empty if not available + * @param algo_spec algorithm name + */ + static std::vector providers(const std::string& algo_spec); + + /** + * @return new object representing the same algorithm as *this + */ + virtual HashFunction* clone() const = 0; + + /** + * @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"; } + + virtual ~HashFunction() = default; + + /** + * Reset the state. + */ + virtual void clear() = 0; + + /** + * @return the hash function name + */ + virtual std::string name() const = 0; + + /** + * @return hash block size as defined for this algorithm + */ + virtual size_t hash_block_size() const { return 0; } + + /** + * Return a new hash object with the same state as *this. This + * allows computing the hash of several messages with a common + * prefix more efficiently than would otherwise be possible. + * + * This function should be called `clone` but that was already + * used for the case of returning an uninitialized object. + * @return new hash object + */ + virtual std::unique_ptr copy_state() const = 0; + }; + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/hash/info.txt b/src/libs/3rdparty/botan/src/lib/hash/info.txt new file mode 100644 index 0000000000..8d38170589 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/hash/info.txt @@ -0,0 +1,7 @@ + +HASH -> 20180112 + + + +hash.h + diff --git a/src/libs/3rdparty/botan/src/lib/hash/mdx_hash/info.txt b/src/libs/3rdparty/botan/src/lib/hash/mdx_hash/info.txt new file mode 100644 index 0000000000..6a509f1be9 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/hash/mdx_hash/info.txt @@ -0,0 +1,5 @@ + +MDX_HASH_FUNCTION -> 20131128 + + +load_on dep diff --git a/src/libs/3rdparty/botan/src/lib/hash/mdx_hash/mdx_hash.cpp b/src/libs/3rdparty/botan/src/lib/hash/mdx_hash/mdx_hash.cpp new file mode 100644 index 0000000000..7d163dbfb0 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/hash/mdx_hash/mdx_hash.cpp @@ -0,0 +1,108 @@ +/* +* Merkle-Damgard Hash Function +* (C) 1999-2008 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include + +namespace Botan { + +/* +* MDx_HashFunction Constructor +*/ +MDx_HashFunction::MDx_HashFunction(size_t block_len, + bool byte_end, + bool bit_end, + size_t cnt_size) : + m_buffer(block_len), + m_count(0), + m_position(0), + BIG_BYTE_ENDIAN(byte_end), + BIG_BIT_ENDIAN(bit_end), + COUNT_SIZE(cnt_size) + { + } + +/* +* Clear memory of sensitive data +*/ +void MDx_HashFunction::clear() + { + zeroise(m_buffer); + m_count = m_position = 0; + } + +/* +* Update the hash +*/ +void MDx_HashFunction::add_data(const uint8_t input[], size_t length) + { + m_count += length; + + if(m_position) + { + buffer_insert(m_buffer, m_position, input, length); + + if(m_position + length >= m_buffer.size()) + { + compress_n(m_buffer.data(), 1); + input += (m_buffer.size() - m_position); + length -= (m_buffer.size() - m_position); + m_position = 0; + } + } + + const size_t full_blocks = length / m_buffer.size(); + const size_t remaining = length % m_buffer.size(); + + if(full_blocks) + compress_n(input, full_blocks); + + buffer_insert(m_buffer, m_position, input + full_blocks * m_buffer.size(), remaining); + m_position += remaining; + } + +/* +* Finalize a hash +*/ +void MDx_HashFunction::final_result(uint8_t output[]) + { + clear_mem(&m_buffer[m_position], m_buffer.size() - m_position); + m_buffer[m_position] = (BIG_BIT_ENDIAN ? 0x80 : 0x01); + + if(m_position >= m_buffer.size() - COUNT_SIZE) + { + compress_n(m_buffer.data(), 1); + zeroise(m_buffer); + } + + write_count(&m_buffer[m_buffer.size() - COUNT_SIZE]); + + compress_n(m_buffer.data(), 1); + copy_out(output); + clear(); + } + +/* +* Write the count bits to the buffer +*/ +void MDx_HashFunction::write_count(uint8_t out[]) + { + if(COUNT_SIZE < 8) + throw Invalid_State("MDx_HashFunction::write_count: COUNT_SIZE < 8"); + if(COUNT_SIZE >= output_length() || COUNT_SIZE >= hash_block_size()) + throw Invalid_Argument("MDx_HashFunction: COUNT_SIZE is too big"); + + const uint64_t bit_count = m_count * 8; + + if(BIG_BYTE_ENDIAN) + store_be(bit_count, out + COUNT_SIZE - 8); + else + store_le(bit_count, out + COUNT_SIZE - 8); + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/hash/mdx_hash/mdx_hash.h b/src/libs/3rdparty/botan/src/lib/hash/mdx_hash/mdx_hash.h new file mode 100644 index 0000000000..f958e9fb75 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/hash/mdx_hash/mdx_hash.h @@ -0,0 +1,68 @@ +/* +* MDx Hash Function +* (C) 1999-2008 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_MDX_BASE_H_ +#define BOTAN_MDX_BASE_H_ + +#include + +namespace Botan { + +/** +* MDx Hash Function Base Class +*/ +class BOTAN_PUBLIC_API(2,0) MDx_HashFunction : public HashFunction + { + public: + /** + * @param block_length is the number of bytes per block + * @param big_byte_endian specifies if the hash uses big-endian bytes + * @param big_bit_endian specifies if the hash uses big-endian bits + * @param counter_size specifies the size of the counter var in bytes + */ + MDx_HashFunction(size_t block_length, + bool big_byte_endian, + bool big_bit_endian, + size_t counter_size = 8); + + size_t hash_block_size() const override final { return m_buffer.size(); } + protected: + void add_data(const uint8_t input[], size_t length) override final; + void final_result(uint8_t output[]) override final; + + /** + * Run the hash's compression function over a set of blocks + * @param blocks the input + * @param block_n the number of blocks + */ + virtual void compress_n(const uint8_t blocks[], size_t block_n) = 0; + + void clear() override; + + /** + * Copy the output to the buffer + * @param buffer to put the output into + */ + virtual void copy_out(uint8_t buffer[]) = 0; + + /** + * Write the count, if used, to this spot + * @param out where to write the counter to + */ + virtual void write_count(uint8_t out[]); + private: + secure_vector m_buffer; + uint64_t m_count; + size_t m_position; + + const bool BIG_BYTE_ENDIAN, BIG_BIT_ENDIAN; + const size_t COUNT_SIZE; + }; + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/hash/sha1/info.txt b/src/libs/3rdparty/botan/src/lib/hash/sha1/info.txt new file mode 100644 index 0000000000..6d326af1c9 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/hash/sha1/info.txt @@ -0,0 +1,7 @@ + +SHA1 -> 20131128 + + + +mdx_hash + diff --git a/src/libs/3rdparty/botan/src/lib/hash/sha1/sha160.cpp b/src/libs/3rdparty/botan/src/lib/hash/sha1/sha160.cpp new file mode 100644 index 0000000000..8c12a4f042 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/hash/sha1/sha160.cpp @@ -0,0 +1,188 @@ +/* +* SHA-160 +* (C) 1999-2008,2011 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include + +namespace Botan { + +std::unique_ptr SHA_160::copy_state() const + { + return std::unique_ptr(new SHA_160(*this)); + } + +namespace SHA1_F { + +namespace { + +/* +* SHA-160 F1 Function +*/ +inline void F1(uint32_t A, uint32_t& B, uint32_t C, uint32_t D, uint32_t& E, uint32_t msg) + { + E += (D ^ (B & (C ^ D))) + msg + 0x5A827999 + rotl<5>(A); + B = rotl<30>(B); + } + +/* +* SHA-160 F2 Function +*/ +inline void F2(uint32_t A, uint32_t& B, uint32_t C, uint32_t D, uint32_t& E, uint32_t msg) + { + E += (B ^ C ^ D) + msg + 0x6ED9EBA1 + rotl<5>(A); + B = rotl<30>(B); + } + +/* +* SHA-160 F3 Function +*/ +inline void F3(uint32_t A, uint32_t& B, uint32_t C, uint32_t D, uint32_t& E, uint32_t msg) + { + E += ((B & C) | ((B | C) & D)) + msg + 0x8F1BBCDC + rotl<5>(A); + B = rotl<30>(B); + } + +/* +* SHA-160 F4 Function +*/ +inline void F4(uint32_t A, uint32_t& B, uint32_t C, uint32_t D, uint32_t& E, uint32_t msg) + { + E += (B ^ C ^ D) + msg + 0xCA62C1D6 + rotl<5>(A); + B = rotl<30>(B); + } + +} + +} + +/* +* SHA-160 Compression Function +*/ +void SHA_160::compress_n(const uint8_t input[], size_t blocks) + { + using namespace SHA1_F; + +#if defined(BOTAN_HAS_SHA1_X86_SHA_NI) + if(CPUID::has_intel_sha()) + { + return sha1_compress_x86(m_digest, input, blocks); + } +#endif + +#if defined(BOTAN_HAS_SHA1_ARMV8) + if(CPUID::has_arm_sha1()) + { + return sha1_armv8_compress_n(m_digest, input, blocks); + } +#endif + +#if defined(BOTAN_HAS_SHA1_SSE2) + if(CPUID::has_sse2()) + { + return sse2_compress_n(m_digest, input, blocks); + } + +#endif + + uint32_t A = m_digest[0], B = m_digest[1], C = m_digest[2], + D = m_digest[3], E = m_digest[4]; + + m_W.resize(80); + + for(size_t i = 0; i != blocks; ++i) + { + load_be(m_W.data(), input, 16); + + for(size_t j = 16; j != 80; j += 8) + { + m_W[j ] = rotl<1>(m_W[j-3] ^ m_W[j-8] ^ m_W[j-14] ^ m_W[j-16]); + m_W[j+1] = rotl<1>(m_W[j-2] ^ m_W[j-7] ^ m_W[j-13] ^ m_W[j-15]); + m_W[j+2] = rotl<1>(m_W[j-1] ^ m_W[j-6] ^ m_W[j-12] ^ m_W[j-14]); + m_W[j+3] = rotl<1>(m_W[j ] ^ m_W[j-5] ^ m_W[j-11] ^ m_W[j-13]); + m_W[j+4] = rotl<1>(m_W[j+1] ^ m_W[j-4] ^ m_W[j-10] ^ m_W[j-12]); + m_W[j+5] = rotl<1>(m_W[j+2] ^ m_W[j-3] ^ m_W[j- 9] ^ m_W[j-11]); + m_W[j+6] = rotl<1>(m_W[j+3] ^ m_W[j-2] ^ m_W[j- 8] ^ m_W[j-10]); + m_W[j+7] = rotl<1>(m_W[j+4] ^ m_W[j-1] ^ m_W[j- 7] ^ m_W[j- 9]); + } + + F1(A, B, C, D, E, m_W[ 0]); F1(E, A, B, C, D, m_W[ 1]); + F1(D, E, A, B, C, m_W[ 2]); F1(C, D, E, A, B, m_W[ 3]); + F1(B, C, D, E, A, m_W[ 4]); F1(A, B, C, D, E, m_W[ 5]); + F1(E, A, B, C, D, m_W[ 6]); F1(D, E, A, B, C, m_W[ 7]); + F1(C, D, E, A, B, m_W[ 8]); F1(B, C, D, E, A, m_W[ 9]); + F1(A, B, C, D, E, m_W[10]); F1(E, A, B, C, D, m_W[11]); + F1(D, E, A, B, C, m_W[12]); F1(C, D, E, A, B, m_W[13]); + F1(B, C, D, E, A, m_W[14]); F1(A, B, C, D, E, m_W[15]); + F1(E, A, B, C, D, m_W[16]); F1(D, E, A, B, C, m_W[17]); + F1(C, D, E, A, B, m_W[18]); F1(B, C, D, E, A, m_W[19]); + + F2(A, B, C, D, E, m_W[20]); F2(E, A, B, C, D, m_W[21]); + F2(D, E, A, B, C, m_W[22]); F2(C, D, E, A, B, m_W[23]); + F2(B, C, D, E, A, m_W[24]); F2(A, B, C, D, E, m_W[25]); + F2(E, A, B, C, D, m_W[26]); F2(D, E, A, B, C, m_W[27]); + F2(C, D, E, A, B, m_W[28]); F2(B, C, D, E, A, m_W[29]); + F2(A, B, C, D, E, m_W[30]); F2(E, A, B, C, D, m_W[31]); + F2(D, E, A, B, C, m_W[32]); F2(C, D, E, A, B, m_W[33]); + F2(B, C, D, E, A, m_W[34]); F2(A, B, C, D, E, m_W[35]); + F2(E, A, B, C, D, m_W[36]); F2(D, E, A, B, C, m_W[37]); + F2(C, D, E, A, B, m_W[38]); F2(B, C, D, E, A, m_W[39]); + + F3(A, B, C, D, E, m_W[40]); F3(E, A, B, C, D, m_W[41]); + F3(D, E, A, B, C, m_W[42]); F3(C, D, E, A, B, m_W[43]); + F3(B, C, D, E, A, m_W[44]); F3(A, B, C, D, E, m_W[45]); + F3(E, A, B, C, D, m_W[46]); F3(D, E, A, B, C, m_W[47]); + F3(C, D, E, A, B, m_W[48]); F3(B, C, D, E, A, m_W[49]); + F3(A, B, C, D, E, m_W[50]); F3(E, A, B, C, D, m_W[51]); + F3(D, E, A, B, C, m_W[52]); F3(C, D, E, A, B, m_W[53]); + F3(B, C, D, E, A, m_W[54]); F3(A, B, C, D, E, m_W[55]); + F3(E, A, B, C, D, m_W[56]); F3(D, E, A, B, C, m_W[57]); + F3(C, D, E, A, B, m_W[58]); F3(B, C, D, E, A, m_W[59]); + + F4(A, B, C, D, E, m_W[60]); F4(E, A, B, C, D, m_W[61]); + F4(D, E, A, B, C, m_W[62]); F4(C, D, E, A, B, m_W[63]); + F4(B, C, D, E, A, m_W[64]); F4(A, B, C, D, E, m_W[65]); + F4(E, A, B, C, D, m_W[66]); F4(D, E, A, B, C, m_W[67]); + F4(C, D, E, A, B, m_W[68]); F4(B, C, D, E, A, m_W[69]); + F4(A, B, C, D, E, m_W[70]); F4(E, A, B, C, D, m_W[71]); + F4(D, E, A, B, C, m_W[72]); F4(C, D, E, A, B, m_W[73]); + F4(B, C, D, E, A, m_W[74]); F4(A, B, C, D, E, m_W[75]); + F4(E, A, B, C, D, m_W[76]); F4(D, E, A, B, C, m_W[77]); + F4(C, D, E, A, B, m_W[78]); F4(B, C, D, E, A, m_W[79]); + + A = (m_digest[0] += A); + B = (m_digest[1] += B); + C = (m_digest[2] += C); + D = (m_digest[3] += D); + E = (m_digest[4] += E); + + input += hash_block_size(); + } + } + +/* +* Copy out the digest +*/ +void SHA_160::copy_out(uint8_t output[]) + { + copy_out_vec_be(output, output_length(), m_digest); + } + +/* +* Clear memory of sensitive data +*/ +void SHA_160::clear() + { + MDx_HashFunction::clear(); + zeroise(m_W); + m_digest[0] = 0x67452301; + m_digest[1] = 0xEFCDAB89; + m_digest[2] = 0x98BADCFE; + m_digest[3] = 0x10325476; + m_digest[4] = 0xC3D2E1F0; + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/hash/sha1/sha160.h b/src/libs/3rdparty/botan/src/lib/hash/sha1/sha160.h new file mode 100644 index 0000000000..9f7035ee63 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/hash/sha1/sha160.h @@ -0,0 +1,73 @@ +/* +* SHA-160 +* (C) 1999-2007,2016 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_SHA_160_H_ +#define BOTAN_SHA_160_H_ + +#include + +namespace Botan { + +/** +* NIST's SHA-160 +*/ +class BOTAN_PUBLIC_API(2,0) SHA_160 final : public MDx_HashFunction + { + public: + std::string name() const override { return "SHA-160"; } + size_t output_length() const override { return 20; } + HashFunction* clone() const override { return new SHA_160; } + std::unique_ptr copy_state() const override; + + void clear() override; + + SHA_160() : MDx_HashFunction(64, true, true), m_digest(5) + { + clear(); + } + + private: + void compress_n(const uint8_t[], size_t blocks) override; + +#if defined(BOTAN_HAS_SHA1_ARMV8) + static void sha1_armv8_compress_n(secure_vector& digest, + const uint8_t blocks[], + size_t block_count); +#endif + +#if defined(BOTAN_HAS_SHA1_SSE2) + static void sse2_compress_n(secure_vector& digest, + const uint8_t blocks[], + size_t block_count); +#endif + +#if defined(BOTAN_HAS_SHA1_X86_SHA_NI) + // Using x86 SHA instructions in Intel Goldmont and Cannonlake + static void sha1_compress_x86(secure_vector& digest, + const uint8_t blocks[], + size_t block_count); +#endif + + + void copy_out(uint8_t[]) override; + + /** + * The digest value + */ + secure_vector m_digest; + + /** + * The message buffer + */ + secure_vector m_W; + }; + +typedef SHA_160 SHA_1; + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/hash/sha1/sha1_armv8/info.txt b/src/libs/3rdparty/botan/src/lib/hash/sha1/sha1_armv8/info.txt new file mode 100644 index 0000000000..405ac412c4 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/hash/sha1/sha1_armv8/info.txt @@ -0,0 +1,10 @@ + +SHA1_ARMV8 -> 20170117 + + +need_isa armv8crypto + + +gcc:4.9 +clang:3.8 + 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 new file mode 100644 index 0000000000..9da48c9fec --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/hash/sha1/sha1_armv8/sha1_armv8.cpp @@ -0,0 +1,207 @@ +/* +* SHA-1 using CPU instructions in ARMv8 +* +* Contributed by Jeffrey Walton. Based on public domain code by +* Johannes Schneiders, Skip Hovsmith and Barry O'Rourke. +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include + +namespace Botan { + +/* +* SHA-1 using CPU instructions in ARMv8 +*/ +//static +#if defined(BOTAN_HAS_SHA1_ARMV8) +BOTAN_FUNC_ISA("+crypto") +void SHA_160::sha1_armv8_compress_n(secure_vector& 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; + + // Load initial values + C0 = vdupq_n_u32(0x5A827999); + C1 = vdupq_n_u32(0x6ED9EBA1); + C2 = vdupq_n_u32(0x8F1BBCDC); + C3 = vdupq_n_u32(0xCA62C1D6); + + ABCD = vld1q_u32(&digest[0]); + E0 = digest[4]; + + // Intermediate void* cast due to https://llvm.org/bugs/show_bug.cgi?id=20670 + const uint32_t* input32 = reinterpret_cast(reinterpret_cast(input8)); + + while (blocks) + { + uint32x4_t MSG0, MSG1, MSG2, MSG3; + uint32x4_t TMP0, TMP1; + + // Save current hash + ABCD_SAVED = ABCD; + E0_SAVED = E0; + + MSG0 = vld1q_u32(input32 + 0); + MSG1 = vld1q_u32(input32 + 4); + MSG2 = vld1q_u32(input32 + 8); + MSG3 = vld1q_u32(input32 + 12); + + MSG0 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(MSG0))); + MSG1 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(MSG1))); + MSG2 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(MSG2))); + MSG3 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(MSG3))); + + TMP0 = vaddq_u32(MSG0, C0); + TMP1 = vaddq_u32(MSG1, C0); + + // Rounds 0-3 + E1 = vsha1h_u32(vgetq_lane_u32(ABCD, 0)); + ABCD = vsha1cq_u32(ABCD, E0, TMP0); + TMP0 = vaddq_u32(MSG2, C0); + MSG0 = vsha1su0q_u32(MSG0, MSG1, MSG2); + + // Rounds 4-7 + E0 = vsha1h_u32(vgetq_lane_u32(ABCD, 0)); + ABCD = vsha1cq_u32(ABCD, E1, TMP1); + TMP1 = vaddq_u32(MSG3, C0); + MSG0 = vsha1su1q_u32(MSG0, MSG3); + MSG1 = vsha1su0q_u32(MSG1, MSG2, MSG3); + + // Rounds 8-11 + E1 = vsha1h_u32(vgetq_lane_u32(ABCD, 0)); + ABCD = vsha1cq_u32(ABCD, E0, TMP0); + TMP0 = vaddq_u32(MSG0, C0); + MSG1 = vsha1su1q_u32(MSG1, MSG0); + MSG2 = vsha1su0q_u32(MSG2, MSG3, MSG0); + + // Rounds 12-15 + E0 = vsha1h_u32(vgetq_lane_u32(ABCD, 0)); + ABCD = vsha1cq_u32(ABCD, E1, TMP1); + TMP1 = vaddq_u32(MSG1, C1); + MSG2 = vsha1su1q_u32(MSG2, MSG1); + MSG3 = vsha1su0q_u32(MSG3, MSG0, MSG1); + + // Rounds 16-19 + E1 = vsha1h_u32(vgetq_lane_u32(ABCD, 0)); + ABCD = vsha1cq_u32(ABCD, E0, TMP0); + TMP0 = vaddq_u32(MSG2, C1); + MSG3 = vsha1su1q_u32(MSG3, MSG2); + MSG0 = vsha1su0q_u32(MSG0, MSG1, MSG2); + + // Rounds 20-23 + E0 = vsha1h_u32(vgetq_lane_u32(ABCD, 0)); + ABCD = vsha1pq_u32(ABCD, E1, TMP1); + TMP1 = vaddq_u32(MSG3, C1); + MSG0 = vsha1su1q_u32(MSG0, MSG3); + MSG1 = vsha1su0q_u32(MSG1, MSG2, MSG3); + + // Rounds 24-27 + E1 = vsha1h_u32(vgetq_lane_u32(ABCD, 0)); + ABCD = vsha1pq_u32(ABCD, E0, TMP0); + TMP0 = vaddq_u32(MSG0, C1); + MSG1 = vsha1su1q_u32(MSG1, MSG0); + MSG2 = vsha1su0q_u32(MSG2, MSG3, MSG0); + + // Rounds 28-31 + E0 = vsha1h_u32(vgetq_lane_u32(ABCD, 0)); + ABCD = vsha1pq_u32(ABCD, E1, TMP1); + TMP1 = vaddq_u32(MSG1, C1); + MSG2 = vsha1su1q_u32(MSG2, MSG1); + MSG3 = vsha1su0q_u32(MSG3, MSG0, MSG1); + + // Rounds 32-35 + E1 = vsha1h_u32(vgetq_lane_u32(ABCD, 0)); + ABCD = vsha1pq_u32(ABCD, E0, TMP0); + TMP0 = vaddq_u32(MSG2, C2); + MSG3 = vsha1su1q_u32(MSG3, MSG2); + MSG0 = vsha1su0q_u32(MSG0, MSG1, MSG2); + + // Rounds 36-39 + E0 = vsha1h_u32(vgetq_lane_u32(ABCD, 0)); + ABCD = vsha1pq_u32(ABCD, E1, TMP1); + TMP1 = vaddq_u32(MSG3, C2); + MSG0 = vsha1su1q_u32(MSG0, MSG3); + MSG1 = vsha1su0q_u32(MSG1, MSG2, MSG3); + + // Rounds 40-43 + E1 = vsha1h_u32(vgetq_lane_u32(ABCD, 0)); + ABCD = vsha1mq_u32(ABCD, E0, TMP0); + TMP0 = vaddq_u32(MSG0, C2); + MSG1 = vsha1su1q_u32(MSG1, MSG0); + MSG2 = vsha1su0q_u32(MSG2, MSG3, MSG0); + + // Rounds 44-47 + E0 = vsha1h_u32(vgetq_lane_u32(ABCD, 0)); + ABCD = vsha1mq_u32(ABCD, E1, TMP1); + TMP1 = vaddq_u32(MSG1, C2); + MSG2 = vsha1su1q_u32(MSG2, MSG1); + MSG3 = vsha1su0q_u32(MSG3, MSG0, MSG1); + + // Rounds 48-51 + E1 = vsha1h_u32(vgetq_lane_u32(ABCD, 0)); + ABCD = vsha1mq_u32(ABCD, E0, TMP0); + TMP0 = vaddq_u32(MSG2, C2); + MSG3 = vsha1su1q_u32(MSG3, MSG2); + MSG0 = vsha1su0q_u32(MSG0, MSG1, MSG2); + + // Rounds 52-55 + E0 = vsha1h_u32(vgetq_lane_u32(ABCD, 0)); + ABCD = vsha1mq_u32(ABCD, E1, TMP1); + TMP1 = vaddq_u32(MSG3, C3); + MSG0 = vsha1su1q_u32(MSG0, MSG3); + MSG1 = vsha1su0q_u32(MSG1, MSG2, MSG3); + + // Rounds 56-59 + E1 = vsha1h_u32(vgetq_lane_u32(ABCD, 0)); + ABCD = vsha1mq_u32(ABCD, E0, TMP0); + TMP0 = vaddq_u32(MSG0, C3); + MSG1 = vsha1su1q_u32(MSG1, MSG0); + MSG2 = vsha1su0q_u32(MSG2, MSG3, MSG0); + + // Rounds 60-63 + E0 = vsha1h_u32(vgetq_lane_u32(ABCD, 0)); + ABCD = vsha1pq_u32(ABCD, E1, TMP1); + TMP1 = vaddq_u32(MSG1, C3); + MSG2 = vsha1su1q_u32(MSG2, MSG1); + MSG3 = vsha1su0q_u32(MSG3, MSG0, MSG1); + + // Rounds 64-67 + E1 = vsha1h_u32(vgetq_lane_u32(ABCD, 0)); + ABCD = vsha1pq_u32(ABCD, E0, TMP0); + TMP0 = vaddq_u32(MSG2, C3); + MSG3 = vsha1su1q_u32(MSG3, MSG2); + MSG0 = vsha1su0q_u32(MSG0, MSG1, MSG2); + + // Rounds 68-71 + E0 = vsha1h_u32(vgetq_lane_u32(ABCD, 0)); + ABCD = vsha1pq_u32(ABCD, E1, TMP1); + TMP1 = vaddq_u32(MSG3, C3); + MSG0 = vsha1su1q_u32(MSG0, MSG3); + + // Rounds 72-75 + E1 = vsha1h_u32(vgetq_lane_u32(ABCD, 0)); + ABCD = vsha1pq_u32(ABCD, E0, TMP0); + + // Rounds 76-79 + E0 = vsha1h_u32(vgetq_lane_u32(ABCD, 0)); + ABCD = vsha1pq_u32(ABCD, E1, TMP1); + + // Add state back + E0 += E0_SAVED; + ABCD = vaddq_u32(ABCD_SAVED, ABCD); + + input32 += 64/4; + blocks--; + } + + // Save digest + vst1q_u32(&digest[0], ABCD); + digest[4] = E0; + } +#endif + +} diff --git a/src/libs/3rdparty/botan/src/lib/hash/sha1/sha1_sse2/info.txt b/src/libs/3rdparty/botan/src/lib/hash/sha1/sha1_sse2/info.txt new file mode 100644 index 0000000000..272bf5e8d4 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/hash/sha1/sha1_sse2/info.txt @@ -0,0 +1,5 @@ + +SHA1_SSE2 -> 20160803 + + +need_isa sse2 diff --git a/src/libs/3rdparty/botan/src/lib/hash/sha1/sha1_sse2/sha1_sse2.cpp b/src/libs/3rdparty/botan/src/lib/hash/sha1/sha1_sse2/sha1_sse2.cpp new file mode 100644 index 0000000000..88e5a0d2c7 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/hash/sha1/sha1_sse2/sha1_sse2.cpp @@ -0,0 +1,335 @@ +/* +* SHA-1 using SSE2 +* Based on public domain code by Dean Gaudet +* (http://arctic.org/~dean/crypto/sha1.html) +* (C) 2009-2011 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include + +namespace Botan { + +namespace SHA1_SSE2_F { + +namespace { + +/* +* First 16 bytes just need byte swapping. Preparing just means +* adding in the round constants. +*/ + +#define prep00_15(P, W) \ + do { \ + W = _mm_shufflehi_epi16(W, _MM_SHUFFLE(2, 3, 0, 1)); \ + W = _mm_shufflelo_epi16(W, _MM_SHUFFLE(2, 3, 0, 1)); \ + W = _mm_or_si128(_mm_slli_epi16(W, 8), \ + _mm_srli_epi16(W, 8)); \ + P.u128 = _mm_add_epi32(W, K00_19); \ + } while(0) + +/* +For each multiple of 4, t, we want to calculate this: + +W[t+0] = rol(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16], 1); +W[t+1] = rol(W[t-2] ^ W[t-7] ^ W[t-13] ^ W[t-15], 1); +W[t+2] = rol(W[t-1] ^ W[t-6] ^ W[t-12] ^ W[t-14], 1); +W[t+3] = rol(W[t] ^ W[t-5] ^ W[t-11] ^ W[t-13], 1); + +we'll actually calculate this: + +W[t+0] = rol(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16], 1); +W[t+1] = rol(W[t-2] ^ W[t-7] ^ W[t-13] ^ W[t-15], 1); +W[t+2] = rol(W[t-1] ^ W[t-6] ^ W[t-12] ^ W[t-14], 1); +W[t+3] = rol( 0 ^ W[t-5] ^ W[t-11] ^ W[t-13], 1); +W[t+3] ^= rol(W[t+0], 1); + +the parameters are: + +W0 = &W[t-16]; +W1 = &W[t-12]; +W2 = &W[t- 8]; +W3 = &W[t- 4]; + +and on output: +prepared = W0 + K +W0 = W[t]..W[t+3] +*/ + +/* note that there is a step here where i want to do a rol by 1, which +* normally would look like this: +* +* r1 = psrld r0,$31 +* r0 = pslld r0,$1 +* r0 = por r0,r1 +* +* but instead i do this: +* +* r1 = pcmpltd r0,zero +* r0 = paddd r0,r0 +* r0 = psub r0,r1 +* +* because pcmpltd and paddd are available in both MMX units on +* efficeon, pentium-m, and opteron but shifts are available in +* only one unit. +*/ +#define prep(prep, XW0, XW1, XW2, XW3, K) \ + do { \ + __m128i r0, r1, r2, r3; \ + \ + /* load W[t-4] 16-byte aligned, and shift */ \ + r3 = _mm_srli_si128((XW3), 4); \ + r0 = (XW0); \ + /* get high 64-bits of XW0 into low 64-bits */ \ + r1 = _mm_shuffle_epi32((XW0), _MM_SHUFFLE(1,0,3,2)); \ + /* load high 64-bits of r1 */ \ + r1 = _mm_unpacklo_epi64(r1, (XW1)); \ + r2 = (XW2); \ + \ + r0 = _mm_xor_si128(r1, r0); \ + r2 = _mm_xor_si128(r3, r2); \ + r0 = _mm_xor_si128(r2, r0); \ + /* unrotated W[t]..W[t+2] in r0 ... still need W[t+3] */ \ + \ + r2 = _mm_slli_si128(r0, 12); \ + r1 = _mm_cmplt_epi32(r0, _mm_setzero_si128()); \ + r0 = _mm_add_epi32(r0, r0); /* shift left by 1 */ \ + r0 = _mm_sub_epi32(r0, r1); /* r0 has W[t]..W[t+2] */ \ + \ + r3 = _mm_srli_epi32(r2, 30); \ + r2 = _mm_slli_epi32(r2, 2); \ + \ + r0 = _mm_xor_si128(r0, r3); \ + r0 = _mm_xor_si128(r0, r2); /* r0 now has W[t+3] */ \ + \ + (XW0) = r0; \ + (prep).u128 = _mm_add_epi32(r0, K); \ + } while(0) + +/* +* SHA-160 F1 Function +*/ +inline void F1(uint32_t A, uint32_t& B, uint32_t C, uint32_t D, uint32_t& E, uint32_t msg) + { + E += (D ^ (B & (C ^ D))) + msg + rotl<5>(A); + B = rotl<30>(B); + } + +/* +* SHA-160 F2 Function +*/ +inline void F2(uint32_t A, uint32_t& B, uint32_t C, uint32_t D, uint32_t& E, uint32_t msg) + { + E += (B ^ C ^ D) + msg + rotl<5>(A); + B = rotl<30>(B); + } + +/* +* SHA-160 F3 Function +*/ +inline void F3(uint32_t A, uint32_t& B, uint32_t C, uint32_t D, uint32_t& E, uint32_t msg) + { + E += ((B & C) | ((B | C) & D)) + msg + rotl<5>(A); + B = rotl<30>(B); + } + +/* +* SHA-160 F4 Function +*/ +inline void F4(uint32_t A, uint32_t& B, uint32_t C, uint32_t D, uint32_t& E, uint32_t msg) + { + E += (B ^ C ^ D) + msg + rotl<5>(A); + B = rotl<30>(B); + } + +} + +} + +/* +* SHA-160 Compression Function using SSE for message expansion +*/ +//static +BOTAN_FUNC_ISA("sse2") +void SHA_160::sse2_compress_n(secure_vector& digest, const uint8_t input[], size_t blocks) + { + using namespace SHA1_SSE2_F; + + const __m128i K00_19 = _mm_set1_epi32(0x5A827999); + const __m128i K20_39 = _mm_set1_epi32(0x6ED9EBA1); + const __m128i K40_59 = _mm_set1_epi32(0x8F1BBCDC); + const __m128i K60_79 = _mm_set1_epi32(0xCA62C1D6); + + uint32_t A = digest[0], + B = digest[1], + C = digest[2], + D = digest[3], + E = digest[4]; + + const __m128i* input_mm = reinterpret_cast(input); + + for(size_t i = 0; i != blocks; ++i) + { + union v4si { + uint32_t u32[4]; + __m128i u128; + }; + + v4si P0, P1, P2, P3; + + __m128i W0 = _mm_loadu_si128(&input_mm[0]); + prep00_15(P0, W0); + + __m128i W1 = _mm_loadu_si128(&input_mm[1]); + prep00_15(P1, W1); + + __m128i W2 = _mm_loadu_si128(&input_mm[2]); + prep00_15(P2, W2); + + __m128i W3 = _mm_loadu_si128(&input_mm[3]); + prep00_15(P3, W3); + + /* + Using SSE4; slower on Core2 and Nehalem + #define GET_P_32(P, i) _mm_extract_epi32(P.u128, i) + + Much slower on all tested platforms + #define GET_P_32(P,i) _mm_cvtsi128_si32(_mm_srli_si128(P.u128, i*4)) + */ + +#define GET_P_32(P, i) P.u32[i] + + F1(A, B, C, D, E, GET_P_32(P0, 0)); + F1(E, A, B, C, D, GET_P_32(P0, 1)); + F1(D, E, A, B, C, GET_P_32(P0, 2)); + F1(C, D, E, A, B, GET_P_32(P0, 3)); + prep(P0, W0, W1, W2, W3, K00_19); + + F1(B, C, D, E, A, GET_P_32(P1, 0)); + F1(A, B, C, D, E, GET_P_32(P1, 1)); + F1(E, A, B, C, D, GET_P_32(P1, 2)); + F1(D, E, A, B, C, GET_P_32(P1, 3)); + prep(P1, W1, W2, W3, W0, K20_39); + + F1(C, D, E, A, B, GET_P_32(P2, 0)); + F1(B, C, D, E, A, GET_P_32(P2, 1)); + F1(A, B, C, D, E, GET_P_32(P2, 2)); + F1(E, A, B, C, D, GET_P_32(P2, 3)); + prep(P2, W2, W3, W0, W1, K20_39); + + F1(D, E, A, B, C, GET_P_32(P3, 0)); + F1(C, D, E, A, B, GET_P_32(P3, 1)); + F1(B, C, D, E, A, GET_P_32(P3, 2)); + F1(A, B, C, D, E, GET_P_32(P3, 3)); + prep(P3, W3, W0, W1, W2, K20_39); + + F1(E, A, B, C, D, GET_P_32(P0, 0)); + F1(D, E, A, B, C, GET_P_32(P0, 1)); + F1(C, D, E, A, B, GET_P_32(P0, 2)); + F1(B, C, D, E, A, GET_P_32(P0, 3)); + prep(P0, W0, W1, W2, W3, K20_39); + + F2(A, B, C, D, E, GET_P_32(P1, 0)); + F2(E, A, B, C, D, GET_P_32(P1, 1)); + F2(D, E, A, B, C, GET_P_32(P1, 2)); + F2(C, D, E, A, B, GET_P_32(P1, 3)); + prep(P1, W1, W2, W3, W0, K20_39); + + F2(B, C, D, E, A, GET_P_32(P2, 0)); + F2(A, B, C, D, E, GET_P_32(P2, 1)); + F2(E, A, B, C, D, GET_P_32(P2, 2)); + F2(D, E, A, B, C, GET_P_32(P2, 3)); + prep(P2, W2, W3, W0, W1, K40_59); + + F2(C, D, E, A, B, GET_P_32(P3, 0)); + F2(B, C, D, E, A, GET_P_32(P3, 1)); + F2(A, B, C, D, E, GET_P_32(P3, 2)); + F2(E, A, B, C, D, GET_P_32(P3, 3)); + prep(P3, W3, W0, W1, W2, K40_59); + + F2(D, E, A, B, C, GET_P_32(P0, 0)); + F2(C, D, E, A, B, GET_P_32(P0, 1)); + F2(B, C, D, E, A, GET_P_32(P0, 2)); + F2(A, B, C, D, E, GET_P_32(P0, 3)); + prep(P0, W0, W1, W2, W3, K40_59); + + F2(E, A, B, C, D, GET_P_32(P1, 0)); + F2(D, E, A, B, C, GET_P_32(P1, 1)); + F2(C, D, E, A, B, GET_P_32(P1, 2)); + F2(B, C, D, E, A, GET_P_32(P1, 3)); + prep(P1, W1, W2, W3, W0, K40_59); + + F3(A, B, C, D, E, GET_P_32(P2, 0)); + F3(E, A, B, C, D, GET_P_32(P2, 1)); + F3(D, E, A, B, C, GET_P_32(P2, 2)); + F3(C, D, E, A, B, GET_P_32(P2, 3)); + prep(P2, W2, W3, W0, W1, K40_59); + + F3(B, C, D, E, A, GET_P_32(P3, 0)); + F3(A, B, C, D, E, GET_P_32(P3, 1)); + F3(E, A, B, C, D, GET_P_32(P3, 2)); + F3(D, E, A, B, C, GET_P_32(P3, 3)); + prep(P3, W3, W0, W1, W2, K60_79); + + F3(C, D, E, A, B, GET_P_32(P0, 0)); + F3(B, C, D, E, A, GET_P_32(P0, 1)); + F3(A, B, C, D, E, GET_P_32(P0, 2)); + F3(E, A, B, C, D, GET_P_32(P0, 3)); + prep(P0, W0, W1, W2, W3, K60_79); + + F3(D, E, A, B, C, GET_P_32(P1, 0)); + F3(C, D, E, A, B, GET_P_32(P1, 1)); + F3(B, C, D, E, A, GET_P_32(P1, 2)); + F3(A, B, C, D, E, GET_P_32(P1, 3)); + prep(P1, W1, W2, W3, W0, K60_79); + + F3(E, A, B, C, D, GET_P_32(P2, 0)); + F3(D, E, A, B, C, GET_P_32(P2, 1)); + F3(C, D, E, A, B, GET_P_32(P2, 2)); + F3(B, C, D, E, A, GET_P_32(P2, 3)); + prep(P2, W2, W3, W0, W1, K60_79); + + F4(A, B, C, D, E, GET_P_32(P3, 0)); + F4(E, A, B, C, D, GET_P_32(P3, 1)); + F4(D, E, A, B, C, GET_P_32(P3, 2)); + F4(C, D, E, A, B, GET_P_32(P3, 3)); + prep(P3, W3, W0, W1, W2, K60_79); + + F4(B, C, D, E, A, GET_P_32(P0, 0)); + F4(A, B, C, D, E, GET_P_32(P0, 1)); + F4(E, A, B, C, D, GET_P_32(P0, 2)); + F4(D, E, A, B, C, GET_P_32(P0, 3)); + + F4(C, D, E, A, B, GET_P_32(P1, 0)); + F4(B, C, D, E, A, GET_P_32(P1, 1)); + F4(A, B, C, D, E, GET_P_32(P1, 2)); + F4(E, A, B, C, D, GET_P_32(P1, 3)); + + F4(D, E, A, B, C, GET_P_32(P2, 0)); + F4(C, D, E, A, B, GET_P_32(P2, 1)); + F4(B, C, D, E, A, GET_P_32(P2, 2)); + F4(A, B, C, D, E, GET_P_32(P2, 3)); + + F4(E, A, B, C, D, GET_P_32(P3, 0)); + F4(D, E, A, B, C, GET_P_32(P3, 1)); + F4(C, D, E, A, B, GET_P_32(P3, 2)); + F4(B, C, D, E, A, GET_P_32(P3, 3)); + + A = (digest[0] += A); + B = (digest[1] += B); + C = (digest[2] += C); + D = (digest[3] += D); + E = (digest[4] += E); + + input_mm += (64 / 16); + } + +#undef GET_P_32 + } + +#undef prep00_15 +#undef prep + +} diff --git a/src/libs/3rdparty/botan/src/lib/hash/sha1/sha1_x86/info.txt b/src/libs/3rdparty/botan/src/lib/hash/sha1/sha1_x86/info.txt new file mode 100644 index 0000000000..cfa1750c23 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/hash/sha1/sha1_x86/info.txt @@ -0,0 +1,11 @@ + +SHA1_X86_SHA_NI -> 20170518 + + +need_isa sha,ssse3,sse41 + + +clang:3.9 +gcc:5.0 +msvc:19.0 # MSVS 2015 + diff --git a/src/libs/3rdparty/botan/src/lib/hash/sha1/sha1_x86/sha1_x86.cpp b/src/libs/3rdparty/botan/src/lib/hash/sha1/sha1_x86/sha1_x86.cpp new file mode 100644 index 0000000000..76feebcea1 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/hash/sha1/sha1_x86/sha1_x86.cpp @@ -0,0 +1,216 @@ +/* +* SHA-1 using Intel SHA intrinsic +* +* Based on public domain code by Sean Gulley +* (https://github.com/mitls/hacl-star/tree/master/experimental/hash) +* Adapted to Botan by Jeffrey Walton. +* +* Further changes +* +* (C) 2017 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include + +namespace Botan { + +#if defined(BOTAN_HAS_SHA1_X86_SHA_NI) +BOTAN_FUNC_ISA("sha,ssse3,sse4.1") +void SHA_160::sha1_compress_x86(secure_vector& digest, + const uint8_t input[], + size_t blocks) + { + const __m128i MASK = _mm_set_epi64x(0x0001020304050607ULL, 0x08090a0b0c0d0e0fULL); + const __m128i* input_mm = reinterpret_cast(input); + + uint32_t* state = digest.data(); + + // Load initial values + __m128i ABCD = _mm_loadu_si128(reinterpret_cast<__m128i*>(state)); + __m128i E0 = _mm_set_epi32(state[4], 0, 0, 0); + ABCD = _mm_shuffle_epi32(ABCD, 0x1B); + + while (blocks) + { + // Save current hash + const __m128i ABCD_SAVE = ABCD; + const __m128i E0_SAVE = E0; + + __m128i MSG0, MSG1, MSG2, MSG3; + __m128i E1; + + // Rounds 0-3 + MSG0 = _mm_loadu_si128(input_mm+0); + MSG0 = _mm_shuffle_epi8(MSG0, MASK); + E0 = _mm_add_epi32(E0, MSG0); + E1 = ABCD; + ABCD = _mm_sha1rnds4_epu32(ABCD, E0, 0); + + // Rounds 4-7 + MSG1 = _mm_loadu_si128(input_mm+1); + MSG1 = _mm_shuffle_epi8(MSG1, MASK); + E1 = _mm_sha1nexte_epu32(E1, MSG1); + E0 = ABCD; + ABCD = _mm_sha1rnds4_epu32(ABCD, E1, 0); + MSG0 = _mm_sha1msg1_epu32(MSG0, MSG1); + + // Rounds 8-11 + MSG2 = _mm_loadu_si128(input_mm+2); + MSG2 = _mm_shuffle_epi8(MSG2, MASK); + E0 = _mm_sha1nexte_epu32(E0, MSG2); + E1 = ABCD; + ABCD = _mm_sha1rnds4_epu32(ABCD, E0, 0); + MSG1 = _mm_sha1msg1_epu32(MSG1, MSG2); + MSG0 = _mm_xor_si128(MSG0, MSG2); + + // Rounds 12-15 + MSG3 = _mm_loadu_si128(input_mm+3); + MSG3 = _mm_shuffle_epi8(MSG3, MASK); + E1 = _mm_sha1nexte_epu32(E1, MSG3); + E0 = ABCD; + MSG0 = _mm_sha1msg2_epu32(MSG0, MSG3); + ABCD = _mm_sha1rnds4_epu32(ABCD, E1, 0); + MSG2 = _mm_sha1msg1_epu32(MSG2, MSG3); + MSG1 = _mm_xor_si128(MSG1, MSG3); + + // Rounds 16-19 + E0 = _mm_sha1nexte_epu32(E0, MSG0); + E1 = ABCD; + MSG1 = _mm_sha1msg2_epu32(MSG1, MSG0); + ABCD = _mm_sha1rnds4_epu32(ABCD, E0, 0); + MSG3 = _mm_sha1msg1_epu32(MSG3, MSG0); + MSG2 = _mm_xor_si128(MSG2, MSG0); + + // Rounds 20-23 + E1 = _mm_sha1nexte_epu32(E1, MSG1); + E0 = ABCD; + MSG2 = _mm_sha1msg2_epu32(MSG2, MSG1); + ABCD = _mm_sha1rnds4_epu32(ABCD, E1, 1); + MSG0 = _mm_sha1msg1_epu32(MSG0, MSG1); + MSG3 = _mm_xor_si128(MSG3, MSG1); + + // Rounds 24-27 + E0 = _mm_sha1nexte_epu32(E0, MSG2); + E1 = ABCD; + MSG3 = _mm_sha1msg2_epu32(MSG3, MSG2); + ABCD = _mm_sha1rnds4_epu32(ABCD, E0, 1); + MSG1 = _mm_sha1msg1_epu32(MSG1, MSG2); + MSG0 = _mm_xor_si128(MSG0, MSG2); + + // Rounds 28-31 + E1 = _mm_sha1nexte_epu32(E1, MSG3); + E0 = ABCD; + MSG0 = _mm_sha1msg2_epu32(MSG0, MSG3); + ABCD = _mm_sha1rnds4_epu32(ABCD, E1, 1); + MSG2 = _mm_sha1msg1_epu32(MSG2, MSG3); + MSG1 = _mm_xor_si128(MSG1, MSG3); + + // Rounds 32-35 + E0 = _mm_sha1nexte_epu32(E0, MSG0); + E1 = ABCD; + MSG1 = _mm_sha1msg2_epu32(MSG1, MSG0); + ABCD = _mm_sha1rnds4_epu32(ABCD, E0, 1); + MSG3 = _mm_sha1msg1_epu32(MSG3, MSG0); + MSG2 = _mm_xor_si128(MSG2, MSG0); + + // Rounds 36-39 + E1 = _mm_sha1nexte_epu32(E1, MSG1); + E0 = ABCD; + MSG2 = _mm_sha1msg2_epu32(MSG2, MSG1); + ABCD = _mm_sha1rnds4_epu32(ABCD, E1, 1); + MSG0 = _mm_sha1msg1_epu32(MSG0, MSG1); + MSG3 = _mm_xor_si128(MSG3, MSG1); + + // Rounds 40-43 + E0 = _mm_sha1nexte_epu32(E0, MSG2); + E1 = ABCD; + MSG3 = _mm_sha1msg2_epu32(MSG3, MSG2); + ABCD = _mm_sha1rnds4_epu32(ABCD, E0, 2); + MSG1 = _mm_sha1msg1_epu32(MSG1, MSG2); + MSG0 = _mm_xor_si128(MSG0, MSG2); + + // Rounds 44-47 + E1 = _mm_sha1nexte_epu32(E1, MSG3); + E0 = ABCD; + MSG0 = _mm_sha1msg2_epu32(MSG0, MSG3); + ABCD = _mm_sha1rnds4_epu32(ABCD, E1, 2); + MSG2 = _mm_sha1msg1_epu32(MSG2, MSG3); + MSG1 = _mm_xor_si128(MSG1, MSG3); + + // Rounds 48-51 + E0 = _mm_sha1nexte_epu32(E0, MSG0); + E1 = ABCD; + MSG1 = _mm_sha1msg2_epu32(MSG1, MSG0); + ABCD = _mm_sha1rnds4_epu32(ABCD, E0, 2); + MSG3 = _mm_sha1msg1_epu32(MSG3, MSG0); + MSG2 = _mm_xor_si128(MSG2, MSG0); + + // Rounds 52-55 + E1 = _mm_sha1nexte_epu32(E1, MSG1); + E0 = ABCD; + MSG2 = _mm_sha1msg2_epu32(MSG2, MSG1); + ABCD = _mm_sha1rnds4_epu32(ABCD, E1, 2); + MSG0 = _mm_sha1msg1_epu32(MSG0, MSG1); + MSG3 = _mm_xor_si128(MSG3, MSG1); + + // Rounds 56-59 + E0 = _mm_sha1nexte_epu32(E0, MSG2); + E1 = ABCD; + MSG3 = _mm_sha1msg2_epu32(MSG3, MSG2); + ABCD = _mm_sha1rnds4_epu32(ABCD, E0, 2); + MSG1 = _mm_sha1msg1_epu32(MSG1, MSG2); + MSG0 = _mm_xor_si128(MSG0, MSG2); + + // Rounds 60-63 + E1 = _mm_sha1nexte_epu32(E1, MSG3); + E0 = ABCD; + MSG0 = _mm_sha1msg2_epu32(MSG0, MSG3); + ABCD = _mm_sha1rnds4_epu32(ABCD, E1, 3); + MSG2 = _mm_sha1msg1_epu32(MSG2, MSG3); + MSG1 = _mm_xor_si128(MSG1, MSG3); + + // Rounds 64-67 + E0 = _mm_sha1nexte_epu32(E0, MSG0); + E1 = ABCD; + MSG1 = _mm_sha1msg2_epu32(MSG1, MSG0); + ABCD = _mm_sha1rnds4_epu32(ABCD, E0, 3); + MSG3 = _mm_sha1msg1_epu32(MSG3, MSG0); + MSG2 = _mm_xor_si128(MSG2, MSG0); + + // Rounds 68-71 + E1 = _mm_sha1nexte_epu32(E1, MSG1); + E0 = ABCD; + MSG2 = _mm_sha1msg2_epu32(MSG2, MSG1); + ABCD = _mm_sha1rnds4_epu32(ABCD, E1, 3); + MSG3 = _mm_xor_si128(MSG3, MSG1); + + // Rounds 72-75 + E0 = _mm_sha1nexte_epu32(E0, MSG2); + E1 = ABCD; + MSG3 = _mm_sha1msg2_epu32(MSG3, MSG2); + ABCD = _mm_sha1rnds4_epu32(ABCD, E0, 3); + + // Rounds 76-79 + E1 = _mm_sha1nexte_epu32(E1, MSG3); + E0 = ABCD; + ABCD = _mm_sha1rnds4_epu32(ABCD, E1, 3); + + // Add values back to state + E0 = _mm_sha1nexte_epu32(E0, E0_SAVE); + ABCD = _mm_add_epi32(ABCD, ABCD_SAVE); + + input_mm += 4; + blocks--; + } + + // Save state + ABCD = _mm_shuffle_epi32(ABCD, 0x1B); + _mm_storeu_si128(reinterpret_cast<__m128i*>(state), ABCD); + state[4] = _mm_extract_epi32(E0, 3); + } +#endif + +} diff --git a/src/libs/3rdparty/botan/src/lib/hash/sha2_32/info.txt b/src/libs/3rdparty/botan/src/lib/hash/sha2_32/info.txt new file mode 100644 index 0000000000..7992eff261 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/hash/sha2_32/info.txt @@ -0,0 +1,7 @@ + +SHA2_32 -> 20131128 + + + +mdx_hash + diff --git a/src/libs/3rdparty/botan/src/lib/hash/sha2_32/sha2_32.cpp b/src/libs/3rdparty/botan/src/lib/hash/sha2_32/sha2_32.cpp new file mode 100644 index 0000000000..99cc2a6ffb --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/hash/sha2_32/sha2_32.cpp @@ -0,0 +1,236 @@ +/* +* SHA-{224,256} +* (C) 1999-2010,2017 Jack Lloyd +* 2007 FlexSecure GmbH +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include + +namespace Botan { + +std::unique_ptr SHA_224::copy_state() const + { + return std::unique_ptr(new SHA_224(*this)); + } + +std::unique_ptr SHA_256::copy_state() const + { + return std::unique_ptr(new SHA_256(*this)); + } + +/* +* SHA-256 F1 Function +* +* Use a macro as many compilers won't inline a function this big, +* even though it is much faster if inlined. +*/ +#define SHA2_32_F(A, B, C, D, E, F, G, H, M1, M2, M3, M4, magic) do { \ + uint32_t A_rho = rotr<2>(A) ^ rotr<13>(A) ^ rotr<22>(A); \ + uint32_t E_rho = rotr<6>(E) ^ rotr<11>(E) ^ rotr<25>(E); \ + uint32_t M2_sigma = rotr<17>(M2) ^ rotr<19>(M2) ^ (M2 >> 10); \ + uint32_t M4_sigma = rotr<7>(M4) ^ rotr<18>(M4) ^ (M4 >> 3); \ + H += magic + E_rho + ((E & F) ^ (~E & G)) + M1; \ + D += H; \ + H += A_rho + ((A & B) | ((A | B) & C)); \ + M1 += M2_sigma + M3 + M4_sigma; \ + } while(0); + +/* +* SHA-224 / SHA-256 compression function +*/ +void SHA_256::compress_digest(secure_vector& digest, + const uint8_t input[], size_t blocks) + { +#if defined(BOTAN_HAS_SHA2_32_X86) + if(CPUID::has_intel_sha()) + { + return SHA_256::compress_digest_x86(digest, input, blocks); + } +#endif + +#if defined(BOTAN_HAS_SHA2_32_X86_BMI2) + if(CPUID::has_bmi2()) + { + return SHA_256::compress_digest_x86_bmi2(digest, input, blocks); + } +#endif + +#if defined(BOTAN_HAS_SHA2_32_ARMV8) + if(CPUID::has_arm_sha2()) + { + return SHA_256::compress_digest_armv8(digest, input, blocks); + } +#endif + + uint32_t A = digest[0], B = digest[1], C = digest[2], + D = digest[3], E = digest[4], F = digest[5], + G = digest[6], H = digest[7]; + + for(size_t i = 0; i != blocks; ++i) + { + uint32_t W00 = load_be(input, 0); + uint32_t W01 = load_be(input, 1); + uint32_t W02 = load_be(input, 2); + uint32_t W03 = load_be(input, 3); + uint32_t W04 = load_be(input, 4); + uint32_t W05 = load_be(input, 5); + uint32_t W06 = load_be(input, 6); + uint32_t W07 = load_be(input, 7); + uint32_t W08 = load_be(input, 8); + uint32_t W09 = load_be(input, 9); + uint32_t W10 = load_be(input, 10); + uint32_t W11 = load_be(input, 11); + uint32_t W12 = load_be(input, 12); + uint32_t W13 = load_be(input, 13); + uint32_t W14 = load_be(input, 14); + uint32_t W15 = load_be(input, 15); + + SHA2_32_F(A, B, C, D, E, F, G, H, W00, W14, W09, W01, 0x428A2F98); + SHA2_32_F(H, A, B, C, D, E, F, G, W01, W15, W10, W02, 0x71374491); + SHA2_32_F(G, H, A, B, C, D, E, F, W02, W00, W11, W03, 0xB5C0FBCF); + SHA2_32_F(F, G, H, A, B, C, D, E, W03, W01, W12, W04, 0xE9B5DBA5); + SHA2_32_F(E, F, G, H, A, B, C, D, W04, W02, W13, W05, 0x3956C25B); + SHA2_32_F(D, E, F, G, H, A, B, C, W05, W03, W14, W06, 0x59F111F1); + SHA2_32_F(C, D, E, F, G, H, A, B, W06, W04, W15, W07, 0x923F82A4); + SHA2_32_F(B, C, D, E, F, G, H, A, W07, W05, W00, W08, 0xAB1C5ED5); + SHA2_32_F(A, B, C, D, E, F, G, H, W08, W06, W01, W09, 0xD807AA98); + SHA2_32_F(H, A, B, C, D, E, F, G, W09, W07, W02, W10, 0x12835B01); + SHA2_32_F(G, H, A, B, C, D, E, F, W10, W08, W03, W11, 0x243185BE); + SHA2_32_F(F, G, H, A, B, C, D, E, W11, W09, W04, W12, 0x550C7DC3); + SHA2_32_F(E, F, G, H, A, B, C, D, W12, W10, W05, W13, 0x72BE5D74); + SHA2_32_F(D, E, F, G, H, A, B, C, W13, W11, W06, W14, 0x80DEB1FE); + SHA2_32_F(C, D, E, F, G, H, A, B, W14, W12, W07, W15, 0x9BDC06A7); + SHA2_32_F(B, C, D, E, F, G, H, A, W15, W13, W08, W00, 0xC19BF174); + + SHA2_32_F(A, B, C, D, E, F, G, H, W00, W14, W09, W01, 0xE49B69C1); + SHA2_32_F(H, A, B, C, D, E, F, G, W01, W15, W10, W02, 0xEFBE4786); + SHA2_32_F(G, H, A, B, C, D, E, F, W02, W00, W11, W03, 0x0FC19DC6); + SHA2_32_F(F, G, H, A, B, C, D, E, W03, W01, W12, W04, 0x240CA1CC); + SHA2_32_F(E, F, G, H, A, B, C, D, W04, W02, W13, W05, 0x2DE92C6F); + SHA2_32_F(D, E, F, G, H, A, B, C, W05, W03, W14, W06, 0x4A7484AA); + SHA2_32_F(C, D, E, F, G, H, A, B, W06, W04, W15, W07, 0x5CB0A9DC); + SHA2_32_F(B, C, D, E, F, G, H, A, W07, W05, W00, W08, 0x76F988DA); + SHA2_32_F(A, B, C, D, E, F, G, H, W08, W06, W01, W09, 0x983E5152); + SHA2_32_F(H, A, B, C, D, E, F, G, W09, W07, W02, W10, 0xA831C66D); + SHA2_32_F(G, H, A, B, C, D, E, F, W10, W08, W03, W11, 0xB00327C8); + SHA2_32_F(F, G, H, A, B, C, D, E, W11, W09, W04, W12, 0xBF597FC7); + SHA2_32_F(E, F, G, H, A, B, C, D, W12, W10, W05, W13, 0xC6E00BF3); + SHA2_32_F(D, E, F, G, H, A, B, C, W13, W11, W06, W14, 0xD5A79147); + SHA2_32_F(C, D, E, F, G, H, A, B, W14, W12, W07, W15, 0x06CA6351); + SHA2_32_F(B, C, D, E, F, G, H, A, W15, W13, W08, W00, 0x14292967); + + SHA2_32_F(A, B, C, D, E, F, G, H, W00, W14, W09, W01, 0x27B70A85); + SHA2_32_F(H, A, B, C, D, E, F, G, W01, W15, W10, W02, 0x2E1B2138); + SHA2_32_F(G, H, A, B, C, D, E, F, W02, W00, W11, W03, 0x4D2C6DFC); + SHA2_32_F(F, G, H, A, B, C, D, E, W03, W01, W12, W04, 0x53380D13); + SHA2_32_F(E, F, G, H, A, B, C, D, W04, W02, W13, W05, 0x650A7354); + SHA2_32_F(D, E, F, G, H, A, B, C, W05, W03, W14, W06, 0x766A0ABB); + SHA2_32_F(C, D, E, F, G, H, A, B, W06, W04, W15, W07, 0x81C2C92E); + SHA2_32_F(B, C, D, E, F, G, H, A, W07, W05, W00, W08, 0x92722C85); + SHA2_32_F(A, B, C, D, E, F, G, H, W08, W06, W01, W09, 0xA2BFE8A1); + SHA2_32_F(H, A, B, C, D, E, F, G, W09, W07, W02, W10, 0xA81A664B); + SHA2_32_F(G, H, A, B, C, D, E, F, W10, W08, W03, W11, 0xC24B8B70); + SHA2_32_F(F, G, H, A, B, C, D, E, W11, W09, W04, W12, 0xC76C51A3); + SHA2_32_F(E, F, G, H, A, B, C, D, W12, W10, W05, W13, 0xD192E819); + SHA2_32_F(D, E, F, G, H, A, B, C, W13, W11, W06, W14, 0xD6990624); + SHA2_32_F(C, D, E, F, G, H, A, B, W14, W12, W07, W15, 0xF40E3585); + SHA2_32_F(B, C, D, E, F, G, H, A, W15, W13, W08, W00, 0x106AA070); + + SHA2_32_F(A, B, C, D, E, F, G, H, W00, W14, W09, W01, 0x19A4C116); + SHA2_32_F(H, A, B, C, D, E, F, G, W01, W15, W10, W02, 0x1E376C08); + SHA2_32_F(G, H, A, B, C, D, E, F, W02, W00, W11, W03, 0x2748774C); + SHA2_32_F(F, G, H, A, B, C, D, E, W03, W01, W12, W04, 0x34B0BCB5); + SHA2_32_F(E, F, G, H, A, B, C, D, W04, W02, W13, W05, 0x391C0CB3); + SHA2_32_F(D, E, F, G, H, A, B, C, W05, W03, W14, W06, 0x4ED8AA4A); + SHA2_32_F(C, D, E, F, G, H, A, B, W06, W04, W15, W07, 0x5B9CCA4F); + SHA2_32_F(B, C, D, E, F, G, H, A, W07, W05, W00, W08, 0x682E6FF3); + SHA2_32_F(A, B, C, D, E, F, G, H, W08, W06, W01, W09, 0x748F82EE); + SHA2_32_F(H, A, B, C, D, E, F, G, W09, W07, W02, W10, 0x78A5636F); + SHA2_32_F(G, H, A, B, C, D, E, F, W10, W08, W03, W11, 0x84C87814); + SHA2_32_F(F, G, H, A, B, C, D, E, W11, W09, W04, W12, 0x8CC70208); + SHA2_32_F(E, F, G, H, A, B, C, D, W12, W10, W05, W13, 0x90BEFFFA); + SHA2_32_F(D, E, F, G, H, A, B, C, W13, W11, W06, W14, 0xA4506CEB); + SHA2_32_F(C, D, E, F, G, H, A, B, W14, W12, W07, W15, 0xBEF9A3F7); + SHA2_32_F(B, C, D, E, F, G, H, A, W15, W13, W08, W00, 0xC67178F2); + + A = (digest[0] += A); + B = (digest[1] += B); + C = (digest[2] += C); + D = (digest[3] += D); + E = (digest[4] += E); + F = (digest[5] += F); + G = (digest[6] += G); + H = (digest[7] += H); + + input += 64; + } + } + +/* +* SHA-224 compression function +*/ +void SHA_224::compress_n(const uint8_t input[], size_t blocks) + { + SHA_256::compress_digest(m_digest, input, blocks); + } + +/* +* Copy out the digest +*/ +void SHA_224::copy_out(uint8_t output[]) + { + copy_out_vec_be(output, output_length(), m_digest); + } + +/* +* Clear memory of sensitive data +*/ +void SHA_224::clear() + { + MDx_HashFunction::clear(); + m_digest[0] = 0xC1059ED8; + m_digest[1] = 0x367CD507; + m_digest[2] = 0x3070DD17; + m_digest[3] = 0xF70E5939; + m_digest[4] = 0xFFC00B31; + m_digest[5] = 0x68581511; + m_digest[6] = 0x64F98FA7; + m_digest[7] = 0xBEFA4FA4; + } + +/* +* SHA-256 compression function +*/ +void SHA_256::compress_n(const uint8_t input[], size_t blocks) + { + SHA_256::compress_digest(m_digest, input, blocks); + } + +/* +* Copy out the digest +*/ +void SHA_256::copy_out(uint8_t output[]) + { + copy_out_vec_be(output, output_length(), m_digest); + } + +/* +* Clear memory of sensitive data +*/ +void SHA_256::clear() + { + MDx_HashFunction::clear(); + m_digest[0] = 0x6A09E667; + m_digest[1] = 0xBB67AE85; + m_digest[2] = 0x3C6EF372; + m_digest[3] = 0xA54FF53A; + m_digest[4] = 0x510E527F; + m_digest[5] = 0x9B05688C; + m_digest[6] = 0x1F83D9AB; + m_digest[7] = 0x5BE0CD19; + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/hash/sha2_32/sha2_32.h b/src/libs/3rdparty/botan/src/lib/hash/sha2_32/sha2_32.h new file mode 100644 index 0000000000..bc883f77ac --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/hash/sha2_32/sha2_32.h @@ -0,0 +1,89 @@ +/* +* SHA-{224,256} +* (C) 1999-2011 Jack Lloyd +* 2007 FlexSecure GmbH +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_SHA_224_256_H_ +#define BOTAN_SHA_224_256_H_ + +#include + +namespace Botan { + +/** +* SHA-224 +*/ +class BOTAN_PUBLIC_API(2,0) SHA_224 final : public MDx_HashFunction + { + public: + std::string name() const override { return "SHA-224"; } + size_t output_length() const override { return 28; } + HashFunction* clone() const override { return new SHA_224; } + std::unique_ptr copy_state() const override; + + void clear() override; + + SHA_224() : MDx_HashFunction(64, true, true), m_digest(8) + { clear(); } + private: + void compress_n(const uint8_t[], size_t blocks) override; + void copy_out(uint8_t[]) override; + + secure_vector m_digest; + }; + +/** +* SHA-256 +*/ +class BOTAN_PUBLIC_API(2,0) SHA_256 final : public MDx_HashFunction + { + public: + std::string name() const override { return "SHA-256"; } + size_t output_length() const override { return 32; } + HashFunction* clone() const override { return new SHA_256; } + std::unique_ptr copy_state() const override; + + void clear() override; + + SHA_256() : MDx_HashFunction(64, true, true), m_digest(8) + { clear(); } + + /* + * Perform a SHA-256 compression. For internal use + */ + static void compress_digest(secure_vector& digest, + const uint8_t input[], + size_t blocks); + + private: + +#if defined(BOTAN_HAS_SHA2_32_ARMV8) + static void compress_digest_armv8(secure_vector& digest, + const uint8_t input[], + size_t blocks); +#endif + +#if defined(BOTAN_HAS_SHA2_32_X86_BMI2) + static void compress_digest_x86_bmi2(secure_vector& digest, + const uint8_t input[], + size_t blocks); +#endif + +#if defined(BOTAN_HAS_SHA2_32_X86) + static void compress_digest_x86(secure_vector& digest, + const uint8_t input[], + size_t blocks); +#endif + + void compress_n(const uint8_t[], size_t blocks) override; + void copy_out(uint8_t[]) override; + + secure_vector m_digest; + }; + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/hash/sha2_32/sha2_32_armv8/info.txt b/src/libs/3rdparty/botan/src/lib/hash/sha2_32/sha2_32_armv8/info.txt new file mode 100644 index 0000000000..74d3fe4abc --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/hash/sha2_32/sha2_32_armv8/info.txt @@ -0,0 +1,10 @@ + +SHA2_32_ARMV8 -> 20170117 + + +need_isa armv8crypto + + +gcc:4.9 +clang:3.8 + diff --git a/src/libs/3rdparty/botan/src/lib/hash/sha2_32/sha2_32_armv8/sha2_32_armv8.cpp b/src/libs/3rdparty/botan/src/lib/hash/sha2_32/sha2_32_armv8/sha2_32_armv8.cpp new file mode 100644 index 0000000000..1574a32738 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/hash/sha2_32/sha2_32_armv8/sha2_32_armv8.cpp @@ -0,0 +1,204 @@ +/* +* SHA-256 using CPU instructions in ARMv8 +* +* Contributed by Jeffrey Walton. Based on public domain code by +* Johannes Schneiders, Skip Hovsmith and Barry O'Rourke. +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include + +namespace Botan { + +/* +* SHA-256 using CPU instructions in ARMv8 +*/ +//static +#if defined(BOTAN_HAS_SHA2_32_ARMV8) +BOTAN_FUNC_ISA("+crypto") +void SHA_256::compress_digest_armv8(secure_vector& digest, const uint8_t input8[], size_t blocks) + { + static const uint32_t K[] = { + 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5, + 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5, + 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3, + 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174, + 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC, + 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA, + 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7, + 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967, + 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13, + 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85, + 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3, + 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070, + 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5, + 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3, + 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208, + 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2, + }; + + uint32x4_t STATE0, STATE1, ABEF_SAVE, CDGH_SAVE; + uint32x4_t MSG0, MSG1, MSG2, MSG3; + uint32x4_t TMP0, TMP1, TMP2; + + // Load initial values + STATE0 = vld1q_u32(&digest[0]); + STATE1 = vld1q_u32(&digest[4]); + + // Intermediate void* cast due to https://llvm.org/bugs/show_bug.cgi?id=20670 + const uint32_t* input32 = reinterpret_cast(reinterpret_cast(input8)); + + while (blocks) + { + // Save current state + ABEF_SAVE = STATE0; + CDGH_SAVE = STATE1; + + MSG0 = vld1q_u32(input32 + 0); + MSG1 = vld1q_u32(input32 + 4); + MSG2 = vld1q_u32(input32 + 8); + MSG3 = vld1q_u32(input32 + 12); + + MSG0 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(MSG0))); + MSG1 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(MSG1))); + MSG2 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(MSG2))); + MSG3 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(MSG3))); + + TMP0 = vaddq_u32(MSG0, vld1q_u32(&K[0x00])); + + // Rounds 0-3 + MSG0 = vsha256su0q_u32(MSG0, MSG1); + TMP2 = STATE0; + TMP1 = vaddq_u32(MSG1, vld1q_u32(&K[0x04])); + STATE0 = vsha256hq_u32(STATE0, STATE1, TMP0); + STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP0); + MSG0 = vsha256su1q_u32(MSG0, MSG2, MSG3); + + // Rounds 4-7 + MSG1 = vsha256su0q_u32(MSG1, MSG2); + TMP2 = STATE0; + TMP0 = vaddq_u32(MSG2, vld1q_u32(&K[0x08])); + STATE0 = vsha256hq_u32(STATE0, STATE1, TMP1); + STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP1); + MSG1 = vsha256su1q_u32(MSG1, MSG3, MSG0); + + // Rounds 8-11 + MSG2 = vsha256su0q_u32(MSG2, MSG3); + TMP2 = STATE0; + TMP1 = vaddq_u32(MSG3, vld1q_u32(&K[0x0c])); + STATE0 = vsha256hq_u32(STATE0, STATE1, TMP0); + STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP0); + MSG2 = vsha256su1q_u32(MSG2, MSG0, MSG1); + + // Rounds 12-15 + MSG3 = vsha256su0q_u32(MSG3, MSG0); + TMP2 = STATE0; + TMP0 = vaddq_u32(MSG0, vld1q_u32(&K[0x10])); + STATE0 = vsha256hq_u32(STATE0, STATE1, TMP1); + STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP1); + MSG3 = vsha256su1q_u32(MSG3, MSG1, MSG2); + + // Rounds 16-19 + MSG0 = vsha256su0q_u32(MSG0, MSG1); + TMP2 = STATE0; + TMP1 = vaddq_u32(MSG1, vld1q_u32(&K[0x14])); + STATE0 = vsha256hq_u32(STATE0, STATE1, TMP0); + STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP0); + MSG0 = vsha256su1q_u32(MSG0, MSG2, MSG3); + + // Rounds 20-23 + MSG1 = vsha256su0q_u32(MSG1, MSG2); + TMP2 = STATE0; + TMP0 = vaddq_u32(MSG2, vld1q_u32(&K[0x18])); + STATE0 = vsha256hq_u32(STATE0, STATE1, TMP1); + STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP1); + MSG1 = vsha256su1q_u32(MSG1, MSG3, MSG0); + + // Rounds 24-27 + MSG2 = vsha256su0q_u32(MSG2, MSG3); + TMP2 = STATE0; + TMP1 = vaddq_u32(MSG3, vld1q_u32(&K[0x1c])); + STATE0 = vsha256hq_u32(STATE0, STATE1, TMP0); + STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP0); + MSG2 = vsha256su1q_u32(MSG2, MSG0, MSG1); + + // Rounds 28-31 + MSG3 = vsha256su0q_u32(MSG3, MSG0); + TMP2 = STATE0; + TMP0 = vaddq_u32(MSG0, vld1q_u32(&K[0x20])); + STATE0 = vsha256hq_u32(STATE0, STATE1, TMP1); + STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP1); + MSG3 = vsha256su1q_u32(MSG3, MSG1, MSG2); + + // Rounds 32-35 + MSG0 = vsha256su0q_u32(MSG0, MSG1); + TMP2 = STATE0; + TMP1 = vaddq_u32(MSG1, vld1q_u32(&K[0x24])); + STATE0 = vsha256hq_u32(STATE0, STATE1, TMP0); + STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP0); + MSG0 = vsha256su1q_u32(MSG0, MSG2, MSG3); + + // Rounds 36-39 + MSG1 = vsha256su0q_u32(MSG1, MSG2); + TMP2 = STATE0; + TMP0 = vaddq_u32(MSG2, vld1q_u32(&K[0x28])); + STATE0 = vsha256hq_u32(STATE0, STATE1, TMP1); + STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP1); + MSG1 = vsha256su1q_u32(MSG1, MSG3, MSG0); + + // Rounds 40-43 + MSG2 = vsha256su0q_u32(MSG2, MSG3); + TMP2 = STATE0; + TMP1 = vaddq_u32(MSG3, vld1q_u32(&K[0x2c])); + STATE0 = vsha256hq_u32(STATE0, STATE1, TMP0); + STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP0); + MSG2 = vsha256su1q_u32(MSG2, MSG0, MSG1); + + // Rounds 44-47 + MSG3 = vsha256su0q_u32(MSG3, MSG0); + TMP2 = STATE0; + TMP0 = vaddq_u32(MSG0, vld1q_u32(&K[0x30])); + STATE0 = vsha256hq_u32(STATE0, STATE1, TMP1); + STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP1); + MSG3 = vsha256su1q_u32(MSG3, MSG1, MSG2); + + // Rounds 48-51 + TMP2 = STATE0; + TMP1 = vaddq_u32(MSG1, vld1q_u32(&K[0x34])); + STATE0 = vsha256hq_u32(STATE0, STATE1, TMP0); + STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP0); + + // Rounds 52-55 + TMP2 = STATE0; + TMP0 = vaddq_u32(MSG2, vld1q_u32(&K[0x38])); + STATE0 = vsha256hq_u32(STATE0, STATE1, TMP1); + STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP1); + + // Rounds 56-59 + TMP2 = STATE0; + TMP1 = vaddq_u32(MSG3, vld1q_u32(&K[0x3c])); + STATE0 = vsha256hq_u32(STATE0, STATE1, TMP0); + STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP0); + + // Rounds 60-63 + TMP2 = STATE0; + STATE0 = vsha256hq_u32(STATE0, STATE1, TMP1); + STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP1); + + // Add back to state + STATE0 = vaddq_u32(STATE0, ABEF_SAVE); + STATE1 = vaddq_u32(STATE1, CDGH_SAVE); + + input32 += 64/4; + blocks--; + } + + // Save state + vst1q_u32(&digest[0], STATE0); + vst1q_u32(&digest[4], STATE1); + } +#endif + +} diff --git a/src/libs/3rdparty/botan/src/lib/hash/sha2_32/sha2_32_bmi2/info.txt b/src/libs/3rdparty/botan/src/lib/hash/sha2_32/sha2_32_bmi2/info.txt new file mode 100644 index 0000000000..dc73497163 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/hash/sha2_32/sha2_32_bmi2/info.txt @@ -0,0 +1,10 @@ + +SHA2_32_X86_BMI2 -> 20180526 + + +need_isa bmi2 + + +gcc +clang + diff --git a/src/libs/3rdparty/botan/src/lib/hash/sha2_32/sha2_32_bmi2/sha2_32_bmi2.cpp b/src/libs/3rdparty/botan/src/lib/hash/sha2_32/sha2_32_bmi2/sha2_32_bmi2.cpp new file mode 100644 index 0000000000..12ceb11c49 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/hash/sha2_32/sha2_32_bmi2/sha2_32_bmi2.cpp @@ -0,0 +1,139 @@ +/* +* (C) 2018 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include + +namespace Botan { + +/* +Your eyes do not decieve you; this is currently just a copy of the +baseline SHA-256 implementation. Because we compile it with BMI2 +flags, GCC and Clang use the BMI2 instructions without further help. + +Likely instruction scheduling could be improved by using inline asm. +*/ + +#define SHA2_32_F(A, B, C, D, E, F, G, H, M1, M2, M3, M4, magic) do { \ + uint32_t A_rho = rotr<2>(A) ^ rotr<13>(A) ^ rotr<22>(A); \ + uint32_t E_rho = rotr<6>(E) ^ rotr<11>(E) ^ rotr<25>(E); \ + uint32_t M2_sigma = rotr<17>(M2) ^ rotr<19>(M2) ^ (M2 >> 10); \ + uint32_t M4_sigma = rotr<7>(M4) ^ rotr<18>(M4) ^ (M4 >> 3); \ + H += magic + E_rho + ((E & F) ^ (~E & G)) + M1; \ + D += H; \ + H += A_rho + ((A & B) | ((A | B) & C)); \ + M1 += M2_sigma + M3 + M4_sigma; \ + } while(0); + +void SHA_256::compress_digest_x86_bmi2(secure_vector& digest, + const uint8_t input[], + size_t blocks) + { + uint32_t A = digest[0], B = digest[1], C = digest[2], + D = digest[3], E = digest[4], F = digest[5], + G = digest[6], H = digest[7]; + + for(size_t i = 0; i != blocks; ++i) + { + uint32_t W00 = load_be(input, 0); + uint32_t W01 = load_be(input, 1); + uint32_t W02 = load_be(input, 2); + uint32_t W03 = load_be(input, 3); + uint32_t W04 = load_be(input, 4); + uint32_t W05 = load_be(input, 5); + uint32_t W06 = load_be(input, 6); + uint32_t W07 = load_be(input, 7); + uint32_t W08 = load_be(input, 8); + uint32_t W09 = load_be(input, 9); + uint32_t W10 = load_be(input, 10); + uint32_t W11 = load_be(input, 11); + uint32_t W12 = load_be(input, 12); + uint32_t W13 = load_be(input, 13); + uint32_t W14 = load_be(input, 14); + uint32_t W15 = load_be(input, 15); + + SHA2_32_F(A, B, C, D, E, F, G, H, W00, W14, W09, W01, 0x428A2F98); + SHA2_32_F(H, A, B, C, D, E, F, G, W01, W15, W10, W02, 0x71374491); + SHA2_32_F(G, H, A, B, C, D, E, F, W02, W00, W11, W03, 0xB5C0FBCF); + SHA2_32_F(F, G, H, A, B, C, D, E, W03, W01, W12, W04, 0xE9B5DBA5); + SHA2_32_F(E, F, G, H, A, B, C, D, W04, W02, W13, W05, 0x3956C25B); + SHA2_32_F(D, E, F, G, H, A, B, C, W05, W03, W14, W06, 0x59F111F1); + SHA2_32_F(C, D, E, F, G, H, A, B, W06, W04, W15, W07, 0x923F82A4); + SHA2_32_F(B, C, D, E, F, G, H, A, W07, W05, W00, W08, 0xAB1C5ED5); + SHA2_32_F(A, B, C, D, E, F, G, H, W08, W06, W01, W09, 0xD807AA98); + SHA2_32_F(H, A, B, C, D, E, F, G, W09, W07, W02, W10, 0x12835B01); + SHA2_32_F(G, H, A, B, C, D, E, F, W10, W08, W03, W11, 0x243185BE); + SHA2_32_F(F, G, H, A, B, C, D, E, W11, W09, W04, W12, 0x550C7DC3); + SHA2_32_F(E, F, G, H, A, B, C, D, W12, W10, W05, W13, 0x72BE5D74); + SHA2_32_F(D, E, F, G, H, A, B, C, W13, W11, W06, W14, 0x80DEB1FE); + SHA2_32_F(C, D, E, F, G, H, A, B, W14, W12, W07, W15, 0x9BDC06A7); + SHA2_32_F(B, C, D, E, F, G, H, A, W15, W13, W08, W00, 0xC19BF174); + + SHA2_32_F(A, B, C, D, E, F, G, H, W00, W14, W09, W01, 0xE49B69C1); + SHA2_32_F(H, A, B, C, D, E, F, G, W01, W15, W10, W02, 0xEFBE4786); + SHA2_32_F(G, H, A, B, C, D, E, F, W02, W00, W11, W03, 0x0FC19DC6); + SHA2_32_F(F, G, H, A, B, C, D, E, W03, W01, W12, W04, 0x240CA1CC); + SHA2_32_F(E, F, G, H, A, B, C, D, W04, W02, W13, W05, 0x2DE92C6F); + SHA2_32_F(D, E, F, G, H, A, B, C, W05, W03, W14, W06, 0x4A7484AA); + SHA2_32_F(C, D, E, F, G, H, A, B, W06, W04, W15, W07, 0x5CB0A9DC); + SHA2_32_F(B, C, D, E, F, G, H, A, W07, W05, W00, W08, 0x76F988DA); + SHA2_32_F(A, B, C, D, E, F, G, H, W08, W06, W01, W09, 0x983E5152); + SHA2_32_F(H, A, B, C, D, E, F, G, W09, W07, W02, W10, 0xA831C66D); + SHA2_32_F(G, H, A, B, C, D, E, F, W10, W08, W03, W11, 0xB00327C8); + SHA2_32_F(F, G, H, A, B, C, D, E, W11, W09, W04, W12, 0xBF597FC7); + SHA2_32_F(E, F, G, H, A, B, C, D, W12, W10, W05, W13, 0xC6E00BF3); + SHA2_32_F(D, E, F, G, H, A, B, C, W13, W11, W06, W14, 0xD5A79147); + SHA2_32_F(C, D, E, F, G, H, A, B, W14, W12, W07, W15, 0x06CA6351); + SHA2_32_F(B, C, D, E, F, G, H, A, W15, W13, W08, W00, 0x14292967); + + SHA2_32_F(A, B, C, D, E, F, G, H, W00, W14, W09, W01, 0x27B70A85); + SHA2_32_F(H, A, B, C, D, E, F, G, W01, W15, W10, W02, 0x2E1B2138); + SHA2_32_F(G, H, A, B, C, D, E, F, W02, W00, W11, W03, 0x4D2C6DFC); + SHA2_32_F(F, G, H, A, B, C, D, E, W03, W01, W12, W04, 0x53380D13); + SHA2_32_F(E, F, G, H, A, B, C, D, W04, W02, W13, W05, 0x650A7354); + SHA2_32_F(D, E, F, G, H, A, B, C, W05, W03, W14, W06, 0x766A0ABB); + SHA2_32_F(C, D, E, F, G, H, A, B, W06, W04, W15, W07, 0x81C2C92E); + SHA2_32_F(B, C, D, E, F, G, H, A, W07, W05, W00, W08, 0x92722C85); + SHA2_32_F(A, B, C, D, E, F, G, H, W08, W06, W01, W09, 0xA2BFE8A1); + SHA2_32_F(H, A, B, C, D, E, F, G, W09, W07, W02, W10, 0xA81A664B); + SHA2_32_F(G, H, A, B, C, D, E, F, W10, W08, W03, W11, 0xC24B8B70); + SHA2_32_F(F, G, H, A, B, C, D, E, W11, W09, W04, W12, 0xC76C51A3); + SHA2_32_F(E, F, G, H, A, B, C, D, W12, W10, W05, W13, 0xD192E819); + SHA2_32_F(D, E, F, G, H, A, B, C, W13, W11, W06, W14, 0xD6990624); + SHA2_32_F(C, D, E, F, G, H, A, B, W14, W12, W07, W15, 0xF40E3585); + SHA2_32_F(B, C, D, E, F, G, H, A, W15, W13, W08, W00, 0x106AA070); + + SHA2_32_F(A, B, C, D, E, F, G, H, W00, W14, W09, W01, 0x19A4C116); + SHA2_32_F(H, A, B, C, D, E, F, G, W01, W15, W10, W02, 0x1E376C08); + SHA2_32_F(G, H, A, B, C, D, E, F, W02, W00, W11, W03, 0x2748774C); + SHA2_32_F(F, G, H, A, B, C, D, E, W03, W01, W12, W04, 0x34B0BCB5); + SHA2_32_F(E, F, G, H, A, B, C, D, W04, W02, W13, W05, 0x391C0CB3); + SHA2_32_F(D, E, F, G, H, A, B, C, W05, W03, W14, W06, 0x4ED8AA4A); + SHA2_32_F(C, D, E, F, G, H, A, B, W06, W04, W15, W07, 0x5B9CCA4F); + SHA2_32_F(B, C, D, E, F, G, H, A, W07, W05, W00, W08, 0x682E6FF3); + SHA2_32_F(A, B, C, D, E, F, G, H, W08, W06, W01, W09, 0x748F82EE); + SHA2_32_F(H, A, B, C, D, E, F, G, W09, W07, W02, W10, 0x78A5636F); + SHA2_32_F(G, H, A, B, C, D, E, F, W10, W08, W03, W11, 0x84C87814); + SHA2_32_F(F, G, H, A, B, C, D, E, W11, W09, W04, W12, 0x8CC70208); + SHA2_32_F(E, F, G, H, A, B, C, D, W12, W10, W05, W13, 0x90BEFFFA); + SHA2_32_F(D, E, F, G, H, A, B, C, W13, W11, W06, W14, 0xA4506CEB); + SHA2_32_F(C, D, E, F, G, H, A, B, W14, W12, W07, W15, 0xBEF9A3F7); + SHA2_32_F(B, C, D, E, F, G, H, A, W15, W13, W08, W00, 0xC67178F2); + + A = (digest[0] += A); + B = (digest[1] += B); + C = (digest[2] += C); + D = (digest[3] += D); + E = (digest[4] += E); + F = (digest[5] += F); + G = (digest[6] += G); + H = (digest[7] += H); + + input += 64; + } + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/hash/sha2_32/sha2_32_x86/info.txt b/src/libs/3rdparty/botan/src/lib/hash/sha2_32/sha2_32_x86/info.txt new file mode 100644 index 0000000000..4a0b25910e --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/hash/sha2_32/sha2_32_x86/info.txt @@ -0,0 +1,11 @@ + +SHA2_32_X86 -> 20170518 + + +need_isa sha,ssse3,sse41 + + +gcc:5.0 +clang:3.9 +msvc:19.0 # MSVS 2015 + diff --git a/src/libs/3rdparty/botan/src/lib/hash/sha2_32/sha2_32_x86/sha2_32_x86.cpp b/src/libs/3rdparty/botan/src/lib/hash/sha2_32/sha2_32_x86/sha2_32_x86.cpp new file mode 100644 index 0000000000..a4bd9b72db --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/hash/sha2_32/sha2_32_x86/sha2_32_x86.cpp @@ -0,0 +1,215 @@ +/* +* Support for SHA-256 x86 instrinsic +* Based on public domain code by Sean Gulley +* (https://github.com/mitls/hacl-star/tree/master/experimental/hash) +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include + +namespace Botan { + +// called from sha2_32.cpp +#if defined(BOTAN_HAS_SHA2_32_X86) +BOTAN_FUNC_ISA("sha,sse4.1,ssse3") +void SHA_256::compress_digest_x86(secure_vector& digest, const uint8_t input[], size_t blocks) + { + __m128i STATE0, STATE1; + __m128i MSG, TMP, MASK; + __m128i TMSG0, TMSG1, TMSG2, TMSG3; + __m128i ABEF_SAVE, CDGH_SAVE; + + uint32_t* state = &digest[0]; + + const __m128i* input_mm = reinterpret_cast(input); + + // Load initial values + TMP = _mm_loadu_si128(reinterpret_cast<__m128i*>(&state[0])); + STATE1 = _mm_loadu_si128(reinterpret_cast<__m128i*>(&state[4])); + MASK = _mm_set_epi64x(0x0c0d0e0f08090a0bULL, 0x0405060700010203ULL); + + TMP = _mm_shuffle_epi32(TMP, 0xB1); // CDAB + STATE1 = _mm_shuffle_epi32(STATE1, 0x1B); // EFGH + STATE0 = _mm_alignr_epi8(TMP, STATE1, 8); // ABEF + STATE1 = _mm_blend_epi16(STATE1, TMP, 0xF0); // CDGH + + while (blocks) + { + // Save current hash + ABEF_SAVE = STATE0; + CDGH_SAVE = STATE1; + + // Rounds 0-3 + MSG = _mm_loadu_si128(input_mm); + TMSG0 = _mm_shuffle_epi8(MSG, MASK); + MSG = _mm_add_epi32(TMSG0, _mm_set_epi64x(0xE9B5DBA5B5C0FBCFULL, 0x71374491428A2F98ULL)); + STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG); + MSG = _mm_shuffle_epi32(MSG, 0x0E); + STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG); + + // Rounds 4-7 + TMSG1 = _mm_loadu_si128(input_mm + 1); + TMSG1 = _mm_shuffle_epi8(TMSG1, MASK); + MSG = _mm_add_epi32(TMSG1, _mm_set_epi64x(0xAB1C5ED5923F82A4ULL, 0x59F111F13956C25BULL)); + STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG); + MSG = _mm_shuffle_epi32(MSG, 0x0E); + STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG); + TMSG0 = _mm_sha256msg1_epu32(TMSG0, TMSG1); + + // Rounds 8-11 + TMSG2 = _mm_loadu_si128(input_mm + 2); + TMSG2 = _mm_shuffle_epi8(TMSG2, MASK); + MSG = _mm_add_epi32(TMSG2, _mm_set_epi64x(0x550C7DC3243185BEULL, 0x12835B01D807AA98ULL)); + STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG); + MSG = _mm_shuffle_epi32(MSG, 0x0E); + STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG); + TMSG1 = _mm_sha256msg1_epu32(TMSG1, TMSG2); + + // Rounds 12-15 + TMSG3 = _mm_loadu_si128(input_mm + 3); + TMSG3 = _mm_shuffle_epi8(TMSG3, MASK); + MSG = _mm_add_epi32(TMSG3, _mm_set_epi64x(0xC19BF1749BDC06A7ULL, 0x80DEB1FE72BE5D74ULL)); + STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG); + TMP = _mm_alignr_epi8(TMSG3, TMSG2, 4); + TMSG0 = _mm_add_epi32(TMSG0, TMP); + TMSG0 = _mm_sha256msg2_epu32(TMSG0, TMSG3); + MSG = _mm_shuffle_epi32(MSG, 0x0E); + STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG); + TMSG2 = _mm_sha256msg1_epu32(TMSG2, TMSG3); + + // Rounds 16-19 + MSG = _mm_add_epi32(TMSG0, _mm_set_epi64x(0x240CA1CC0FC19DC6ULL, 0xEFBE4786E49B69C1ULL)); + STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG); + TMP = _mm_alignr_epi8(TMSG0, TMSG3, 4); + TMSG1 = _mm_add_epi32(TMSG1, TMP); + TMSG1 = _mm_sha256msg2_epu32(TMSG1, TMSG0); + MSG = _mm_shuffle_epi32(MSG, 0x0E); + STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG); + TMSG3 = _mm_sha256msg1_epu32(TMSG3, TMSG0); + + // Rounds 20-23 + MSG = _mm_add_epi32(TMSG1, _mm_set_epi64x(0x76F988DA5CB0A9DCULL, 0x4A7484AA2DE92C6FULL)); + STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG); + TMP = _mm_alignr_epi8(TMSG1, TMSG0, 4); + TMSG2 = _mm_add_epi32(TMSG2, TMP); + TMSG2 = _mm_sha256msg2_epu32(TMSG2, TMSG1); + MSG = _mm_shuffle_epi32(MSG, 0x0E); + STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG); + TMSG0 = _mm_sha256msg1_epu32(TMSG0, TMSG1); + + // Rounds 24-27 + MSG = _mm_add_epi32(TMSG2, _mm_set_epi64x(0xBF597FC7B00327C8ULL, 0xA831C66D983E5152ULL)); + STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG); + TMP = _mm_alignr_epi8(TMSG2, TMSG1, 4); + TMSG3 = _mm_add_epi32(TMSG3, TMP); + TMSG3 = _mm_sha256msg2_epu32(TMSG3, TMSG2); + MSG = _mm_shuffle_epi32(MSG, 0x0E); + STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG); + TMSG1 = _mm_sha256msg1_epu32(TMSG1, TMSG2); + + // Rounds 28-31 + MSG = _mm_add_epi32(TMSG3, _mm_set_epi64x(0x1429296706CA6351ULL, 0xD5A79147C6E00BF3ULL)); + STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG); + TMP = _mm_alignr_epi8(TMSG3, TMSG2, 4); + TMSG0 = _mm_add_epi32(TMSG0, TMP); + TMSG0 = _mm_sha256msg2_epu32(TMSG0, TMSG3); + MSG = _mm_shuffle_epi32(MSG, 0x0E); + STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG); + TMSG2 = _mm_sha256msg1_epu32(TMSG2, TMSG3); + + // Rounds 32-35 + MSG = _mm_add_epi32(TMSG0, _mm_set_epi64x(0x53380D134D2C6DFCULL, 0x2E1B213827B70A85ULL)); + STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG); + TMP = _mm_alignr_epi8(TMSG0, TMSG3, 4); + TMSG1 = _mm_add_epi32(TMSG1, TMP); + TMSG1 = _mm_sha256msg2_epu32(TMSG1, TMSG0); + MSG = _mm_shuffle_epi32(MSG, 0x0E); + STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG); + TMSG3 = _mm_sha256msg1_epu32(TMSG3, TMSG0); + + // Rounds 36-39 + MSG = _mm_add_epi32(TMSG1, _mm_set_epi64x(0x92722C8581C2C92EULL, 0x766A0ABB650A7354ULL)); + STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG); + TMP = _mm_alignr_epi8(TMSG1, TMSG0, 4); + TMSG2 = _mm_add_epi32(TMSG2, TMP); + TMSG2 = _mm_sha256msg2_epu32(TMSG2, TMSG1); + MSG = _mm_shuffle_epi32(MSG, 0x0E); + STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG); + TMSG0 = _mm_sha256msg1_epu32(TMSG0, TMSG1); + + // Rounds 40-43 + MSG = _mm_add_epi32(TMSG2, _mm_set_epi64x(0xC76C51A3C24B8B70ULL, 0xA81A664BA2BFE8A1ULL)); + STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG); + TMP = _mm_alignr_epi8(TMSG2, TMSG1, 4); + TMSG3 = _mm_add_epi32(TMSG3, TMP); + TMSG3 = _mm_sha256msg2_epu32(TMSG3, TMSG2); + MSG = _mm_shuffle_epi32(MSG, 0x0E); + STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG); + TMSG1 = _mm_sha256msg1_epu32(TMSG1, TMSG2); + + // Rounds 44-47 + MSG = _mm_add_epi32(TMSG3, _mm_set_epi64x(0x106AA070F40E3585ULL, 0xD6990624D192E819ULL)); + STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG); + TMP = _mm_alignr_epi8(TMSG3, TMSG2, 4); + TMSG0 = _mm_add_epi32(TMSG0, TMP); + TMSG0 = _mm_sha256msg2_epu32(TMSG0, TMSG3); + MSG = _mm_shuffle_epi32(MSG, 0x0E); + STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG); + TMSG2 = _mm_sha256msg1_epu32(TMSG2, TMSG3); + + // Rounds 48-51 + MSG = _mm_add_epi32(TMSG0, _mm_set_epi64x(0x34B0BCB52748774CULL, 0x1E376C0819A4C116ULL)); + STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG); + TMP = _mm_alignr_epi8(TMSG0, TMSG3, 4); + TMSG1 = _mm_add_epi32(TMSG1, TMP); + TMSG1 = _mm_sha256msg2_epu32(TMSG1, TMSG0); + MSG = _mm_shuffle_epi32(MSG, 0x0E); + STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG); + TMSG3 = _mm_sha256msg1_epu32(TMSG3, TMSG0); + + // Rounds 52-55 + MSG = _mm_add_epi32(TMSG1, _mm_set_epi64x(0x682E6FF35B9CCA4FULL, 0x4ED8AA4A391C0CB3ULL)); + STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG); + TMP = _mm_alignr_epi8(TMSG1, TMSG0, 4); + TMSG2 = _mm_add_epi32(TMSG2, TMP); + TMSG2 = _mm_sha256msg2_epu32(TMSG2, TMSG1); + MSG = _mm_shuffle_epi32(MSG, 0x0E); + STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG); + + // Rounds 56-59 + MSG = _mm_add_epi32(TMSG2, _mm_set_epi64x(0x8CC7020884C87814ULL, 0x78A5636F748F82EEULL)); + STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG); + TMP = _mm_alignr_epi8(TMSG2, TMSG1, 4); + TMSG3 = _mm_add_epi32(TMSG3, TMP); + TMSG3 = _mm_sha256msg2_epu32(TMSG3, TMSG2); + MSG = _mm_shuffle_epi32(MSG, 0x0E); + STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG); + + // Rounds 60-63 + MSG = _mm_add_epi32(TMSG3, _mm_set_epi64x(0xC67178F2BEF9A3F7ULL, 0xA4506CEB90BEFFFAULL)); + STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG); + MSG = _mm_shuffle_epi32(MSG, 0x0E); + STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG); + + // Add values back to state + STATE0 = _mm_add_epi32(STATE0, ABEF_SAVE); + STATE1 = _mm_add_epi32(STATE1, CDGH_SAVE); + + input_mm += 4; + blocks--; + } + + TMP = _mm_shuffle_epi32(STATE0, 0x1B); // FEBA + STATE1 = _mm_shuffle_epi32(STATE1, 0xB1); // DCHG + STATE0 = _mm_blend_epi16(TMP, STATE1, 0xF0); // DCBA + STATE1 = _mm_alignr_epi8(STATE1, TMP, 8); // ABEF + + // Save state + _mm_storeu_si128(reinterpret_cast<__m128i*>(&state[0]), STATE0); + _mm_storeu_si128(reinterpret_cast<__m128i*>(&state[4]), STATE1); + } +#endif + +} diff --git a/src/libs/3rdparty/botan/src/lib/hash/sha2_64/info.txt b/src/libs/3rdparty/botan/src/lib/hash/sha2_64/info.txt new file mode 100644 index 0000000000..6fb415a6bb --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/hash/sha2_64/info.txt @@ -0,0 +1,7 @@ + +SHA2_64 -> 20131128 + + + +mdx_hash + diff --git a/src/libs/3rdparty/botan/src/lib/hash/sha2_64/sha2_64.cpp b/src/libs/3rdparty/botan/src/lib/hash/sha2_64/sha2_64.cpp new file mode 100644 index 0000000000..45992e9968 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/hash/sha2_64/sha2_64.cpp @@ -0,0 +1,241 @@ +/* +* SHA-{384,512} +* (C) 1999-2011,2015 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include + +namespace Botan { + +std::unique_ptr SHA_384::copy_state() const + { + return std::unique_ptr(new SHA_384(*this)); + } + +std::unique_ptr SHA_512::copy_state() const + { + return std::unique_ptr(new SHA_512(*this)); + } + +std::unique_ptr SHA_512_256::copy_state() const + { + return std::unique_ptr(new SHA_512_256(*this)); + } + +namespace { + +/* +* SHA-512 F1 Function +* +* Use a macro as many compilers won't inline a function this big, +* even though it is much faster if inlined. +*/ +#define SHA2_64_F(A, B, C, D, E, F, G, H, M1, M2, M3, M4, magic) \ + do { \ + const uint64_t E_rho = rotr<14>(E) ^ rotr<18>(E) ^ rotr<41>(E); \ + const uint64_t A_rho = rotr<28>(A) ^ rotr<34>(A) ^ rotr<39>(A); \ + const uint64_t M2_sigma = rotr<19>(M2) ^ rotr<61>(M2) ^ (M2 >> 6); \ + const uint64_t M4_sigma = rotr<1>(M4) ^ rotr<8>(M4) ^ (M4 >> 7); \ + H += magic + E_rho + ((E & F) ^ (~E & G)) + M1; \ + D += H; \ + H += A_rho + ((A & B) | ((A | B) & C)); \ + M1 += M2_sigma + M3 + M4_sigma; \ + } while(0); + +/* +* SHA-{384,512} Compression Function +*/ +void SHA64_compress(secure_vector& digest, + const uint8_t input[], size_t blocks) + { + uint64_t A = digest[0], B = digest[1], C = digest[2], + D = digest[3], E = digest[4], F = digest[5], + G = digest[6], H = digest[7]; + + for(size_t i = 0; i != blocks; ++i) + { + uint64_t W00 = load_be(input, 0); + uint64_t W01 = load_be(input, 1); + uint64_t W02 = load_be(input, 2); + uint64_t W03 = load_be(input, 3); + uint64_t W04 = load_be(input, 4); + uint64_t W05 = load_be(input, 5); + uint64_t W06 = load_be(input, 6); + uint64_t W07 = load_be(input, 7); + uint64_t W08 = load_be(input, 8); + uint64_t W09 = load_be(input, 9); + uint64_t W10 = load_be(input, 10); + uint64_t W11 = load_be(input, 11); + uint64_t W12 = load_be(input, 12); + uint64_t W13 = load_be(input, 13); + uint64_t W14 = load_be(input, 14); + uint64_t W15 = load_be(input, 15); + + SHA2_64_F(A, B, C, D, E, F, G, H, W00, W14, W09, W01, 0x428A2F98D728AE22); + SHA2_64_F(H, A, B, C, D, E, F, G, W01, W15, W10, W02, 0x7137449123EF65CD); + SHA2_64_F(G, H, A, B, C, D, E, F, W02, W00, W11, W03, 0xB5C0FBCFEC4D3B2F); + SHA2_64_F(F, G, H, A, B, C, D, E, W03, W01, W12, W04, 0xE9B5DBA58189DBBC); + SHA2_64_F(E, F, G, H, A, B, C, D, W04, W02, W13, W05, 0x3956C25BF348B538); + SHA2_64_F(D, E, F, G, H, A, B, C, W05, W03, W14, W06, 0x59F111F1B605D019); + SHA2_64_F(C, D, E, F, G, H, A, B, W06, W04, W15, W07, 0x923F82A4AF194F9B); + SHA2_64_F(B, C, D, E, F, G, H, A, W07, W05, W00, W08, 0xAB1C5ED5DA6D8118); + SHA2_64_F(A, B, C, D, E, F, G, H, W08, W06, W01, W09, 0xD807AA98A3030242); + SHA2_64_F(H, A, B, C, D, E, F, G, W09, W07, W02, W10, 0x12835B0145706FBE); + SHA2_64_F(G, H, A, B, C, D, E, F, W10, W08, W03, W11, 0x243185BE4EE4B28C); + SHA2_64_F(F, G, H, A, B, C, D, E, W11, W09, W04, W12, 0x550C7DC3D5FFB4E2); + SHA2_64_F(E, F, G, H, A, B, C, D, W12, W10, W05, W13, 0x72BE5D74F27B896F); + SHA2_64_F(D, E, F, G, H, A, B, C, W13, W11, W06, W14, 0x80DEB1FE3B1696B1); + SHA2_64_F(C, D, E, F, G, H, A, B, W14, W12, W07, W15, 0x9BDC06A725C71235); + SHA2_64_F(B, C, D, E, F, G, H, A, W15, W13, W08, W00, 0xC19BF174CF692694); + SHA2_64_F(A, B, C, D, E, F, G, H, W00, W14, W09, W01, 0xE49B69C19EF14AD2); + SHA2_64_F(H, A, B, C, D, E, F, G, W01, W15, W10, W02, 0xEFBE4786384F25E3); + SHA2_64_F(G, H, A, B, C, D, E, F, W02, W00, W11, W03, 0x0FC19DC68B8CD5B5); + SHA2_64_F(F, G, H, A, B, C, D, E, W03, W01, W12, W04, 0x240CA1CC77AC9C65); + SHA2_64_F(E, F, G, H, A, B, C, D, W04, W02, W13, W05, 0x2DE92C6F592B0275); + SHA2_64_F(D, E, F, G, H, A, B, C, W05, W03, W14, W06, 0x4A7484AA6EA6E483); + SHA2_64_F(C, D, E, F, G, H, A, B, W06, W04, W15, W07, 0x5CB0A9DCBD41FBD4); + SHA2_64_F(B, C, D, E, F, G, H, A, W07, W05, W00, W08, 0x76F988DA831153B5); + SHA2_64_F(A, B, C, D, E, F, G, H, W08, W06, W01, W09, 0x983E5152EE66DFAB); + SHA2_64_F(H, A, B, C, D, E, F, G, W09, W07, W02, W10, 0xA831C66D2DB43210); + SHA2_64_F(G, H, A, B, C, D, E, F, W10, W08, W03, W11, 0xB00327C898FB213F); + SHA2_64_F(F, G, H, A, B, C, D, E, W11, W09, W04, W12, 0xBF597FC7BEEF0EE4); + SHA2_64_F(E, F, G, H, A, B, C, D, W12, W10, W05, W13, 0xC6E00BF33DA88FC2); + SHA2_64_F(D, E, F, G, H, A, B, C, W13, W11, W06, W14, 0xD5A79147930AA725); + SHA2_64_F(C, D, E, F, G, H, A, B, W14, W12, W07, W15, 0x06CA6351E003826F); + SHA2_64_F(B, C, D, E, F, G, H, A, W15, W13, W08, W00, 0x142929670A0E6E70); + SHA2_64_F(A, B, C, D, E, F, G, H, W00, W14, W09, W01, 0x27B70A8546D22FFC); + SHA2_64_F(H, A, B, C, D, E, F, G, W01, W15, W10, W02, 0x2E1B21385C26C926); + SHA2_64_F(G, H, A, B, C, D, E, F, W02, W00, W11, W03, 0x4D2C6DFC5AC42AED); + SHA2_64_F(F, G, H, A, B, C, D, E, W03, W01, W12, W04, 0x53380D139D95B3DF); + SHA2_64_F(E, F, G, H, A, B, C, D, W04, W02, W13, W05, 0x650A73548BAF63DE); + SHA2_64_F(D, E, F, G, H, A, B, C, W05, W03, W14, W06, 0x766A0ABB3C77B2A8); + SHA2_64_F(C, D, E, F, G, H, A, B, W06, W04, W15, W07, 0x81C2C92E47EDAEE6); + SHA2_64_F(B, C, D, E, F, G, H, A, W07, W05, W00, W08, 0x92722C851482353B); + SHA2_64_F(A, B, C, D, E, F, G, H, W08, W06, W01, W09, 0xA2BFE8A14CF10364); + SHA2_64_F(H, A, B, C, D, E, F, G, W09, W07, W02, W10, 0xA81A664BBC423001); + SHA2_64_F(G, H, A, B, C, D, E, F, W10, W08, W03, W11, 0xC24B8B70D0F89791); + SHA2_64_F(F, G, H, A, B, C, D, E, W11, W09, W04, W12, 0xC76C51A30654BE30); + SHA2_64_F(E, F, G, H, A, B, C, D, W12, W10, W05, W13, 0xD192E819D6EF5218); + SHA2_64_F(D, E, F, G, H, A, B, C, W13, W11, W06, W14, 0xD69906245565A910); + SHA2_64_F(C, D, E, F, G, H, A, B, W14, W12, W07, W15, 0xF40E35855771202A); + SHA2_64_F(B, C, D, E, F, G, H, A, W15, W13, W08, W00, 0x106AA07032BBD1B8); + SHA2_64_F(A, B, C, D, E, F, G, H, W00, W14, W09, W01, 0x19A4C116B8D2D0C8); + SHA2_64_F(H, A, B, C, D, E, F, G, W01, W15, W10, W02, 0x1E376C085141AB53); + SHA2_64_F(G, H, A, B, C, D, E, F, W02, W00, W11, W03, 0x2748774CDF8EEB99); + SHA2_64_F(F, G, H, A, B, C, D, E, W03, W01, W12, W04, 0x34B0BCB5E19B48A8); + SHA2_64_F(E, F, G, H, A, B, C, D, W04, W02, W13, W05, 0x391C0CB3C5C95A63); + SHA2_64_F(D, E, F, G, H, A, B, C, W05, W03, W14, W06, 0x4ED8AA4AE3418ACB); + SHA2_64_F(C, D, E, F, G, H, A, B, W06, W04, W15, W07, 0x5B9CCA4F7763E373); + SHA2_64_F(B, C, D, E, F, G, H, A, W07, W05, W00, W08, 0x682E6FF3D6B2B8A3); + SHA2_64_F(A, B, C, D, E, F, G, H, W08, W06, W01, W09, 0x748F82EE5DEFB2FC); + SHA2_64_F(H, A, B, C, D, E, F, G, W09, W07, W02, W10, 0x78A5636F43172F60); + SHA2_64_F(G, H, A, B, C, D, E, F, W10, W08, W03, W11, 0x84C87814A1F0AB72); + SHA2_64_F(F, G, H, A, B, C, D, E, W11, W09, W04, W12, 0x8CC702081A6439EC); + SHA2_64_F(E, F, G, H, A, B, C, D, W12, W10, W05, W13, 0x90BEFFFA23631E28); + SHA2_64_F(D, E, F, G, H, A, B, C, W13, W11, W06, W14, 0xA4506CEBDE82BDE9); + SHA2_64_F(C, D, E, F, G, H, A, B, W14, W12, W07, W15, 0xBEF9A3F7B2C67915); + SHA2_64_F(B, C, D, E, F, G, H, A, W15, W13, W08, W00, 0xC67178F2E372532B); + SHA2_64_F(A, B, C, D, E, F, G, H, W00, W14, W09, W01, 0xCA273ECEEA26619C); + SHA2_64_F(H, A, B, C, D, E, F, G, W01, W15, W10, W02, 0xD186B8C721C0C207); + SHA2_64_F(G, H, A, B, C, D, E, F, W02, W00, W11, W03, 0xEADA7DD6CDE0EB1E); + SHA2_64_F(F, G, H, A, B, C, D, E, W03, W01, W12, W04, 0xF57D4F7FEE6ED178); + SHA2_64_F(E, F, G, H, A, B, C, D, W04, W02, W13, W05, 0x06F067AA72176FBA); + SHA2_64_F(D, E, F, G, H, A, B, C, W05, W03, W14, W06, 0x0A637DC5A2C898A6); + SHA2_64_F(C, D, E, F, G, H, A, B, W06, W04, W15, W07, 0x113F9804BEF90DAE); + SHA2_64_F(B, C, D, E, F, G, H, A, W07, W05, W00, W08, 0x1B710B35131C471B); + SHA2_64_F(A, B, C, D, E, F, G, H, W08, W06, W01, W09, 0x28DB77F523047D84); + SHA2_64_F(H, A, B, C, D, E, F, G, W09, W07, W02, W10, 0x32CAAB7B40C72493); + SHA2_64_F(G, H, A, B, C, D, E, F, W10, W08, W03, W11, 0x3C9EBE0A15C9BEBC); + SHA2_64_F(F, G, H, A, B, C, D, E, W11, W09, W04, W12, 0x431D67C49C100D4C); + SHA2_64_F(E, F, G, H, A, B, C, D, W12, W10, W05, W13, 0x4CC5D4BECB3E42B6); + SHA2_64_F(D, E, F, G, H, A, B, C, W13, W11, W06, W14, 0x597F299CFC657E2A); + SHA2_64_F(C, D, E, F, G, H, A, B, W14, W12, W07, W15, 0x5FCB6FAB3AD6FAEC); + SHA2_64_F(B, C, D, E, F, G, H, A, W15, W13, W08, W00, 0x6C44198C4A475817); + + A = (digest[0] += A); + B = (digest[1] += B); + C = (digest[2] += C); + D = (digest[3] += D); + E = (digest[4] += E); + F = (digest[5] += F); + G = (digest[6] += G); + H = (digest[7] += H); + + input += 128; + } + } + +} + +void SHA_512_256::compress_n(const uint8_t input[], size_t blocks) + { + SHA64_compress(m_digest, input, blocks); + } + +void SHA_384::compress_n(const uint8_t input[], size_t blocks) + { + SHA64_compress(m_digest, input, blocks); + } + +void SHA_512::compress_n(const uint8_t input[], size_t blocks) + { + SHA64_compress(m_digest, input, blocks); + } + +void SHA_512_256::copy_out(uint8_t output[]) + { + copy_out_vec_be(output, output_length(), m_digest); + } + +void SHA_384::copy_out(uint8_t output[]) + { + copy_out_vec_be(output, output_length(), m_digest); + } + +void SHA_512::copy_out(uint8_t output[]) + { + copy_out_vec_be(output, output_length(), m_digest); + } + +void SHA_512_256::clear() + { + MDx_HashFunction::clear(); + m_digest[0] = 0x22312194FC2BF72C; + m_digest[1] = 0x9F555FA3C84C64C2; + m_digest[2] = 0x2393B86B6F53B151; + m_digest[3] = 0x963877195940EABD; + m_digest[4] = 0x96283EE2A88EFFE3; + m_digest[5] = 0xBE5E1E2553863992; + m_digest[6] = 0x2B0199FC2C85B8AA; + m_digest[7] = 0x0EB72DDC81C52CA2; + } + +void SHA_384::clear() + { + MDx_HashFunction::clear(); + m_digest[0] = 0xCBBB9D5DC1059ED8; + m_digest[1] = 0x629A292A367CD507; + m_digest[2] = 0x9159015A3070DD17; + m_digest[3] = 0x152FECD8F70E5939; + m_digest[4] = 0x67332667FFC00B31; + m_digest[5] = 0x8EB44A8768581511; + m_digest[6] = 0xDB0C2E0D64F98FA7; + m_digest[7] = 0x47B5481DBEFA4FA4; + } + +void SHA_512::clear() + { + MDx_HashFunction::clear(); + m_digest[0] = 0x6A09E667F3BCC908; + m_digest[1] = 0xBB67AE8584CAA73B; + m_digest[2] = 0x3C6EF372FE94F82B; + m_digest[3] = 0xA54FF53A5F1D36F1; + m_digest[4] = 0x510E527FADE682D1; + m_digest[5] = 0x9B05688C2B3E6C1F; + m_digest[6] = 0x1F83D9ABFB41BD6B; + m_digest[7] = 0x5BE0CD19137E2179; + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/hash/sha2_64/sha2_64.h b/src/libs/3rdparty/botan/src/lib/hash/sha2_64/sha2_64.h new file mode 100644 index 0000000000..cbe1ad70bb --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/hash/sha2_64/sha2_64.h @@ -0,0 +1,82 @@ +/* +* SHA-{384,512} +* (C) 1999-2010,2015 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_SHA_64BIT_H_ +#define BOTAN_SHA_64BIT_H_ + +#include + +namespace Botan { + +/** +* SHA-384 +*/ +class BOTAN_PUBLIC_API(2,0) SHA_384 final : public MDx_HashFunction + { + public: + std::string name() const override { return "SHA-384"; } + size_t output_length() const override { return 48; } + HashFunction* clone() const override { return new SHA_384; } + std::unique_ptr copy_state() const override; + + void clear() override; + + SHA_384() : MDx_HashFunction(128, true, true, 16), m_digest(8) + { clear(); } + private: + void compress_n(const uint8_t[], size_t blocks) override; + void copy_out(uint8_t[]) override; + + secure_vector m_digest; + }; + +/** +* SHA-512 +*/ +class BOTAN_PUBLIC_API(2,0) SHA_512 final : public MDx_HashFunction + { + public: + std::string name() const override { return "SHA-512"; } + size_t output_length() const override { return 64; } + HashFunction* clone() const override { return new SHA_512; } + std::unique_ptr copy_state() const override; + + void clear() override; + + SHA_512() : MDx_HashFunction(128, true, true, 16), m_digest(8) + { clear(); } + private: + void compress_n(const uint8_t[], size_t blocks) override; + void copy_out(uint8_t[]) override; + + secure_vector m_digest; + }; + +/** +* SHA-512/256 +*/ +class BOTAN_PUBLIC_API(2,0) SHA_512_256 final : public MDx_HashFunction + { + public: + std::string name() const override { return "SHA-512-256"; } + size_t output_length() const override { return 32; } + HashFunction* clone() const override { return new SHA_512_256; } + std::unique_ptr copy_state() const override; + + void clear() override; + + SHA_512_256() : MDx_HashFunction(128, true, true, 16), m_digest(8) { clear(); } + private: + void compress_n(const uint8_t[], size_t blocks) override; + void copy_out(uint8_t[]) override; + + secure_vector m_digest; + }; + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/kdf/info.txt b/src/libs/3rdparty/botan/src/lib/kdf/info.txt new file mode 100644 index 0000000000..81567300f5 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/kdf/info.txt @@ -0,0 +1,12 @@ + +KDF_BASE -> 20131128 + + + +mac +hash + + + +kdf.h + diff --git a/src/libs/3rdparty/botan/src/lib/kdf/kdf.cpp b/src/libs/3rdparty/botan/src/lib/kdf/kdf.cpp new file mode 100644 index 0000000000..fbe24462ad --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/kdf/kdf.cpp @@ -0,0 +1,251 @@ +/* +* KDF Retrieval +* (C) 1999-2007 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include +#include + +#if defined(BOTAN_HAS_HKDF) +#include +#endif + +#if defined(BOTAN_HAS_KDF1) +#include +#endif + +#if defined(BOTAN_HAS_KDF2) +#include +#endif + +#if defined(BOTAN_HAS_KDF1_18033) +#include +#endif + +#if defined(BOTAN_HAS_TLS_V10_PRF) || defined(BOTAN_HAS_TLS_V12_PRF) +#include +#endif + +#if defined(BOTAN_HAS_X942_PRF) +#include +#endif + +#if defined(BOTAN_HAS_SP800_108) +#include +#endif + +#if defined(BOTAN_HAS_SP800_56A) +#include +#endif + +#if defined(BOTAN_HAS_SP800_56C) +#include +#endif + +namespace Botan { + +namespace { + +template +std::unique_ptr +kdf_create_mac_or_hash(const std::string& nm) + { + if(auto mac = MessageAuthenticationCode::create(nm)) + return std::unique_ptr(new KDF_Type(mac.release())); + + if(auto mac = MessageAuthenticationCode::create("HMAC(" + nm + ")")) + return std::unique_ptr(new KDF_Type(mac.release())); + + return nullptr; + } + +} + +std::unique_ptr KDF::create(const std::string& algo_spec, + const std::string& provider) + { + const SCAN_Name req(algo_spec); + +#if defined(BOTAN_HAS_HKDF) + if(req.algo_name() == "HKDF" && req.arg_count() == 1) + { + if(provider.empty() || provider == "base") + { + return kdf_create_mac_or_hash(req.arg(0)); + } + } + + if(req.algo_name() == "HKDF-Extract" && req.arg_count() == 1) + { + if(provider.empty() || provider == "base") + { + return kdf_create_mac_or_hash(req.arg(0)); + } + } + + if(req.algo_name() == "HKDF-Expand" && req.arg_count() == 1) + { + if(provider.empty() || provider == "base") + { + return kdf_create_mac_or_hash(req.arg(0)); + } + } +#endif + +#if defined(BOTAN_HAS_KDF2) + if(req.algo_name() == "KDF2" && req.arg_count() == 1) + { + if(provider.empty() || provider == "base") + { + if(auto hash = HashFunction::create(req.arg(0))) + return std::unique_ptr(new KDF2(hash.release())); + } + } +#endif + +#if defined(BOTAN_HAS_KDF1_18033) + if(req.algo_name() == "KDF1-18033" && req.arg_count() == 1) + { + if(provider.empty() || provider == "base") + { + if(auto hash = HashFunction::create(req.arg(0))) + return std::unique_ptr(new KDF1_18033(hash.release())); + } + } +#endif + +#if defined(BOTAN_HAS_KDF1) + if(req.algo_name() == "KDF1" && req.arg_count() == 1) + { + if(provider.empty() || provider == "base") + { + if(auto hash = HashFunction::create(req.arg(0))) + return std::unique_ptr(new KDF1(hash.release())); + } + } +#endif + +#if defined(BOTAN_HAS_TLS_V10_PRF) + if(req.algo_name() == "TLS-PRF" && req.arg_count() == 0) + { + if(provider.empty() || provider == "base") + { + return std::unique_ptr(new TLS_PRF); + } + } +#endif + +#if defined(BOTAN_HAS_TLS_V12_PRF) + if(req.algo_name() == "TLS-12-PRF" && req.arg_count() == 1) + { + if(provider.empty() || provider == "base") + { + return kdf_create_mac_or_hash(req.arg(0)); + } + } +#endif + +#if defined(BOTAN_HAS_X942_PRF) + if(req.algo_name() == "X9.42-PRF" && req.arg_count() == 1) + { + if(provider.empty() || provider == "base") + { + return std::unique_ptr(new X942_PRF(req.arg(0))); + } + } +#endif + +#if defined(BOTAN_HAS_SP800_108) + if(req.algo_name() == "SP800-108-Counter" && req.arg_count() == 1) + { + if(provider.empty() || provider == "base") + { + return kdf_create_mac_or_hash(req.arg(0)); + } + } + + if(req.algo_name() == "SP800-108-Feedback" && req.arg_count() == 1) + { + if(provider.empty() || provider == "base") + { + return kdf_create_mac_or_hash(req.arg(0)); + } + } + + if(req.algo_name() == "SP800-108-Pipeline" && req.arg_count() == 1) + { + if(provider.empty() || provider == "base") + { + return kdf_create_mac_or_hash(req.arg(0)); + } + } +#endif + +#if defined(BOTAN_HAS_SP800_56A) + if(req.algo_name() == "SP800-56A" && req.arg_count() == 1) + { + if(auto hash = HashFunction::create(req.arg(0))) + return std::unique_ptr(new SP800_56A_Hash(hash.release())); + if(auto mac = MessageAuthenticationCode::create(req.arg(0))) + return std::unique_ptr(new SP800_56A_HMAC(mac.release())); + } +#endif + +#if defined(BOTAN_HAS_SP800_56C) + if(req.algo_name() == "SP800-56C" && req.arg_count() == 1) + { + std::unique_ptr exp(kdf_create_mac_or_hash(req.arg(0))); + if(exp) + { + if(auto mac = MessageAuthenticationCode::create(req.arg(0))) + return std::unique_ptr(new SP800_56C(mac.release(), exp.release())); + + if(auto mac = MessageAuthenticationCode::create("HMAC(" + req.arg(0) + ")")) + return std::unique_ptr(new SP800_56C(mac.release(), exp.release())); + } + } +#endif + + BOTAN_UNUSED(req); + BOTAN_UNUSED(provider); + + return nullptr; + } + +//static +std::unique_ptr +KDF::create_or_throw(const std::string& algo, + const std::string& provider) + { + if(auto kdf = KDF::create(algo, provider)) + { + return kdf; + } + throw Lookup_Error("KDF", algo, provider); + } + +std::vector KDF::providers(const std::string& algo_spec) + { + return probe_providers_of(algo_spec, { "base" }); + } + +KDF* get_kdf(const std::string& algo_spec) + { + SCAN_Name request(algo_spec); + + if(request.algo_name() == "Raw") + return nullptr; // No KDF + + //return KDF::create_or_throw(algo_spec).release(); + auto kdf = KDF::create(algo_spec); + if(!kdf) + throw Algorithm_Not_Found(algo_spec); + return kdf.release(); + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/kdf/kdf.h b/src/libs/3rdparty/botan/src/lib/kdf/kdf.h new file mode 100644 index 0000000000..dd4cfedf6d --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/kdf/kdf.h @@ -0,0 +1,196 @@ +/* +* Key Derivation Function interfaces +* (C) 1999-2007 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_KDF_BASE_H_ +#define BOTAN_KDF_BASE_H_ + +#include +#include +#include + +namespace Botan { + +/** +* Key Derivation Function +*/ +class BOTAN_PUBLIC_API(2,0) KDF + { + public: + virtual ~KDF() = default; + + /** + * 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 + 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 + 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 providers(const std::string& algo_spec); + + /** + * @return KDF name + */ + virtual std::string name() const = 0; + + /** + * Derive a key + * @param key buffer holding the derived key, must be of length key_len + * @param key_len the desired output length in bytes + * @param secret the secret input + * @param secret_len size of secret in bytes + * @param salt a diversifier + * @param salt_len size of salt in bytes + * @param label purpose for the derived keying material + * @param label_len size of label in bytes + * @return the derived key + */ + virtual size_t kdf(uint8_t key[], size_t key_len, + const uint8_t secret[], size_t secret_len, + const uint8_t salt[], size_t salt_len, + const uint8_t label[], size_t label_len) const = 0; + + /** + * Derive a key + * @param key_len the desired output length in bytes + * @param secret the secret input + * @param secret_len size of secret in bytes + * @param salt a diversifier + * @param salt_len size of salt in bytes + * @param label purpose for the derived keying material + * @param label_len size of label in bytes + * @return the derived key + */ + secure_vector derive_key(size_t key_len, + const uint8_t secret[], + size_t secret_len, + const uint8_t salt[], + size_t salt_len, + const uint8_t label[] = nullptr, + size_t label_len = 0) const + { + secure_vector key(key_len); + key.resize(kdf(key.data(), key.size(), secret, secret_len, salt, salt_len, label, label_len)); + return key; + } + + /** + * Derive a key + * @param key_len the desired output length in bytes + * @param secret the secret input + * @param salt a diversifier + * @param label purpose for the derived keying material + * @return the derived key + */ + secure_vector derive_key(size_t key_len, + const secure_vector& secret, + const std::string& salt = "", + const std::string& label = "") const + { + return derive_key(key_len, secret.data(), secret.size(), + cast_char_ptr_to_uint8(salt.data()), + salt.length(), + cast_char_ptr_to_uint8(label.data()), + label.length()); + + } + + /** + * Derive a key + * @param key_len the desired output length in bytes + * @param secret the secret input + * @param salt a diversifier + * @param label purpose for the derived keying material + * @return the derived key + */ + template + secure_vector derive_key(size_t key_len, + const std::vector& secret, + const std::vector& salt, + const std::vector& label) const + { + return derive_key(key_len, + secret.data(), secret.size(), + salt.data(), salt.size(), + label.data(), label.size()); + } + + /** + * Derive a key + * @param key_len the desired output length in bytes + * @param secret the secret input + * @param salt a diversifier + * @param salt_len size of salt in bytes + * @param label purpose for the derived keying material + * @return the derived key + */ + secure_vector derive_key(size_t key_len, + const secure_vector& secret, + const uint8_t salt[], + size_t salt_len, + const std::string& label = "") const + { + return derive_key(key_len, + secret.data(), secret.size(), + salt, salt_len, + cast_char_ptr_to_uint8(label.data()), + label.size()); + } + + /** + * Derive a key + * @param key_len the desired output length in bytes + * @param secret the secret input + * @param secret_len size of secret in bytes + * @param salt a diversifier + * @param label purpose for the derived keying material + * @return the derived key + */ + secure_vector derive_key(size_t key_len, + const uint8_t secret[], + size_t secret_len, + const std::string& salt = "", + const std::string& label = "") const + { + return derive_key(key_len, secret, secret_len, + cast_char_ptr_to_uint8(salt.data()), + salt.length(), + cast_char_ptr_to_uint8(label.data()), + label.length()); + } + + /** + * @return new object representing the same algorithm as *this + */ + virtual KDF* clone() const = 0; + }; + +/** +* Factory method for KDF (key derivation function) +* @param algo_spec the name of the KDF to create +* @return pointer to newly allocated object of that type +*/ +BOTAN_PUBLIC_API(2,0) KDF* get_kdf(const std::string& algo_spec); + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/mac/hmac/hmac.cpp b/src/libs/3rdparty/botan/src/lib/mac/hmac/hmac.cpp new file mode 100644 index 0000000000..72c617c5b4 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/mac/hmac/hmac.cpp @@ -0,0 +1,107 @@ +/* +* HMAC +* (C) 1999-2007,2014 Jack Lloyd +* 2007 Yves Jerschow +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include + +namespace Botan { + +/* +* Update a HMAC Calculation +*/ +void HMAC::add_data(const uint8_t input[], size_t length) + { + verify_key_set(m_ikey.empty() == false); + m_hash->update(input, length); + } + +/* +* Finalize a HMAC Calculation +*/ +void HMAC::final_result(uint8_t mac[]) + { + verify_key_set(m_okey.empty() == false); + m_hash->final(mac); + m_hash->update(m_okey); + m_hash->update(mac, output_length()); + m_hash->final(mac); + m_hash->update(m_ikey); + } + +Key_Length_Specification HMAC::key_spec() const + { + // Support very long lengths for things like PBKDF2 and the TLS PRF + return Key_Length_Specification(0, 4096); + } + +/* +* HMAC Key Schedule +*/ +void HMAC::key_schedule(const uint8_t key[], size_t length) + { + m_hash->clear(); + + m_ikey.resize(m_hash->hash_block_size()); + m_okey.resize(m_hash->hash_block_size()); + + const uint8_t ipad = 0x36; + const uint8_t opad = 0x5C; + + std::fill(m_ikey.begin(), m_ikey.end(), ipad); + std::fill(m_okey.begin(), m_okey.end(), opad); + + if(length > m_hash->hash_block_size()) + { + secure_vector hmac_key = m_hash->process(key, length); + xor_buf(m_ikey, hmac_key, hmac_key.size()); + xor_buf(m_okey, hmac_key, hmac_key.size()); + } + else + { + xor_buf(m_ikey, key, length); + xor_buf(m_okey, key, length); + } + + m_hash->update(m_ikey); + } + +/* +* Clear memory of sensitive data +*/ +void HMAC::clear() + { + m_hash->clear(); + zap(m_ikey); + zap(m_okey); + } + +/* +* Return the name of this type +*/ +std::string HMAC::name() const + { + return "HMAC(" + m_hash->name() + ")"; + } + +/* +* Return a clone of this object +*/ +MessageAuthenticationCode* HMAC::clone() const + { + return new HMAC(m_hash->clone()); + } + +/* +* HMAC Constructor +*/ +HMAC::HMAC(HashFunction* hash) : m_hash(hash) + { + BOTAN_ARG_CHECK(m_hash->hash_block_size() > 0, + "HMAC is not compatible with this hash function"); + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/mac/hmac/hmac.h b/src/libs/3rdparty/botan/src/lib/mac/hmac/hmac.h new file mode 100644 index 0000000000..8001594324 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/mac/hmac/hmac.h @@ -0,0 +1,48 @@ +/* +* HMAC +* (C) 1999-2007,2014 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_HMAC_H_ +#define BOTAN_HMAC_H_ + +#include +#include + +namespace Botan { + +/** +* HMAC +*/ +class BOTAN_PUBLIC_API(2,0) HMAC final : public MessageAuthenticationCode + { + public: + void clear() override; + std::string name() const override; + MessageAuthenticationCode* clone() const override; + + size_t output_length() const override { return m_hash->output_length(); } + + Key_Length_Specification key_spec() const override; + + /** + * @param hash the hash to use for HMACing + */ + explicit HMAC(HashFunction* hash); + + HMAC(const HMAC&) = delete; + HMAC& operator=(const HMAC&) = delete; + private: + void add_data(const uint8_t[], size_t) override; + void final_result(uint8_t[]) override; + void key_schedule(const uint8_t[], size_t) override; + + std::unique_ptr m_hash; + secure_vector m_ikey, m_okey; + }; + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/mac/hmac/info.txt b/src/libs/3rdparty/botan/src/lib/mac/hmac/info.txt new file mode 100644 index 0000000000..50dc665dc9 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/mac/hmac/info.txt @@ -0,0 +1,7 @@ + +HMAC -> 20131128 + + + +hash + diff --git a/src/libs/3rdparty/botan/src/lib/mac/info.txt b/src/libs/3rdparty/botan/src/lib/mac/info.txt new file mode 100644 index 0000000000..7aef92b879 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/mac/info.txt @@ -0,0 +1,7 @@ + +MAC -> 20150626 + + + +mac.h + diff --git a/src/libs/3rdparty/botan/src/lib/mac/mac.cpp b/src/libs/3rdparty/botan/src/lib/mac/mac.cpp new file mode 100644 index 0000000000..4c3fc5230e --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/mac/mac.cpp @@ -0,0 +1,171 @@ +/* +* Message Authentication Code base class +* (C) 1999-2008 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include + +#if defined(BOTAN_HAS_CBC_MAC) + #include +#endif + +#if defined(BOTAN_HAS_CMAC) + #include +#endif + +#if defined(BOTAN_HAS_GMAC) + #include + #include +#endif + +#if defined(BOTAN_HAS_HMAC) + #include + #include +#endif + +#if defined(BOTAN_HAS_POLY1305) + #include +#endif + +#if defined(BOTAN_HAS_SIPHASH) + #include +#endif + +#if defined(BOTAN_HAS_ANSI_X919_MAC) + #include +#endif + +namespace Botan { + +std::unique_ptr +MessageAuthenticationCode::create(const std::string& algo_spec, + const std::string& provider) + { + const SCAN_Name req(algo_spec); + +#if defined(BOTAN_HAS_GMAC) + if(req.algo_name() == "GMAC" && req.arg_count() == 1) + { + if(provider.empty() || provider == "base") + { + if(auto bc = BlockCipher::create(req.arg(0))) + return std::unique_ptr(new GMAC(bc.release())); + } + } +#endif + +#if defined(BOTAN_HAS_HMAC) + if(req.algo_name() == "HMAC" && req.arg_count() == 1) + { + // TODO OpenSSL + if(provider.empty() || provider == "base") + { + if(auto h = HashFunction::create(req.arg(0))) + return std::unique_ptr(new HMAC(h.release())); + } + } +#endif + +#if defined(BOTAN_HAS_POLY1305) + if(req.algo_name() == "Poly1305" && req.arg_count() == 0) + { + if(provider.empty() || provider == "base") + return std::unique_ptr(new Poly1305); + } +#endif + +#if defined(BOTAN_HAS_SIPHASH) + if(req.algo_name() == "SipHash") + { + if(provider.empty() || provider == "base") + { + return std::unique_ptr( + new SipHash(req.arg_as_integer(0, 2), req.arg_as_integer(1, 4))); + } + } +#endif + +#if defined(BOTAN_HAS_CMAC) + if((req.algo_name() == "CMAC" || req.algo_name() == "OMAC") && req.arg_count() == 1) + { + // TODO: OpenSSL CMAC + if(provider.empty() || provider == "base") + { + if(auto bc = BlockCipher::create(req.arg(0))) + return std::unique_ptr(new CMAC(bc.release())); + } + } +#endif + + +#if defined(BOTAN_HAS_CBC_MAC) + if(req.algo_name() == "CBC-MAC" && req.arg_count() == 1) + { + if(provider.empty() || provider == "base") + { + if(auto bc = BlockCipher::create(req.arg(0))) + return std::unique_ptr(new CBC_MAC(bc.release())); + } + } +#endif + +#if defined(BOTAN_HAS_ANSI_X919_MAC) + if(req.algo_name() == "X9.19-MAC") + { + if(provider.empty() || provider == "base") + { + return std::unique_ptr(new ANSI_X919_MAC); + } + } +#endif + + BOTAN_UNUSED(req); + BOTAN_UNUSED(provider); + + return nullptr; + } + +std::vector +MessageAuthenticationCode::providers(const std::string& algo_spec) + { + return probe_providers_of(algo_spec, {"base", "openssl"}); + } + +//static +std::unique_ptr +MessageAuthenticationCode::create_or_throw(const std::string& algo, + const std::string& provider) + { + if(auto mac = MessageAuthenticationCode::create(algo, provider)) + { + return mac; + } + throw Lookup_Error("MAC", algo, provider); + } + +void MessageAuthenticationCode::start_msg(const uint8_t nonce[], size_t nonce_len) + { + BOTAN_UNUSED(nonce); + if(nonce_len > 0) + throw Invalid_IV_Length(name(), nonce_len); + } + +/* +* Default (deterministic) MAC verification operation +*/ +bool MessageAuthenticationCode::verify_mac(const uint8_t mac[], size_t length) + { + secure_vector our_mac = final(); + + if(our_mac.size() != length) + return false; + + return constant_time_compare(our_mac.data(), mac, length); + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/mac/mac.h b/src/libs/3rdparty/botan/src/lib/mac/mac.h new file mode 100644 index 0000000000..de30b7dbb2 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/mac/mac.h @@ -0,0 +1,143 @@ +/* +* Base class for message authentiction codes +* (C) 1999-2007 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_MESSAGE_AUTH_CODE_BASE_H_ +#define BOTAN_MESSAGE_AUTH_CODE_BASE_H_ + +#include +#include +#include +#include + +namespace Botan { + +/** +* This class represents Message Authentication Code (MAC) objects. +*/ +class BOTAN_PUBLIC_API(2,0) MessageAuthenticationCode : public Buffered_Computation, + public SymmetricAlgorithm + { + 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 use + * @return a null pointer if the algo/provider combination cannot be found + */ + static std::unique_ptr + create(const std::string& algo_spec, + const std::string& provider = ""); + + /* + * 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 use + * Throws a Lookup_Error if algo/provider combination cannot be found + */ + static std::unique_ptr + 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 providers(const std::string& algo_spec); + + virtual ~MessageAuthenticationCode() = default; + + /** + * Prepare for processing a message under the specified nonce + * + * Most MACs neither require nor support a nonce; for these algorithms + * calling `start_msg` is optional and calling it with anything other than + * an empty string is an error. One MAC which *requires* a per-message + * nonce be specified is GMAC. + * + * @param nonce the message nonce bytes + * @param nonce_len the size of len in bytes + * Default implementation simply rejects all non-empty nonces + * since most hash/MAC algorithms do not support randomization + */ + virtual void start_msg(const uint8_t nonce[], size_t nonce_len); + + /** + * Begin processing a message with a nonce + * + * @param nonce the per message nonce + */ + template + void start(const std::vector& nonce) + { + start_msg(nonce.data(), nonce.size()); + } + + /** + * Begin processing a message. + * @param nonce the per message nonce + * @param nonce_len length of nonce + */ + void start(const uint8_t nonce[], size_t nonce_len) + { + start_msg(nonce, nonce_len); + } + + /** + * Begin processing a message. + */ + void start() + { + return start_msg(nullptr, 0); + } + + /** + * Verify a MAC. + * @param in the MAC to verify as a byte array + * @param length the length of param in + * @return true if the MAC is valid, false otherwise + */ + virtual bool verify_mac(const uint8_t in[], size_t length); + + /** + * Verify a MAC. + * @param in the MAC to verify as a byte array + * @return true if the MAC is valid, false otherwise + */ + virtual bool verify_mac(const std::vector& in) + { + return verify_mac(in.data(), in.size()); + } + + /** + * Verify a MAC. + * @param in the MAC to verify as a byte array + * @return true if the MAC is valid, false otherwise + */ + virtual bool verify_mac(const secure_vector& in) + { + return verify_mac(in.data(), in.size()); + } + + /** + * Get a new object representing the same algorithm as *this + */ + virtual MessageAuthenticationCode* clone() const = 0; + + /** + * @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"; } + + }; + +typedef MessageAuthenticationCode MAC; + +} + +#endif 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 new file mode 100644 index 0000000000..c428199659 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/math/bigint/big_code.cpp @@ -0,0 +1,166 @@ +/* +* BigInt Encoding/Decoding +* (C) 1999-2010,2012 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include + +namespace Botan { + +/* +* Encode a BigInt +*/ +void BigInt::encode(uint8_t output[], const BigInt& n, Base base) + { + if(base == Binary) + { + n.binary_encode(output); + } + else if(base == Hexadecimal) + { + secure_vector binary(n.encoded_size(Binary)); + n.binary_encode(binary.data()); + + hex_encode(cast_uint8_ptr_to_char(output), + binary.data(), binary.size()); + } + else if(base == Decimal) + { + BigInt copy = n; + BigInt remainder; + copy.set_sign(Positive); + const size_t output_size = n.encoded_size(Decimal); + for(size_t j = 0; j != output_size; ++j) + { + divide(copy, 10, copy, remainder); + output[output_size - 1 - j] = + Charset::digit2char(static_cast(remainder.word_at(0))); + if(copy.is_zero()) + break; + } + } + else + throw Invalid_Argument("Unknown BigInt encoding method"); + } + +/* +* Encode a BigInt +*/ +std::vector BigInt::encode(const BigInt& n, Base base) + { + std::vector 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'; + return output; + } + +/* +* Encode a BigInt +*/ +secure_vector BigInt::encode_locked(const BigInt& n, Base base) + { + secure_vector 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'; + return output; + } + +/* +* Encode a BigInt, with leading 0s if needed +*/ +secure_vector BigInt::encode_1363(const BigInt& n, size_t bytes) + { + secure_vector output(bytes); + BigInt::encode_1363(output.data(), output.size(), n); + return output; + } + +//static +void BigInt::encode_1363(uint8_t output[], size_t bytes, const BigInt& n) + { + const size_t n_bytes = n.bytes(); + if(n_bytes > bytes) + throw Encoding_Error("encode_1363: n is too large to encode properly"); + + const size_t leading_0s = bytes - n_bytes; + encode(&output[leading_0s], n, Binary); + } + +/* +* Encode two BigInt, with leading 0s if needed, and concatenate +*/ +secure_vector BigInt::encode_fixed_length_int_pair(const BigInt& n1, const BigInt& n2, size_t bytes) + { + secure_vector output(2 * bytes); + BigInt::encode_1363(output.data(), bytes, n1); + BigInt::encode_1363(output.data() + bytes, bytes, n2); + return output; + } + +/* +* Decode a BigInt +*/ +BigInt BigInt::decode(const uint8_t buf[], size_t length, Base base) + { + BigInt r; + if(base == Binary) + r.binary_decode(buf, length); + else if(base == Hexadecimal) + { + secure_vector binary; + + if(length % 2) + { + // Handle lack of leading 0 + const char buf0_with_leading_0[2] = + { '0', static_cast(buf[0]) }; + + binary = hex_decode_locked(buf0_with_leading_0, 2); + + binary += hex_decode_locked(cast_uint8_ptr_to_char(&buf[1]), + length - 1, + false); + } + else + binary = hex_decode_locked(cast_uint8_ptr_to_char(buf), + length, false); + + r.binary_decode(binary.data(), binary.size()); + } + else if(base == Decimal) + { + for(size_t i = 0; i != length; ++i) + { + if(Charset::is_space(buf[i])) + continue; + + if(!Charset::is_digit(buf[i])) + throw Invalid_Argument("BigInt::decode: " + "Invalid character in decimal input"); + + const uint8_t x = Charset::char2digit(buf[i]); + + if(x >= 10) + throw Invalid_Argument("BigInt: Invalid decimal string"); + + r *= 10; + r += x; + } + } + else + throw Invalid_Argument("Unknown BigInt decoding method"); + return r; + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/math/bigint/big_io.cpp b/src/libs/3rdparty/botan/src/lib/math/bigint/big_io.cpp new file mode 100644 index 0000000000..803e1cc4ae --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/math/bigint/big_io.cpp @@ -0,0 +1,56 @@ +/* +* BigInt Input/Output +* (C) 1999-2007 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include + +namespace Botan { + +/* +* Write the BigInt into a stream +*/ +std::ostream& operator<<(std::ostream& stream, const BigInt& n) + { + BigInt::Base base = BigInt::Decimal; + if(stream.flags() & std::ios::hex) + base = BigInt::Hexadecimal; + else if(stream.flags() & std::ios::oct) + throw Exception("Octal output of BigInt not supported"); + + if(n == 0) + stream.write("0", 1); + else + { + if(n < 0) + stream.write("-", 1); + const std::vector buffer = BigInt::encode(n, base); + size_t skip = 0; + while(skip < buffer.size() && buffer[skip] == '0') + ++skip; + stream.write(cast_uint8_ptr_to_char(buffer.data()) + skip, + buffer.size() - skip); + } + if(!stream.good()) + throw Stream_IO_Error("BigInt output operator has failed"); + return stream; + } + +/* +* Read the BigInt from a stream +*/ +std::istream& operator>>(std::istream& stream, BigInt& n) + { + std::string str; + std::getline(stream, str); + if(stream.bad() || (stream.fail() && !stream.eof())) + throw Stream_IO_Error("BigInt input operator has failed"); + n = BigInt(str); + return stream; + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/math/bigint/big_ops2.cpp b/src/libs/3rdparty/botan/src/lib/math/bigint/big_ops2.cpp new file mode 100644 index 0000000000..bd107f33ad --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/math/bigint/big_ops2.cpp @@ -0,0 +1,382 @@ +/* +* (C) 1999-2007,2018 Jack Lloyd +* 2016 Matthias Gierlings +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include + +namespace Botan { + +BigInt& BigInt::add(const word y[], size_t y_sw, Sign y_sign) + { + const size_t x_sw = sig_words(); + + if(sign() == y_sign) + { + const size_t reg_size = std::max(x_sw, y_sw) + 1; + + if(m_reg.size() < reg_size) + grow_to(reg_size); + + bigint_add2(mutable_data(), reg_size - 1, y, y_sw); + } + else + { + const int32_t relative_size = bigint_cmp(data(), x_sw, y, y_sw); + + if(relative_size < 0) + { + const size_t reg_size = std::max(x_sw, y_sw); + grow_to(reg_size); + bigint_sub2_rev(mutable_data(), y, y_sw); + set_sign(y_sign); + } + else if(relative_size == 0) + { + zeroise(m_reg); + set_sign(Positive); + } + else if(relative_size > 0) + { + bigint_sub2(mutable_data(), x_sw, y, y_sw); + } + } + + return (*this); + } + +BigInt& BigInt::operator+=(const BigInt& y) + { + return add(y.data(), y.sig_words(), y.sign()); + } + +BigInt& BigInt::operator+=(word y) + { + return add(&y, 1, Positive); + } + +BigInt& BigInt::sub(const word y[], size_t y_sw, Sign y_sign) + { + const size_t x_sw = sig_words(); + + int32_t relative_size = bigint_cmp(data(), x_sw, y, y_sw); + + const size_t reg_size = std::max(x_sw, y_sw) + 1; + grow_to(reg_size); + + if(relative_size < 0) + { + if(sign() == y_sign) + bigint_sub2_rev(mutable_data(), y, y_sw); + else + bigint_add2(mutable_data(), reg_size - 1, y, y_sw); + + set_sign(y_sign == Positive ? Negative : Positive); + } + else if(relative_size == 0) + { + if(sign() == y_sign) + { + clear(); + set_sign(Positive); + } + else + bigint_shl1(mutable_data(), x_sw, 0, 1); + } + else if(relative_size > 0) + { + if(sign() == y_sign) + bigint_sub2(mutable_data(), x_sw, y, y_sw); + else + bigint_add2(mutable_data(), reg_size - 1, y, y_sw); + } + + return (*this); + } + +BigInt& BigInt::operator-=(const BigInt& y) + { + return sub(y.data(), y.sig_words(), y.sign()); + } + +BigInt& BigInt::operator-=(word y) + { + return sub(&y, 1, Positive); + } + +BigInt& BigInt::mod_add(const BigInt& s, const BigInt& mod, secure_vector& ws) + { + if(this->is_negative() || s.is_negative() || mod.is_negative()) + throw Invalid_Argument("BigInt::mod_add expects all arguments are positive"); + + // TODO add optimized version of this + *this += s; + this->reduce_below(mod, ws); + + return (*this); + } + +BigInt& BigInt::mod_sub(const BigInt& s, const BigInt& mod, secure_vector& ws) + { + if(this->is_negative() || s.is_negative() || mod.is_negative()) + throw Invalid_Argument("BigInt::mod_sub expects all arguments are positive"); + + const size_t t_sw = sig_words(); + const size_t s_sw = s.sig_words(); + const size_t mod_sw = mod.sig_words(); + + if(t_sw > mod_sw || s_sw > mod_sw) + throw Invalid_Argument("BigInt::mod_sub args larger than modulus"); + + BOTAN_DEBUG_ASSERT(*this < mod); + BOTAN_DEBUG_ASSERT(s < mod); + + int32_t relative_size = bigint_cmp(data(), t_sw, s.data(), s_sw); + + if(relative_size >= 0) + { + // this >= s in which case just subtract + bigint_sub2(mutable_data(), t_sw, s.data(), s_sw); + } + else + { + // Otherwise we must sub s and then add p (or add (p - s) as here) + + if(ws.size() < mod_sw) + ws.resize(mod_sw); + + word borrow = bigint_sub3(ws.data(), mod.data(), mod_sw, s.data(), s_sw); + BOTAN_ASSERT_NOMSG(borrow == 0); + + if(m_reg.size() < mod_sw) + grow_to(mod_sw); + + word carry = bigint_add2_nc(mutable_data(), m_reg.size(), ws.data(), mod_sw); + BOTAN_ASSERT_NOMSG(carry == 0); + } + + return (*this); + } + +BigInt& BigInt::rev_sub(const word y[], size_t y_sw, secure_vector& ws) + { + /* + *this = BigInt(y, y_sw) - *this; + return *this; + */ + if(this->sign() != BigInt::Positive) + throw Invalid_State("BigInt::sub_rev requires this is positive"); + + const size_t x_sw = this->sig_words(); + + const int32_t relative_size = bigint_cmp(y, y_sw, this->data(), x_sw); + + ws.resize(std::max(y_sw, x_sw) + 1); + clear_mem(ws.data(), ws.size()); + + if(relative_size < 0) + { + bigint_sub3(ws.data(), this->data(), x_sw, y, y_sw); + this->flip_sign(); + } + else if(relative_size == 0) + { + ws.clear(); + } + else if(relative_size > 0) + { + bigint_sub3(ws.data(), y, y_sw, this->data(), x_sw); + } + + m_reg.swap(ws); + + return (*this); + } + +/* +* Multiplication Operator +*/ +BigInt& BigInt::operator*=(const BigInt& y) + { + secure_vector ws; + return this->mul(y, ws); + } + +BigInt& BigInt::mul(const BigInt& y, secure_vector& ws) + { + const size_t x_sw = sig_words(); + const size_t y_sw = y.sig_words(); + set_sign((sign() == y.sign()) ? Positive : Negative); + + if(x_sw == 0 || y_sw == 0) + { + clear(); + set_sign(Positive); + } + else if(x_sw == 1 && y_sw) + { + grow_to(y_sw + 1); + bigint_linmul3(mutable_data(), y.data(), y_sw, word_at(0)); + } + else if(y_sw == 1 && x_sw) + { + grow_to(x_sw + 1); + bigint_linmul2(mutable_data(), x_sw, y.word_at(0)); + } + else + { + const size_t new_size = x_sw + y_sw + 1; + ws.resize(new_size); + secure_vector z_reg(new_size); + + bigint_mul(z_reg.data(), z_reg.size(), + data(), size(), x_sw, + y.data(), y.size(), y_sw, + ws.data(), ws.size()); + + z_reg.swap(m_reg); + } + + return (*this); + } + +BigInt& BigInt::square(secure_vector& ws) + { + const size_t sw = sig_words(); + + secure_vector z(2*sw); + ws.resize(z.size()); + + bigint_sqr(z.data(), z.size(), + data(), size(), sw, + ws.data(), ws.size()); + + swap_reg(z); + set_sign(BigInt::Positive); + + return (*this); + } + +BigInt& BigInt::operator*=(word y) + { + if(y == 0) + { + clear(); + set_sign(Positive); + } + + const size_t x_sw = sig_words(); + + if(size() < x_sw + 1) + grow_to(x_sw + 1); + bigint_linmul2(mutable_data(), x_sw, y); + + return (*this); + } + +/* +* Division Operator +*/ +BigInt& BigInt::operator/=(const BigInt& y) + { + if(y.sig_words() == 1 && is_power_of_2(y.word_at(0))) + (*this) >>= (y.bits() - 1); + else + (*this) = (*this) / y; + return (*this); + } + +/* +* Modulo Operator +*/ +BigInt& BigInt::operator%=(const BigInt& mod) + { + return (*this = (*this) % mod); + } + +/* +* Modulo Operator +*/ +word BigInt::operator%=(word mod) + { + if(mod == 0) + throw BigInt::DivideByZero(); + + if(is_power_of_2(mod)) + { + word result = (word_at(0) & (mod - 1)); + clear(); + grow_to(2); + m_reg[0] = result; + return result; + } + + word remainder = 0; + + for(size_t j = sig_words(); j > 0; --j) + remainder = bigint_modop(remainder, word_at(j-1), mod); + clear(); + grow_to(2); + + if(remainder && sign() == BigInt::Negative) + m_reg[0] = mod - remainder; + else + m_reg[0] = remainder; + + set_sign(BigInt::Positive); + + return word_at(0); + } + +/* +* Left Shift Operator +*/ +BigInt& BigInt::operator<<=(size_t shift) + { + if(shift) + { + const size_t shift_words = shift / BOTAN_MP_WORD_BITS, + shift_bits = shift % BOTAN_MP_WORD_BITS, + words = sig_words(); + + /* + * FIXME - if shift_words == 0 && the top shift_bits of the top word + * are zero then we know that no additional word is needed and can + * skip the allocation. + */ + const size_t needed_size = words + shift_words + (shift_bits ? 1 : 0); + + if(m_reg.size() < needed_size) + grow_to(needed_size); + + bigint_shl1(mutable_data(), words, shift_words, shift_bits); + } + + return (*this); + } + +/* +* Right Shift Operator +*/ +BigInt& BigInt::operator>>=(size_t shift) + { + if(shift) + { + const size_t shift_words = shift / BOTAN_MP_WORD_BITS, + shift_bits = shift % BOTAN_MP_WORD_BITS; + + bigint_shr1(mutable_data(), sig_words(), shift_words, shift_bits); + + if(is_zero()) + set_sign(Positive); + } + + return (*this); + } + +} 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 new file mode 100644 index 0000000000..492a69ad05 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/math/bigint/big_ops3.cpp @@ -0,0 +1,219 @@ +/* +* BigInt Binary Operators +* (C) 1999-2007 Jack Lloyd +* 2016 Matthias Gierlings +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include +#include + +namespace Botan { + +namespace { + +BigInt bigint_add(const BigInt& x, const word y[], size_t y_sw, BigInt::Sign y_sign) + { + const size_t x_sw = x.sig_words(); + + BigInt z(x.sign(), std::max(x_sw, y_sw) + 1); + + if(x.sign() == y_sign) + bigint_add3(z.mutable_data(), x.data(), x_sw, y, y_sw); + else + { + int32_t relative_size = bigint_cmp(x.data(), x_sw, y, y_sw); + + if(relative_size < 0) + { + bigint_sub3(z.mutable_data(), y, y_sw, x.data(), x_sw); + z.set_sign(y_sign); + } + else if(relative_size == 0) + z.set_sign(BigInt::Positive); + else if(relative_size > 0) + bigint_sub3(z.mutable_data(), x.data(), x_sw, y, y_sw); + } + + return z; + } + +BigInt bigint_sub(const BigInt& x, const word y[], size_t y_sw, BigInt::Sign y_sign) + { + const size_t x_sw = x.sig_words(); + + int32_t relative_size = bigint_cmp(x.data(), x_sw, y, y_sw); + + BigInt z(BigInt::Positive, std::max(x_sw, y_sw) + 1); + + if(relative_size < 0) + { + if(x.sign() == y_sign) + bigint_sub3(z.mutable_data(), y, y_sw, x.data(), x_sw); + else + bigint_add3(z.mutable_data(), x.data(), x_sw, y, y_sw); + z.set_sign(y_sign == BigInt::Positive ? BigInt::Negative : BigInt::Positive); + } + else if(relative_size == 0) + { + if(x.sign() != y_sign) + bigint_shl2(z.mutable_data(), x.data(), x_sw, 0, 1); + z.set_sign(y_sign == BigInt::Positive ? BigInt::Negative : BigInt::Positive); + } + else if(relative_size > 0) + { + if(x.sign() == y_sign) + bigint_sub3(z.mutable_data(), x.data(), x_sw, y, y_sw); + else + bigint_add3(z.mutable_data(), x.data(), x_sw, y, y_sw); + z.set_sign(x.sign()); + } + return z; + } + +} + +BigInt operator+(const BigInt& x, const BigInt& y) + { + return bigint_add(x, y.data(), y.sig_words(), y.sign()); + } + +BigInt operator+(const BigInt& x, word y) + { + return bigint_add(x, &y, 1, BigInt::Positive); + } + +BigInt operator-(const BigInt& x, const BigInt& y) + { + return bigint_sub(x, y.data(), y.sig_words(), y.sign()); + } + +BigInt operator-(const BigInt& x, word y) + { + return bigint_sub(x, &y, 1, BigInt::Positive); + } + +/* +* Multiplication Operator +*/ +BigInt operator*(const BigInt& x, const BigInt& y) + { + const size_t x_sw = x.sig_words(), y_sw = y.sig_words(); + + BigInt z(BigInt::Positive, x.size() + y.size()); + + if(x_sw == 1 && y_sw) + bigint_linmul3(z.mutable_data(), y.data(), y_sw, x.word_at(0)); + else if(y_sw == 1 && x_sw) + bigint_linmul3(z.mutable_data(), x.data(), x_sw, y.word_at(0)); + else if(x_sw && y_sw) + { + secure_vector workspace(z.size()); + + bigint_mul(z.mutable_data(), z.size(), + x.data(), x.size(), x_sw, + y.data(), y.size(), y_sw, + workspace.data(), workspace.size()); + } + + if(x_sw && y_sw && x.sign() != y.sign()) + z.flip_sign(); + return z; + } + +/* +* Division Operator +*/ +BigInt operator/(const BigInt& x, const BigInt& y) + { + if(y.sig_words() == 1 && is_power_of_2(y.word_at(0))) + return (x >> (y.bits() - 1)); + + BigInt q, r; + divide(x, y, q, r); + return q; + } + +/* +* Modulo Operator +*/ +BigInt operator%(const BigInt& n, const BigInt& mod) + { + if(mod.is_zero()) + throw BigInt::DivideByZero(); + if(mod.is_negative()) + throw Invalid_Argument("BigInt::operator%: modulus must be > 0"); + if(n.is_positive() && mod.is_positive() && n < mod) + return n; + + BigInt q, r; + divide(n, mod, q, r); + return r; + } + +/* +* Modulo Operator +*/ +word operator%(const BigInt& n, word mod) + { + if(mod == 0) + throw BigInt::DivideByZero(); + + if(mod == 1) + return 0; + + if(is_power_of_2(mod)) + return (n.word_at(0) & (mod - 1)); + + word remainder = 0; + + for(size_t j = n.sig_words(); j > 0; --j) + remainder = bigint_modop(remainder, n.word_at(j-1), mod); + + if(remainder && n.sign() == BigInt::Negative) + return mod - remainder; + return remainder; + } + +/* +* Left Shift Operator +*/ +BigInt operator<<(const BigInt& x, size_t shift) + { + if(shift == 0) + return x; + + const size_t shift_words = shift / BOTAN_MP_WORD_BITS, + shift_bits = shift % BOTAN_MP_WORD_BITS; + + const size_t x_sw = x.sig_words(); + + BigInt y(x.sign(), x_sw + shift_words + (shift_bits ? 1 : 0)); + bigint_shl2(y.mutable_data(), x.data(), x_sw, shift_words, shift_bits); + return y; + } + +/* +* Right Shift Operator +*/ +BigInt operator>>(const BigInt& x, size_t shift) + { + if(shift == 0) + return x; + if(x.bits() <= shift) + return 0; + + const size_t shift_words = shift / BOTAN_MP_WORD_BITS, + shift_bits = shift % BOTAN_MP_WORD_BITS, + x_sw = x.sig_words(); + + BigInt y(x.sign(), x_sw - shift_words); + bigint_shr2(y.mutable_data(), x.data(), x_sw, shift_words, shift_bits); + return y; + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/math/bigint/big_rand.cpp b/src/libs/3rdparty/botan/src/lib/math/bigint/big_rand.cpp new file mode 100644 index 0000000000..dd4cb5eaba --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/math/bigint/big_rand.cpp @@ -0,0 +1,64 @@ +/* +* BigInt Random Generation +* (C) 1999-2007 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include + +namespace Botan { + +/* +* Randomize this number +*/ +void BigInt::randomize(RandomNumberGenerator& rng, + size_t bitsize, bool set_high_bit) + { + set_sign(Positive); + + if(bitsize == 0) + { + clear(); + } + else + { + secure_vector array = rng.random_vec(round_up(bitsize, 8) / 8); + + // Always cut unwanted bits + if(bitsize % 8) + array[0] &= 0xFF >> (8 - (bitsize % 8)); + + // Set the highest bit if wanted + if (set_high_bit) + array[0] |= 0x80 >> ((bitsize % 8) ? (8 - bitsize % 8) : 0); + + binary_decode(array); + } + } + +/* +* Generate a random integer within given range +*/ +BigInt BigInt::random_integer(RandomNumberGenerator& rng, + const BigInt& min, const BigInt& max) + { + if(min.is_negative() || max.is_negative() || max <= min) + throw Invalid_Argument("BigInt::random_integer invalid range"); + + BigInt r; + + const size_t bits = max.bits(); + + do + { + r.randomize(rng, bits, false); + } + while(r < min || r >= max); + + return r; + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/math/bigint/bigint.cpp b/src/libs/3rdparty/botan/src/lib/math/bigint/bigint.cpp new file mode 100644 index 0000000000..495907d1ab --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/math/bigint/bigint.cpp @@ -0,0 +1,381 @@ +/* +* BigInt Base +* (C) 1999-2011,2012,2014 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include +#include + +namespace Botan { + +BigInt::BigInt(const word words[], size_t length) + { + m_reg.assign(words, words + length); + } + +/* +* Construct a BigInt from a regular number +*/ +BigInt::BigInt(uint64_t n) + { + if(n == 0) + return; + + const size_t limbs_needed = sizeof(uint64_t) / sizeof(word); + + m_reg.resize(limbs_needed); + for(size_t i = 0; i != limbs_needed; ++i) + m_reg[i] = ((n >> (i*BOTAN_MP_WORD_BITS)) & MP_WORD_MASK); + } + +/* +* Construct a BigInt of the specified size +*/ +BigInt::BigInt(Sign s, size_t size) + { + m_reg.resize(round_up(size, 8)); + m_signedness = s; + } + +/* +* Copy constructor +*/ +BigInt::BigInt(const BigInt& other) + { + m_reg = other.m_reg; + m_signedness = other.m_signedness; + } + +/* +* Construct a BigInt from a string +*/ +BigInt::BigInt(const std::string& str) + { + Base base = Decimal; + size_t markers = 0; + bool negative = false; + + if(str.length() > 0 && str[0] == '-') + { + markers += 1; + negative = true; + } + + if(str.length() > markers + 2 && str[markers ] == '0' && + str[markers + 1] == 'x') + { + markers += 2; + base = Hexadecimal; + } + + *this = decode(cast_char_ptr_to_uint8(str.data()) + markers, + str.length() - markers, base); + + if(negative) set_sign(Negative); + else set_sign(Positive); + } + +BigInt::BigInt(const uint8_t input[], size_t length) + { + binary_decode(input, length); + } + +/* +* Construct a BigInt from an encoded BigInt +*/ +BigInt::BigInt(const uint8_t input[], size_t length, Base base) + { + *this = decode(input, length, 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); + + const size_t b = this->bits(); + if(b > max_bits) + { + *this >>= (b - max_bits); + } + } + +/* +* Construct a BigInt from an encoded BigInt +*/ +BigInt::BigInt(RandomNumberGenerator& rng, size_t bits, bool set_high_bit) + { + randomize(rng, bits, set_high_bit); + } + +int32_t BigInt::cmp_word(word other) const + { + if(is_negative()) + return -1; // other is positive ... + + const size_t sw = this->sig_words(); + if(sw > 1) + return 1; // must be larger since other is just one word ... + + return bigint_cmp(this->data(), sw, &other, 1); + } + +/* +* Comparison Function +*/ +int32_t BigInt::cmp(const BigInt& other, bool check_signs) const + { + if(check_signs) + { + if(other.is_positive() && this->is_negative()) + return -1; + + if(other.is_negative() && this->is_positive()) + return 1; + + if(other.is_negative() && this->is_negative()) + return (-bigint_cmp(this->data(), this->sig_words(), + other.data(), other.sig_words())); + } + + return bigint_cmp(this->data(), this->sig_words(), + other.data(), other.sig_words()); + } + +void BigInt::encode_words(word out[], size_t size) const + { + const size_t words = sig_words(); + + if(words > size) + throw Encoding_Error("BigInt::encode_words value too large to encode"); + + clear_mem(out, size); + copy_mem(out, data(), words); + } + +/* +* Return bits {offset...offset+length} +*/ +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"); + + 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(1) << length) - 1; + const size_t shift = (offset % 8); + + return static_cast((piece >> shift) & mask); + } + +/* +* Convert this number to a uint32_t, if possible +*/ +uint32_t BigInt::to_u32bit() const + { + if(is_negative()) + throw Encoding_Error("BigInt::to_u32bit: Number is negative"); + if(bits() > 32) + throw Encoding_Error("BigInt::to_u32bit: Number is too big to convert"); + + uint32_t out = 0; + for(size_t i = 0; i != 4; ++i) + out = (out << 8) | byte_at(3-i); + return out; + } + +/* +* Set bit number n +*/ +void BigInt::set_bit(size_t n) + { + const size_t which = n / BOTAN_MP_WORD_BITS; + const word mask = static_cast(1) << (n % BOTAN_MP_WORD_BITS); + if(which >= size()) grow_to(which + 1); + m_reg[which] |= mask; + } + +/* +* Clear bit number n +*/ +void BigInt::clear_bit(size_t n) + { + const size_t which = n / BOTAN_MP_WORD_BITS; + const word mask = static_cast(1) << (n % BOTAN_MP_WORD_BITS); + if(which < size()) + m_reg[which] &= ~mask; + } + +size_t BigInt::bytes() const + { + return round_up(bits(), 8) / 8; + } + +/* +* Count how many bits are being used +*/ +size_t BigInt::bits() const + { + const size_t words = sig_words(); + + if(words == 0) + return 0; + + const size_t full_words = words - 1; + return (full_words * BOTAN_MP_WORD_BITS + high_bit(word_at(full_words))); + } + +/* +* Calcluate the size in a certain base +*/ +size_t BigInt::encoded_size(Base base) const + { + static const double LOG_2_BASE_10 = 0.30102999566; + + if(base == Binary) + return bytes(); + else if(base == Hexadecimal) + return 2*bytes(); + else if(base == Decimal) + return static_cast((bits() * LOG_2_BASE_10) + 1); + else + throw Invalid_Argument("Unknown base for BigInt encoding"); + } + +/* +* Return the negation of this number +*/ +BigInt BigInt::operator-() const + { + BigInt x = (*this); + x.flip_sign(); + return x; + } + +void BigInt::reduce_below(const BigInt& p, secure_vector& ws) + { + if(p.is_negative()) + throw Invalid_Argument("BigInt::reduce_below mod must be positive"); + + const size_t p_words = p.sig_words(); + + if(size() < p_words + 1) + grow_to(p_words + 1); + + if(ws.size() < p_words + 1) + ws.resize(p_words + 1); + + clear_mem(ws.data(), ws.size()); + + for(;;) + { + word borrow = bigint_sub3(ws.data(), data(), p_words + 1, p.data(), p_words); + + if(borrow) + break; + + m_reg.swap(ws); + } + } + +/* +* Return the absolute value of this number +*/ +BigInt BigInt::abs() const + { + BigInt x = (*this); + x.set_sign(Positive); + return x; + } + +void BigInt::grow_to(size_t n) + { + if(n > size()) + { + if(n <= m_reg.capacity()) + m_reg.resize(m_reg.capacity()); + else + m_reg.resize(round_up(n, 8)); + } + } + +/* +* Encode this number into bytes +*/ +void BigInt::binary_encode(uint8_t output[]) const + { + const size_t sig_bytes = bytes(); + for(size_t i = 0; i != sig_bytes; ++i) + output[sig_bytes-i-1] = byte_at(i); + } + +/* +* Set this number to the value in buf +*/ +void BigInt::binary_decode(const uint8_t buf[], size_t length) + { + const size_t WORD_BYTES = sizeof(word); + + clear(); + m_reg.resize(round_up((length / WORD_BYTES) + 1, 8)); + + for(size_t i = 0; i != length / WORD_BYTES; ++i) + { + const size_t top = length - WORD_BYTES*i; + for(size_t j = WORD_BYTES; j > 0; --j) + m_reg[i] = (m_reg[i] << 8) | buf[top - j]; + } + + for(size_t i = 0; i != length % WORD_BYTES; ++i) + m_reg[length / WORD_BYTES] = (m_reg[length / WORD_BYTES] << 8) | buf[i]; + } + +#if defined(BOTAN_HAS_VALGRIND) +void BigInt::const_time_poison() const + { + CT::poison(m_reg.data(), m_reg.size()); + } + +void BigInt::const_time_unpoison() const + { + CT::unpoison(m_reg.data(), m_reg.size()); + } +#endif + +void BigInt::const_time_lookup(secure_vector& output, + const std::vector& vec, + size_t idx) + { + const size_t words = output.size(); + + clear_mem(output.data(), output.size()); + + CT::poison(&idx, sizeof(idx)); + + for(size_t i = 0; i != vec.size(); ++i) + { + BOTAN_ASSERT(vec[i].size() >= words, + "Word size as expected in const_time_lookup"); + + const word mask = CT::is_equal(i, idx); + + for(size_t w = 0; w != words; ++w) + output[w] |= CT::select(mask, vec[i].word_at(w), 0); + } + + CT::unpoison(idx); + CT::unpoison(output.data(), output.size()); + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/math/bigint/bigint.h b/src/libs/3rdparty/botan/src/lib/math/bigint/bigint.h new file mode 100644 index 0000000000..4a07723b77 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/math/bigint/bigint.h @@ -0,0 +1,806 @@ +/* +* BigInt +* (C) 1999-2008,2012 Jack Lloyd +* 2007 FlexSecure +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_BIGINT_H_ +#define BOTAN_BIGINT_H_ + +#include +#include +#include +#include +#include + +namespace Botan { + +class RandomNumberGenerator; + +/** +* Arbitrary precision integer +*/ +class BOTAN_PUBLIC_API(2,0) BigInt final + { + public: + /** + * Base enumerator for encoding and decoding + */ + enum Base { Decimal = 10, Hexadecimal = 16, Binary = 256 }; + + /** + * Sign symbol definitions for positive and negative numbers + */ + enum Sign { Negative = 0, Positive = 1 }; + + /** + * DivideByZero Exception + */ + class BOTAN_PUBLIC_API(2,0) DivideByZero final : public Exception + { + public: + DivideByZero() : Exception("BigInt divide by zero") {} + }; + + /** + * Create empty BigInt + */ + BigInt() = default; + + /** + * Create BigInt from 64 bit integer + * @param n initial value of this BigInt + */ + BigInt(uint64_t n); + + /** + * Copy Constructor + * @param other the BigInt to copy + */ + BigInt(const BigInt& other); + + /** + * Create BigInt from a string. If the string starts with 0x the + * rest of the string will be interpreted as hexadecimal digits. + * Otherwise, it will be interpreted as a decimal number. + * + * @param str the string to parse for an integer value + */ + explicit BigInt(const std::string& str); + + /** + * Create a BigInt from an integer in a byte array + * @param buf the byte array holding the value + * @param length size of buf + */ + BigInt(const uint8_t buf[], size_t length); + + /** + * 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 + */ + BigInt(const uint8_t buf[], size_t length, Base base); + + /** + * Create a BigInt from an integer in a byte array + * @param buf the byte array holding the value + * @param length size of buf + * @param max_bits if the resulting integer is more than max_bits, + * it will be shifted so it is at most max_bits in length. + */ + BigInt(const uint8_t buf[], size_t length, size_t max_bits); + + /** + * Create a BigInt from an array of words + * @param words the words + * @param length number of words + */ + BigInt(const word words[], size_t length); + + /** + * \brief Create a random BigInt of the specified size + * + * @param rng random number generator + * @param bits size in bits + * @param set_high_bit if true, the highest bit is always set + * + * @see randomize + */ + BigInt(RandomNumberGenerator& rng, size_t bits, bool set_high_bit = true); + + /** + * Create BigInt of specified size, all zeros + * @param sign the sign + * @param n size of the internal register in words + */ + BigInt(Sign sign, size_t n); + + /** + * Move constructor + */ + BigInt(BigInt&& other) + { + this->swap(other); + } + + /** + * Move assignment + */ + BigInt& operator=(BigInt&& other) + { + if(this != &other) + this->swap(other); + + return (*this); + } + + /** + * Copy assignment + */ + BigInt& operator=(const BigInt&) = default; + + /** + * Swap this value with another + * @param other BigInt to swap values with + */ + void swap(BigInt& other) + { + m_reg.swap(other.m_reg); + std::swap(m_signedness, other.m_signedness); + } + + void swap_reg(secure_vector& reg) + { + m_reg.swap(reg); + } + + /** + * += operator + * @param y the BigInt to add to this + */ + BigInt& operator+=(const BigInt& y); + + /** + * += operator + * @param y the word to add to this + */ + BigInt& operator+=(word y); + + /** + * -= operator + * @param y the BigInt to subtract from this + */ + BigInt& operator-=(const BigInt& y); + + /** + * -= operator + * @param y the word to subtract from this + */ + BigInt& operator-=(word y); + + /** + * *= operator + * @param y the BigInt to multiply with this + */ + BigInt& operator*=(const BigInt& y); + + /** + * *= operator + * @param y the word to multiply with this + */ + BigInt& operator*=(word y); + + /** + * /= operator + * @param y the BigInt to divide this by + */ + BigInt& operator/=(const BigInt& y); + + /** + * Modulo operator + * @param y the modulus to reduce this by + */ + BigInt& operator%=(const BigInt& y); + + /** + * Modulo operator + * @param y the modulus (word) to reduce this by + */ + word operator%=(word y); + + /** + * Left shift operator + * @param shift the number of bits to shift this left by + */ + BigInt& operator<<=(size_t shift); + + /** + * Right shift operator + * @param shift the number of bits to shift this right by + */ + BigInt& operator>>=(size_t shift); + + /** + * Increment operator + */ + BigInt& operator++() { return (*this += 1); } + + /** + * Decrement operator + */ + BigInt& operator--() { return (*this -= 1); } + + /** + * Postfix increment operator + */ + BigInt operator++(int) { BigInt x = (*this); ++(*this); return x; } + + /** + * Postfix decrement operator + */ + BigInt operator--(int) { BigInt x = (*this); --(*this); return x; } + + /** + * Unary negation operator + * @return negative this + */ + BigInt operator-() const; + + /** + * ! operator + * @return true iff this is zero, otherwise false + */ + bool operator !() const { return (!is_nonzero()); } + + BigInt& add(const word y[], size_t y_words, Sign sign); + BigInt& sub(const word y[], size_t y_words, Sign sign); + + /** + * Multiply this with y + * @param y the BigInt to multiply with this + * @param ws a temp workspace + */ + BigInt& mul(const BigInt& y, secure_vector& ws); + + /** + * Square value of *this + * @param ws a temp workspace + */ + BigInt& square(secure_vector& ws); + + /** + * Set *this to y - *this + * @param y the BigInt to subtract from as a sequence of words + * @param y_size length of y in words + * @param ws a temp workspace + */ + BigInt& rev_sub(const word y[], size_t y_size, secure_vector& ws); + + /** + * Set *this to (*this + y) % mod + * This function assumes *this is >= 0 && < mod + * @param y the BigInt to add - assumed y >= 0 and y < mod + * @param mod the positive modulus + * @param ws a temp workspace + */ + BigInt& mod_add(const BigInt& y, const BigInt& mod, secure_vector& ws); + + /** + * Set *this to (*this - y) % mod + * This function assumes *this is >= 0 && < mod + * @param y the BigInt to subtract - assumed y >= 0 and y < mod + * @param mod the positive modulus + * @param ws a temp workspace + */ + BigInt& mod_sub(const BigInt& y, const BigInt& mod, secure_vector& ws); + + /** + * Return *this below mod + * + * Assumes that *this is (if anything) only slightly larger than + * mod and performs repeated subtractions. It should not be used if + * *this is much larger than mod, instead of modulo operator. + */ + void reduce_below(const BigInt& mod, secure_vector &ws); + + /** + * Zeroize the BigInt. The size of the underlying register is not + * modified. + */ + void clear() { zeroise(m_reg); } + + /** + * Compare this to another BigInt + * @param n the BigInt value to compare with + * @param check_signs include sign in comparison? + * @result if (thisn) return 1, if both + * values are identical return 0 [like Perl's <=> operator] + */ + int32_t cmp(const BigInt& n, bool check_signs = true) const; + + /** + * Compare this to an integer + * @param n the value to compare with + * @result if (thisn) return 1, if both + * values are identical return 0 [like Perl's <=> operator] + */ + int32_t cmp_word(word n) const; + + /** + * Test if the integer has an even value + * @result true if the integer is even, false otherwise + */ + bool is_even() const { return (get_bit(0) == 0); } + + /** + * Test if the integer has an odd value + * @result true if the integer is odd, false otherwise + */ + bool is_odd() const { return (get_bit(0) == 1); } + + /** + * Test if the integer is not zero + * @result true if the integer is non-zero, false otherwise + */ + bool is_nonzero() const { return (!is_zero()); } + + /** + * Test if the integer is zero + * @result true if the integer is zero, false otherwise + */ + bool is_zero() const + { + const size_t sw = sig_words(); + + for(size_t i = 0; i != sw; ++i) + if(m_reg[i]) + return false; + return true; + } + + /** + * Set bit at specified position + * @param n bit position to set + */ + void set_bit(size_t n); + + /** + * Clear bit at specified position + * @param n bit position to clear + */ + void clear_bit(size_t n); + + /** + * Clear all but the lowest n bits + * @param n amount of bits to keep + */ + void mask_bits(size_t n) + { + if(n == 0) { clear(); return; } + + const size_t top_word = n / BOTAN_MP_WORD_BITS; + const word mask = (static_cast(1) << (n % BOTAN_MP_WORD_BITS)) - 1; + + if(top_word < size()) + { + const size_t len = size() - (top_word + 1); + if (len > 0) + { + clear_mem(&m_reg[top_word+1], len); + } + m_reg[top_word] &= mask; + } + } + + /** + * Return bit value at specified position + * @param n the bit offset to test + * @result true, if the bit at position n is set, false otherwise + */ + bool get_bit(size_t n) const + { + return ((word_at(n / BOTAN_MP_WORD_BITS) >> (n % BOTAN_MP_WORD_BITS)) & 1); + } + + /** + * Return (a maximum of) 32 bits of the complete value + * @param offset the offset to start extracting + * @param length amount of bits to extract (starting at offset) + * @result the integer extracted from the register starting at + * offset with specified length + */ + uint32_t get_substring(size_t offset, size_t length) const; + + /** + * Convert this value into a uint32_t, if it is in the range + * [0 ... 2**32-1], or otherwise throw an exception. + * @result the value as a uint32_t if conversion is possible + */ + uint32_t to_u32bit() const; + + /** + * @param n the offset to get a byte from + * @result byte at offset n + */ + uint8_t byte_at(size_t n) const + { + return get_byte(sizeof(word) - (n % sizeof(word)) - 1, + word_at(n / sizeof(word))); + } + + /** + * Return the word at a specified position of the internal register + * @param n position in the register + * @return value at position n + */ + word word_at(size_t n) const + { return ((n < size()) ? m_reg[n] : 0); } + + void set_word_at(size_t i, word w) + { + if(i >= m_reg.size()) + grow_to(i + 1); + m_reg[i] = w; + } + + void set_words(const word w[], size_t len) + { + m_reg.resize(len); + copy_mem(mutable_data(), w, len); + } + + /** + * Tests if the sign of the integer is negative + * @result true, iff the integer has a negative sign + */ + bool is_negative() const { return (sign() == Negative); } + + /** + * Tests if the sign of the integer is positive + * @result true, iff the integer has a positive sign + */ + bool is_positive() const { return (sign() == Positive); } + + /** + * Return the sign of the integer + * @result the sign of the integer + */ + Sign sign() const { return (m_signedness); } + + /** + * @result the opposite sign of the represented integer value + */ + Sign reverse_sign() const + { + if(sign() == Positive) + return Negative; + return Positive; + } + + /** + * Flip the sign of this BigInt + */ + void flip_sign() + { + set_sign(reverse_sign()); + } + + /** + * Set sign of the integer + * @param sign new Sign to set + */ + void set_sign(Sign sign) + { + if(is_zero()) + m_signedness = Positive; + else + m_signedness = sign; + } + + /** + * @result absolute (positive) value of this + */ + BigInt abs() const; + + /** + * Give size of internal register + * @result size of internal register in words + */ + size_t size() const { return m_reg.size(); } + + /** + * Return how many words we need to hold this value + * @result significant words of the represented integer value + */ + size_t sig_words() const + { + const word* x = m_reg.data(); + size_t sig = m_reg.size(); + + while(sig && (x[sig-1] == 0)) + sig--; + return sig; + } + + /** + * Give byte length of the integer + * @result byte length of the represented integer value + */ + size_t bytes() const; + + /** + * Get the bit length of the integer + * @result bit length of the represented integer value + */ + size_t bits() const; + + /** + * Return a mutable pointer to the register + * @result a pointer to the start of the internal register + */ + word* mutable_data() { return m_reg.data(); } + + /** + * Return a const pointer to the register + * @result a pointer to the start of the internal register + */ + const word* data() const { return m_reg.data(); } + + secure_vector& get_word_vector() { return m_reg; } + const secure_vector& get_word_vector() const { return m_reg; } + + /** + * Increase internal register buffer to at least n words + * @param n new size of register + */ + void grow_to(size_t n); + + /** + * Resize the vector to the minimum word size to hold the integer, or + * min_size words, whichever is larger + */ + void shrink_to_fit(size_t min_size = 0) + { + const size_t words = std::max(min_size, sig_words()); + m_reg.resize(words); + } + + /** + * Fill BigInt with a random number with size of bitsize + * + * If \p set_high_bit is true, the highest bit will be set, which causes + * the entropy to be \a bits-1. Otherwise the highest bit is randomly chosen + * by the rng, causing the entropy to be \a bits. + * + * @param rng the random number generator to use + * @param bitsize number of bits the created random value should have + * @param set_high_bit if true, the highest bit is always set + */ + void randomize(RandomNumberGenerator& rng, size_t bitsize, bool set_high_bit = true); + + /** + * Store BigInt-value in a given byte array + * @param buf destination byte array for the integer value + */ + void binary_encode(uint8_t buf[]) const; + + /** + * Read integer value from a byte array with given size + * @param buf byte array buffer containing the integer + * @param length size of buf + */ + void binary_decode(const uint8_t buf[], size_t length); + + /** + * Read integer value from a byte array (secure_vector) + * @param buf the array to load from + */ + void binary_decode(const secure_vector& buf) + { + binary_decode(buf.data(), buf.size()); + } + + /** + * @param base the base to measure the size for + * @return size of this integer in base base + */ + size_t encoded_size(Base base = Binary) const; + + /** + * Place the value into out, zero-padding up to size words + * Throw if *this cannot be represented in size words + */ + void encode_words(word out[], size_t size) const; + +#if defined(BOTAN_HAS_VALGRIND) + void const_time_poison() const; + void const_time_unpoison() const; +#else + void const_time_poison() const {} + void const_time_unpoison() const {} +#endif + + /** + * @param rng a random number generator + * @param min the minimum value (must be non-negative) + * @param max the maximum value (must be non-negative and > min) + * @return random integer in [min,max) + */ + static BigInt random_integer(RandomNumberGenerator& rng, + const BigInt& min, + const BigInt& max); + + /** + * Create a power of two + * @param n the power of two to create + * @return bigint representing 2^n + */ + static BigInt power_of_2(size_t n) + { + BigInt b; + b.set_bit(n); + return b; + } + + /** + * 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 encode(const BigInt& n, Base base = Binary); + + /** + * Encode the integer value from a BigInt to a secure_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 secure_vector encode_locked(const BigInt& n, + Base base = Binary); + + /** + * Encode the integer value from a BigInt to a byte array + * @param buf destination byte array for the encoded integer + * value with given base + * @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); + + /** + * Create a BigInt from an integer in a byte array + * @param buf the binary value to load + * @param length size of buf + * @param base number-base of the integer in buf + * @result BigInt representing the integer in the byte array + */ + static BigInt decode(const uint8_t buf[], size_t length, + Base base = Binary); + + /** + * Create a BigInt from an integer in a byte array + * @param buf the binary value to load + * @param base number-base of the integer in buf + * @result BigInt representing the integer in the byte array + */ + static BigInt decode(const secure_vector& buf, + Base base = Binary) + { + return BigInt::decode(buf.data(), buf.size(), base); + } + + /** + * Create a BigInt from an integer in a byte array + * @param buf the binary value to load + * @param base number-base of the integer in buf + * @result BigInt representing the integer in the byte array + */ + static BigInt decode(const std::vector& buf, + Base base = Binary) + { + return BigInt::decode(buf.data(), buf.size(), base); + } + + /** + * Encode a BigInt to a byte array according to IEEE 1363 + * @param n the BigInt to encode + * @param bytes the length of the resulting secure_vector + * @result a secure_vector containing the encoded BigInt + */ + static secure_vector encode_1363(const BigInt& n, size_t bytes); + + static void encode_1363(uint8_t out[], size_t bytes, const BigInt& n); + + /** + * Encode two BigInt to a byte array according to IEEE 1363 + * @param n1 the first BigInt to encode + * @param n2 the second BigInt to encode + * @param bytes the length of the encoding of each single BigInt + * @result a secure_vector containing the concatenation of the two encoded BigInt + */ + static secure_vector encode_fixed_length_int_pair(const BigInt& n1, const BigInt& n2, size_t bytes); + + /** + * Set output = vec[idx].m_reg in constant time + * All words of vec must have the same size + */ + static void const_time_lookup( + secure_vector& output, + const std::vector& vec, + size_t idx); + + private: + secure_vector m_reg; + Sign m_signedness = Positive; + }; + +/* +* Arithmetic Operators +*/ +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); +inline BigInt operator+(word x, const BigInt& y) { return y + x; } + +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,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); +BigInt BOTAN_PUBLIC_API(2,0) operator<<(const BigInt& x, size_t n); +BigInt BOTAN_PUBLIC_API(2,0) operator>>(const BigInt& x, size_t n); + +/* +* Comparison Operators +*/ +inline bool operator==(const BigInt& a, const BigInt& b) + { return (a.cmp(b) == 0); } +inline bool operator!=(const BigInt& a, const BigInt& b) + { return (a.cmp(b) != 0); } +inline bool operator<=(const BigInt& a, const BigInt& b) + { return (a.cmp(b) <= 0); } +inline bool operator>=(const BigInt& a, const BigInt& b) + { return (a.cmp(b) >= 0); } +inline bool operator<(const BigInt& a, const BigInt& b) + { return (a.cmp(b) < 0); } +inline bool operator>(const BigInt& a, const BigInt& b) + { return (a.cmp(b) > 0); } + +inline bool operator==(const BigInt& a, word b) + { return (a.cmp_word(b) == 0); } +inline bool operator!=(const BigInt& a, word b) + { return (a.cmp_word(b) != 0); } +inline bool operator<=(const BigInt& a, word b) + { return (a.cmp_word(b) <= 0); } +inline bool operator>=(const BigInt& a, word b) + { return (a.cmp_word(b) >= 0); } +inline bool operator<(const BigInt& a, word b) + { return (a.cmp_word(b) < 0); } +inline bool operator>(const BigInt& a, word b) + { return (a.cmp_word(b) > 0); } + +/* +* I/O Operators +*/ +BOTAN_PUBLIC_API(2,0) std::ostream& operator<<(std::ostream&, const BigInt&); +BOTAN_PUBLIC_API(2,0) std::istream& operator>>(std::istream&, BigInt&); + +} + +namespace std { + +template<> +inline void swap(Botan::BigInt& x, Botan::BigInt& y) + { + x.swap(y); + } + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/math/bigint/divide.cpp b/src/libs/3rdparty/botan/src/lib/math/bigint/divide.cpp new file mode 100644 index 0000000000..63326d6552 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/math/bigint/divide.cpp @@ -0,0 +1,140 @@ +/* +* Division Algorithm +* (C) 1999-2007,2012 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include + +namespace Botan { + +namespace { + +/* +* Handle signed operands, if necessary +*/ +void sign_fixup(const BigInt& x, const BigInt& y, BigInt& q, BigInt& r) + { + if(x.sign() == BigInt::Negative) + { + q.flip_sign(); + if(r.is_nonzero()) { --q; r = y.abs() - r; } + } + if(y.sign() == BigInt::Negative) + q.flip_sign(); + } + +bool division_check(word q, word y2, word y1, + word x3, word x2, word x1) + { + // Compute (y3,y2,y1) = (y2,y1) * q + + word y3 = 0; + y1 = word_madd2(q, y1, &y3); + y2 = word_madd2(q, y2, &y3); + + // Return (y3,y2,y1) >? (x3,x2,x1) + + if(y3 > x3) return true; + if(y3 < x3) return false; + + if(y2 > x2) return true; + if(y2 < x2) return false; + + if(y1 > x1) return true; + if(y1 < x1) return false; + + return false; + } + +} + +/* +* Solve x = q * y + r +*/ +void divide(const BigInt& x, const BigInt& y_arg, BigInt& q, BigInt& r) + { + if(y_arg.is_zero()) + throw BigInt::DivideByZero(); + + BigInt y = y_arg; + const size_t y_words = y.sig_words(); + + r = x; + q = 0; + + r.set_sign(BigInt::Positive); + y.set_sign(BigInt::Positive); + + int32_t compare = r.cmp(y); + + if(compare == 0) + { + q = 1; + r = 0; + } + else if(compare > 0) + { + size_t shifts = 0; + word y_top = y.word_at(y.sig_words()-1); + while(y_top < MP_WORD_TOP_BIT) { y_top <<= 1; ++shifts; } + y <<= shifts; + r <<= shifts; + + const size_t n = r.sig_words() - 1, t = y_words - 1; + + if(n < t) + throw Internal_Error("BigInt division word sizes"); + + q.grow_to(n - t + 1); + + word* q_words = q.mutable_data(); + + if(n <= t) + { + while(r > y) { r -= y; ++q; } + r >>= shifts; + sign_fixup(x, y_arg, q, r); + return; + } + + BigInt temp = y << (BOTAN_MP_WORD_BITS * (n-t)); + + while(r >= temp) { r -= temp; q_words[n-t] += 1; } + + for(size_t j = n; j != t; --j) + { + const word x_j0 = r.word_at(j); + const word x_j1 = r.word_at(j-1); + const word y_t = y.word_at(t); + + if(x_j0 == y_t) + q_words[j-t-1] = MP_WORD_MAX; + else + q_words[j-t-1] = bigint_divop(x_j0, x_j1, y_t); + + while(division_check(q_words[j-t-1], + y_t, y.word_at(t-1), + x_j0, x_j1, r.word_at(j-2))) + { + q_words[j-t-1] -= 1; + } + + r -= (q_words[j-t-1] * y) << (BOTAN_MP_WORD_BITS * (j-t-1)); + + if(r.is_negative()) + { + r += y << (BOTAN_MP_WORD_BITS * (j-t-1)); + q_words[j-t-1] -= 1; + } + } + r >>= shifts; + } + + sign_fixup(x, y_arg, q, r); + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/math/bigint/divide.h b/src/libs/3rdparty/botan/src/lib/math/bigint/divide.h new file mode 100644 index 0000000000..03e5ff7c14 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/math/bigint/divide.h @@ -0,0 +1,29 @@ +/* +* Division +* (C) 1999-2007 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_DIVISON_ALGORITHM_H_ +#define BOTAN_DIVISON_ALGORITHM_H_ + +#include + +namespace Botan { + +/** +* BigInt Division +* @param x an integer +* @param y a non-zero integer +* @param q will be set to x / y +* @param r will be set to x % y +*/ +void BOTAN_PUBLIC_API(2,0) divide(const BigInt& x, + const BigInt& y, + BigInt& q, + BigInt& r); + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/math/bigint/info.txt b/src/libs/3rdparty/botan/src/lib/math/bigint/info.txt new file mode 100644 index 0000000000..e84061bb6d --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/math/bigint/info.txt @@ -0,0 +1,16 @@ + +BIGINT -> 20131128 + + +load_on auto + + +bigint.h +divide.h + + + +mp +hex +rng + diff --git a/src/libs/3rdparty/botan/src/lib/math/mp/info.txt b/src/libs/3rdparty/botan/src/lib/math/mp/info.txt new file mode 100644 index 0000000000..cee4325ed8 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/math/mp/info.txt @@ -0,0 +1,10 @@ + +BIGINT_MP -> 20151225 + + + +mp_core.h +mp_madd.h +mp_asmi.h +mp_monty.h + diff --git a/src/libs/3rdparty/botan/src/lib/math/mp/mp_asmi.h b/src/libs/3rdparty/botan/src/lib/math/mp/mp_asmi.h new file mode 100644 index 0000000000..1b332811f8 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/math/mp/mp_asmi.h @@ -0,0 +1,875 @@ +/* +* Lowest Level MPI Algorithms +* (C) 1999-2010 Jack Lloyd +* 2006 Luca Piccarreta +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_MP_ASM_INTERNAL_H_ +#define BOTAN_MP_ASM_INTERNAL_H_ + +#include + +namespace Botan { + +#if defined(BOTAN_MP_USE_X86_32_ASM) + +#define ADDSUB2_OP(OPERATION, INDEX) \ + ASM("movl 4*" #INDEX "(%[y]), %[carry]") \ + ASM(OPERATION " %[carry], 4*" #INDEX "(%[x])") \ + +#define ADDSUB3_OP(OPERATION, INDEX) \ + ASM("movl 4*" #INDEX "(%[x]), %[carry]") \ + ASM(OPERATION " 4*" #INDEX "(%[y]), %[carry]") \ + ASM("movl %[carry], 4*" #INDEX "(%[z])") \ + +#define LINMUL_OP(WRITE_TO, INDEX) \ + ASM("movl 4*" #INDEX "(%[x]),%%eax") \ + ASM("mull %[y]") \ + ASM("addl %[carry],%%eax") \ + ASM("adcl $0,%%edx") \ + ASM("movl %%edx,%[carry]") \ + ASM("movl %%eax, 4*" #INDEX "(%[" WRITE_TO "])") + +#define MULADD_OP(IGNORED, INDEX) \ + ASM("movl 4*" #INDEX "(%[x]),%%eax") \ + ASM("mull %[y]") \ + ASM("addl %[carry],%%eax") \ + ASM("adcl $0,%%edx") \ + ASM("addl 4*" #INDEX "(%[z]),%%eax") \ + ASM("adcl $0,%%edx") \ + ASM("movl %%edx,%[carry]") \ + ASM("movl %%eax, 4*" #INDEX " (%[z])") + +#define ADD_OR_SUBTRACT(CORE_CODE) \ + ASM("rorl %[carry]") \ + CORE_CODE \ + ASM("sbbl %[carry],%[carry]") \ + ASM("negl %[carry]") + +#elif defined(BOTAN_MP_USE_X86_64_ASM) + +#define ADDSUB2_OP(OPERATION, INDEX) \ + ASM("movq 8*" #INDEX "(%[y]), %[carry]") \ + ASM(OPERATION " %[carry], 8*" #INDEX "(%[x])") \ + +#define ADDSUB3_OP(OPERATION, INDEX) \ + ASM("movq 8*" #INDEX "(%[x]), %[carry]") \ + ASM(OPERATION " 8*" #INDEX "(%[y]), %[carry]") \ + ASM("movq %[carry], 8*" #INDEX "(%[z])") \ + +#define LINMUL_OP(WRITE_TO, INDEX) \ + ASM("movq 8*" #INDEX "(%[x]),%%rax") \ + ASM("mulq %[y]") \ + ASM("addq %[carry],%%rax") \ + ASM("adcq $0,%%rdx") \ + ASM("movq %%rdx,%[carry]") \ + ASM("movq %%rax, 8*" #INDEX "(%[" WRITE_TO "])") + +#define MULADD_OP(IGNORED, INDEX) \ + ASM("movq 8*" #INDEX "(%[x]),%%rax") \ + ASM("mulq %[y]") \ + ASM("addq %[carry],%%rax") \ + ASM("adcq $0,%%rdx") \ + ASM("addq 8*" #INDEX "(%[z]),%%rax") \ + ASM("adcq $0,%%rdx") \ + ASM("movq %%rdx,%[carry]") \ + ASM("movq %%rax, 8*" #INDEX " (%[z])") + +#define ADD_OR_SUBTRACT(CORE_CODE) \ + ASM("rorq %[carry]") \ + CORE_CODE \ + ASM("sbbq %[carry],%[carry]") \ + ASM("negq %[carry]") + +#endif + +#if defined(ADD_OR_SUBTRACT) + +#define ASM(x) x "\n\t" + +#define DO_8_TIMES(MACRO, ARG) \ + MACRO(ARG, 0) \ + MACRO(ARG, 1) \ + MACRO(ARG, 2) \ + MACRO(ARG, 3) \ + MACRO(ARG, 4) \ + MACRO(ARG, 5) \ + MACRO(ARG, 6) \ + MACRO(ARG, 7) + +#endif + +/* +* Word Addition +*/ +inline word word_add(word x, word y, word* carry) + { +#if defined(BOTAN_MP_USE_X86_32_ASM) + asm( + ADD_OR_SUBTRACT(ASM("adcl %[y],%[x]")) + : [x]"=r"(x), [carry]"=r"(*carry) + : "0"(x), [y]"rm"(y), "1"(*carry) + : "cc"); + return x; + +#elif defined(BOTAN_MP_USE_X86_64_ASM) + + asm( + ADD_OR_SUBTRACT(ASM("adcq %[y],%[x]")) + : [x]"=r"(x), [carry]"=r"(*carry) + : "0"(x), [y]"rm"(y), "1"(*carry) + : "cc"); + return x; + +#else + word z = x + y; + word c1 = (z < x); + z += *carry; + *carry = c1 | (z < *carry); + return z; +#endif + } + +/* +* Eight Word Block Addition, Two Argument +*/ +inline word word8_add2(word x[8], const word y[8], word carry) + { +#if defined(BOTAN_MP_USE_X86_32_ASM) + asm( + ADD_OR_SUBTRACT(DO_8_TIMES(ADDSUB2_OP, "adcl")) + : [carry]"=r"(carry) + : [x]"r"(x), [y]"r"(y), "0"(carry) + : "cc", "memory"); + return carry; + +#elif defined(BOTAN_MP_USE_X86_64_ASM) + + asm( + ADD_OR_SUBTRACT(DO_8_TIMES(ADDSUB2_OP, "adcq")) + : [carry]"=r"(carry) + : [x]"r"(x), [y]"r"(y), "0"(carry) + : "cc", "memory"); + return carry; + +#elif defined(BOTAN_MP_USE_X86_32_MSVC_ASM) + + __asm { + mov edx,[x] + mov esi,[y] + xor eax,eax + sub eax,[carry] //force CF=1 iff *carry==1 + mov eax,[esi] + adc [edx],eax + mov eax,[esi+4] + adc [edx+4],eax + mov eax,[esi+8] + adc [edx+8],eax + mov eax,[esi+12] + adc [edx+12],eax + mov eax,[esi+16] + adc [edx+16],eax + mov eax,[esi+20] + adc [edx+20],eax + mov eax,[esi+24] + adc [edx+24],eax + mov eax,[esi+28] + adc [edx+28],eax + sbb eax,eax + neg eax + } + +#else + x[0] = word_add(x[0], y[0], &carry); + x[1] = word_add(x[1], y[1], &carry); + x[2] = word_add(x[2], y[2], &carry); + x[3] = word_add(x[3], y[3], &carry); + x[4] = word_add(x[4], y[4], &carry); + x[5] = word_add(x[5], y[5], &carry); + x[6] = word_add(x[6], y[6], &carry); + x[7] = word_add(x[7], y[7], &carry); + return carry; +#endif + } + +/* +* Eight Word Block Addition, Three Argument +*/ +inline word word8_add3(word z[8], const word x[8], + const word y[8], word carry) + { +#if defined(BOTAN_MP_USE_X86_32_ASM) + asm( + ADD_OR_SUBTRACT(DO_8_TIMES(ADDSUB3_OP, "adcl")) + : [carry]"=r"(carry) + : [x]"r"(x), [y]"r"(y), [z]"r"(z), "0"(carry) + : "cc", "memory"); + return carry; + +#elif defined(BOTAN_MP_USE_X86_64_ASM) + + asm( + ADD_OR_SUBTRACT(DO_8_TIMES(ADDSUB3_OP, "adcq")) + : [carry]"=r"(carry) + : [x]"r"(x), [y]"r"(y), [z]"r"(z), "0"(carry) + : "cc", "memory"); + return carry; + +#elif defined(BOTAN_MP_USE_X86_32_MSVC_ASM) + + __asm { + mov edi,[x] + mov esi,[y] + mov ebx,[z] + xor eax,eax + sub eax,[carry] //force CF=1 iff *carry==1 + mov eax,[edi] + adc eax,[esi] + mov [ebx],eax + + mov eax,[edi+4] + adc eax,[esi+4] + mov [ebx+4],eax + + mov eax,[edi+8] + adc eax,[esi+8] + mov [ebx+8],eax + + mov eax,[edi+12] + adc eax,[esi+12] + mov [ebx+12],eax + + mov eax,[edi+16] + adc eax,[esi+16] + mov [ebx+16],eax + + mov eax,[edi+20] + adc eax,[esi+20] + mov [ebx+20],eax + + mov eax,[edi+24] + adc eax,[esi+24] + mov [ebx+24],eax + + mov eax,[edi+28] + adc eax,[esi+28] + mov [ebx+28],eax + + sbb eax,eax + neg eax + } + +#else + z[0] = word_add(x[0], y[0], &carry); + z[1] = word_add(x[1], y[1], &carry); + z[2] = word_add(x[2], y[2], &carry); + z[3] = word_add(x[3], y[3], &carry); + z[4] = word_add(x[4], y[4], &carry); + z[5] = word_add(x[5], y[5], &carry); + z[6] = word_add(x[6], y[6], &carry); + z[7] = word_add(x[7], y[7], &carry); + return carry; +#endif + } + +/* +* Word Subtraction +*/ +inline word word_sub(word x, word y, word* carry) + { +#if defined(BOTAN_MP_USE_X86_32_ASM) + asm( + ADD_OR_SUBTRACT(ASM("sbbl %[y],%[x]")) + : [x]"=r"(x), [carry]"=r"(*carry) + : "0"(x), [y]"rm"(y), "1"(*carry) + : "cc"); + return x; + +#elif defined(BOTAN_MP_USE_X86_64_ASM) + + asm( + ADD_OR_SUBTRACT(ASM("sbbq %[y],%[x]")) + : [x]"=r"(x), [carry]"=r"(*carry) + : "0"(x), [y]"rm"(y), "1"(*carry) + : "cc"); + return x; + +#else + word t0 = x - y; + word c1 = (t0 > x); + word z = t0 - *carry; + *carry = c1 | (z > t0); + return z; +#endif + } + +/* +* Eight Word Block Subtraction, Two Argument +*/ +inline word word8_sub2(word x[8], const word y[8], word carry) + { +#if defined(BOTAN_MP_USE_X86_32_ASM) + asm( + ADD_OR_SUBTRACT(DO_8_TIMES(ADDSUB2_OP, "sbbl")) + : [carry]"=r"(carry) + : [x]"r"(x), [y]"r"(y), "0"(carry) + : "cc", "memory"); + return carry; + +#elif defined(BOTAN_MP_USE_X86_64_ASM) + + asm( + ADD_OR_SUBTRACT(DO_8_TIMES(ADDSUB2_OP, "sbbq")) + : [carry]"=r"(carry) + : [x]"r"(x), [y]"r"(y), "0"(carry) + : "cc", "memory"); + return carry; + +#elif defined(BOTAN_MP_USE_X86_32_MSVC_ASM) + + __asm { + mov edi,[x] + mov esi,[y] + xor eax,eax + sub eax,[carry] //force CF=1 iff *carry==1 + mov eax,[edi] + sbb eax,[esi] + mov [edi],eax + mov eax,[edi+4] + sbb eax,[esi+4] + mov [edi+4],eax + mov eax,[edi+8] + sbb eax,[esi+8] + mov [edi+8],eax + mov eax,[edi+12] + sbb eax,[esi+12] + mov [edi+12],eax + mov eax,[edi+16] + sbb eax,[esi+16] + mov [edi+16],eax + mov eax,[edi+20] + sbb eax,[esi+20] + mov [edi+20],eax + mov eax,[edi+24] + sbb eax,[esi+24] + mov [edi+24],eax + mov eax,[edi+28] + sbb eax,[esi+28] + mov [edi+28],eax + sbb eax,eax + neg eax + } + +#else + x[0] = word_sub(x[0], y[0], &carry); + x[1] = word_sub(x[1], y[1], &carry); + x[2] = word_sub(x[2], y[2], &carry); + x[3] = word_sub(x[3], y[3], &carry); + x[4] = word_sub(x[4], y[4], &carry); + x[5] = word_sub(x[5], y[5], &carry); + x[6] = word_sub(x[6], y[6], &carry); + x[7] = word_sub(x[7], y[7], &carry); + return carry; +#endif + } + +/* +* Eight Word Block Subtraction, Two Argument +*/ +inline word word8_sub2_rev(word x[8], const word y[8], word carry) + { +#if defined(BOTAN_MP_USE_X86_32_ASM) + asm( + ADD_OR_SUBTRACT(DO_8_TIMES(ADDSUB3_OP, "sbbl")) + : [carry]"=r"(carry) + : [x]"r"(y), [y]"r"(x), [z]"r"(x), "0"(carry) + : "cc", "memory"); + return carry; + +#elif defined(BOTAN_MP_USE_X86_64_ASM) + + asm( + ADD_OR_SUBTRACT(DO_8_TIMES(ADDSUB3_OP, "sbbq")) + : [carry]"=r"(carry) + : [x]"r"(y), [y]"r"(x), [z]"r"(x), "0"(carry) + : "cc", "memory"); + return carry; + +#else + x[0] = word_sub(y[0], x[0], &carry); + x[1] = word_sub(y[1], x[1], &carry); + x[2] = word_sub(y[2], x[2], &carry); + x[3] = word_sub(y[3], x[3], &carry); + x[4] = word_sub(y[4], x[4], &carry); + x[5] = word_sub(y[5], x[5], &carry); + x[6] = word_sub(y[6], x[6], &carry); + x[7] = word_sub(y[7], x[7], &carry); + return carry; +#endif + } + +/* +* Eight Word Block Subtraction, Three Argument +*/ +inline word word8_sub3(word z[8], const word x[8], + const word y[8], word carry) + { +#if defined(BOTAN_MP_USE_X86_32_ASM) + asm( + ADD_OR_SUBTRACT(DO_8_TIMES(ADDSUB3_OP, "sbbl")) + : [carry]"=r"(carry) + : [x]"r"(x), [y]"r"(y), [z]"r"(z), "0"(carry) + : "cc", "memory"); + return carry; + +#elif defined(BOTAN_MP_USE_X86_64_ASM) + + asm( + ADD_OR_SUBTRACT(DO_8_TIMES(ADDSUB3_OP, "sbbq")) + : [carry]"=r"(carry) + : [x]"r"(x), [y]"r"(y), [z]"r"(z), "0"(carry) + : "cc", "memory"); + return carry; + +#elif defined(BOTAN_MP_USE_X86_32_MSVC_ASM) + + __asm { + mov edi,[x] + mov esi,[y] + xor eax,eax + sub eax,[carry] //force CF=1 iff *carry==1 + mov ebx,[z] + mov eax,[edi] + sbb eax,[esi] + mov [ebx],eax + mov eax,[edi+4] + sbb eax,[esi+4] + mov [ebx+4],eax + mov eax,[edi+8] + sbb eax,[esi+8] + mov [ebx+8],eax + mov eax,[edi+12] + sbb eax,[esi+12] + mov [ebx+12],eax + mov eax,[edi+16] + sbb eax,[esi+16] + mov [ebx+16],eax + mov eax,[edi+20] + sbb eax,[esi+20] + mov [ebx+20],eax + mov eax,[edi+24] + sbb eax,[esi+24] + mov [ebx+24],eax + mov eax,[edi+28] + sbb eax,[esi+28] + mov [ebx+28],eax + sbb eax,eax + neg eax + } + +#else + z[0] = word_sub(x[0], y[0], &carry); + z[1] = word_sub(x[1], y[1], &carry); + z[2] = word_sub(x[2], y[2], &carry); + z[3] = word_sub(x[3], y[3], &carry); + z[4] = word_sub(x[4], y[4], &carry); + z[5] = word_sub(x[5], y[5], &carry); + z[6] = word_sub(x[6], y[6], &carry); + z[7] = word_sub(x[7], y[7], &carry); + return carry; +#endif + } + +/* +* Eight Word Block Linear Multiplication +*/ +inline word word8_linmul2(word x[8], word y, word carry) + { +#if defined(BOTAN_MP_USE_X86_32_ASM) + asm( + DO_8_TIMES(LINMUL_OP, "x") + : [carry]"=r"(carry) + : [x]"r"(x), [y]"rm"(y), "0"(carry) + : "cc", "%eax", "%edx"); + return carry; + +#elif defined(BOTAN_MP_USE_X86_64_ASM) + + asm( + DO_8_TIMES(LINMUL_OP, "x") + : [carry]"=r"(carry) + : [x]"r"(x), [y]"rm"(y), "0"(carry) + : "cc", "%rax", "%rdx"); + return carry; + +#elif defined(BOTAN_MP_USE_X86_32_MSVC_ASM) + + __asm { + mov esi,[x] + mov eax,[esi] //load a + mul [y] //edx(hi):eax(lo)=a*b + add eax,[carry] //sum lo carry + adc edx,0 //sum hi carry + mov ecx,edx //store carry + mov [esi],eax //load a + + mov eax,[esi+4] //load a + mul [y] //edx(hi):eax(lo)=a*b + add eax,ecx //sum lo carry + adc edx,0 //sum hi carry + mov ecx,edx //store carry + mov [esi+4],eax //load a + + mov eax,[esi+8] //load a + mul [y] //edx(hi):eax(lo)=a*b + add eax,ecx //sum lo carry + adc edx,0 //sum hi carry + mov ecx,edx //store carry + mov [esi+8],eax //load a + + mov eax,[esi+12] //load a + mul [y] //edx(hi):eax(lo)=a*b + add eax,ecx //sum lo carry + adc edx,0 //sum hi carry + mov ecx,edx //store carry + mov [esi+12],eax //load a + + mov eax,[esi+16] //load a + mul [y] //edx(hi):eax(lo)=a*b + add eax,ecx //sum lo carry + adc edx,0 //sum hi carry + mov ecx,edx //store carry + mov [esi+16],eax //load a + + mov eax,[esi+20] //load a + mul [y] //edx(hi):eax(lo)=a*b + add eax,ecx //sum lo carry + adc edx,0 //sum hi carry + mov ecx,edx //store carry + mov [esi+20],eax //load a + + mov eax,[esi+24] //load a + mul [y] //edx(hi):eax(lo)=a*b + add eax,ecx //sum lo carry + adc edx,0 //sum hi carry + mov ecx,edx //store carry + mov [esi+24],eax //load a + + mov eax,[esi+28] //load a + mul [y] //edx(hi):eax(lo)=a*b + add eax,ecx //sum lo carry + adc edx,0 //sum hi carry + mov [esi+28],eax //load a + + mov eax,edx //store carry + } + +#else + x[0] = word_madd2(x[0], y, &carry); + x[1] = word_madd2(x[1], y, &carry); + x[2] = word_madd2(x[2], y, &carry); + x[3] = word_madd2(x[3], y, &carry); + x[4] = word_madd2(x[4], y, &carry); + x[5] = word_madd2(x[5], y, &carry); + x[6] = word_madd2(x[6], y, &carry); + x[7] = word_madd2(x[7], y, &carry); + return carry; +#endif + } + +/* +* Eight Word Block Linear Multiplication +*/ +inline word word8_linmul3(word z[8], const word x[8], word y, word carry) + { +#if defined(BOTAN_MP_USE_X86_32_ASM) + asm( + DO_8_TIMES(LINMUL_OP, "z") + : [carry]"=r"(carry) + : [z]"r"(z), [x]"r"(x), [y]"rm"(y), "0"(carry) + : "cc", "%eax", "%edx"); + return carry; + +#elif defined(BOTAN_MP_USE_X86_64_ASM) + asm( + DO_8_TIMES(LINMUL_OP, "z") + : [carry]"=r"(carry) + : [z]"r"(z), [x]"r"(x), [y]"rm"(y), "0"(carry) + : "cc", "%rax", "%rdx"); + return carry; + +#elif defined(BOTAN_MP_USE_X86_32_MSVC_ASM) + + __asm { + mov edi,[z] + mov esi,[x] + mov eax,[esi] //load a + mul [y] //edx(hi):eax(lo)=a*b + add eax,[carry] //sum lo carry + adc edx,0 //sum hi carry + mov ecx,edx //store carry + mov [edi],eax //load a + + mov eax,[esi+4] //load a + mul [y] //edx(hi):eax(lo)=a*b + add eax,ecx //sum lo carry + adc edx,0 //sum hi carry + mov ecx,edx //store carry + mov [edi+4],eax //load a + + mov eax,[esi+8] //load a + mul [y] //edx(hi):eax(lo)=a*b + add eax,ecx //sum lo carry + adc edx,0 //sum hi carry + mov ecx,edx //store carry + mov [edi+8],eax //load a + + mov eax,[esi+12] //load a + mul [y] //edx(hi):eax(lo)=a*b + add eax,ecx //sum lo carry + adc edx,0 //sum hi carry + mov ecx,edx //store carry + mov [edi+12],eax //load a + + mov eax,[esi+16] //load a + mul [y] //edx(hi):eax(lo)=a*b + add eax,ecx //sum lo carry + adc edx,0 //sum hi carry + mov ecx,edx //store carry + mov [edi+16],eax //load a + + mov eax,[esi+20] //load a + mul [y] //edx(hi):eax(lo)=a*b + add eax,ecx //sum lo carry + adc edx,0 //sum hi carry + mov ecx,edx //store carry + mov [edi+20],eax //load a + + mov eax,[esi+24] //load a + mul [y] //edx(hi):eax(lo)=a*b + add eax,ecx //sum lo carry + adc edx,0 //sum hi carry + mov ecx,edx //store carry + mov [edi+24],eax //load a + + mov eax,[esi+28] //load a + mul [y] //edx(hi):eax(lo)=a*b + add eax,ecx //sum lo carry + adc edx,0 //sum hi carry + mov [edi+28],eax //load a + mov eax,edx //store carry + } + +#else + z[0] = word_madd2(x[0], y, &carry); + z[1] = word_madd2(x[1], y, &carry); + z[2] = word_madd2(x[2], y, &carry); + z[3] = word_madd2(x[3], y, &carry); + z[4] = word_madd2(x[4], y, &carry); + z[5] = word_madd2(x[5], y, &carry); + z[6] = word_madd2(x[6], y, &carry); + z[7] = word_madd2(x[7], y, &carry); + return carry; +#endif + } + +/* +* Eight Word Block Multiply/Add +*/ +inline word word8_madd3(word z[8], const word x[8], word y, word carry) + { +#if defined(BOTAN_MP_USE_X86_32_ASM) + asm( + DO_8_TIMES(MULADD_OP, "") + : [carry]"=r"(carry) + : [z]"r"(z), [x]"r"(x), [y]"rm"(y), "0"(carry) + : "cc", "%eax", "%edx"); + return carry; + +#elif defined(BOTAN_MP_USE_X86_64_ASM) + + asm( + DO_8_TIMES(MULADD_OP, "") + : [carry]"=r"(carry) + : [z]"r"(z), [x]"r"(x), [y]"rm"(y), "0"(carry) + : "cc", "%rax", "%rdx"); + return carry; + +#else + z[0] = word_madd3(x[0], y, z[0], &carry); + z[1] = word_madd3(x[1], y, z[1], &carry); + z[2] = word_madd3(x[2], y, z[2], &carry); + z[3] = word_madd3(x[3], y, z[3], &carry); + z[4] = word_madd3(x[4], y, z[4], &carry); + z[5] = word_madd3(x[5], y, z[5], &carry); + z[6] = word_madd3(x[6], y, z[6], &carry); + z[7] = word_madd3(x[7], y, z[7], &carry); + return carry; +#endif + } + +/* +* Multiply-Add Accumulator +* (w2,w1,w0) += x * y +*/ +inline void word3_muladd(word* w2, word* w1, word* w0, word x, word y) + { +#if defined(BOTAN_MP_USE_X86_32_ASM) + word z0 = 0, z1 = 0; + + asm ("mull %[y]" + : "=a"(z0),"=d"(z1) + : "a"(x), [y]"rm"(y) + : "cc"); + + asm(ASM("addl %[z0],%[w0]") + ASM("adcl %[z1],%[w1]") + ASM("adcl $0,%[w2]") + + : [w0]"=r"(*w0), [w1]"=r"(*w1), [w2]"=r"(*w2) + : [z0]"r"(z0), [z1]"r"(z1), "0"(*w0), "1"(*w1), "2"(*w2) + : "cc"); + +#elif defined(BOTAN_MP_USE_X86_64_ASM) + + word z0 = 0, z1 = 0; + + asm ("mulq %[y]" + : "=a"(z0),"=d"(z1) + : "a"(x), [y]"rm"(y) + : "cc"); + + asm(ASM("addq %[z0],%[w0]") + ASM("adcq %[z1],%[w1]") + ASM("adcq $0,%[w2]") + + : [w0]"=r"(*w0), [w1]"=r"(*w1), [w2]"=r"(*w2) + : [z0]"r"(z0), [z1]"r"(z1), "0"(*w0), "1"(*w1), "2"(*w2) + : "cc"); + +#else + word carry = *w0; + *w0 = word_madd2(x, y, &carry); + *w1 += carry; + *w2 += (*w1 < carry); +#endif + } + +/* +* 3-word addition +* (w2,w1,w0) += x +*/ +inline void word3_add(word* w2, word* w1, word* w0, word x) + { +#if defined(BOTAN_MP_USE_X86_32_ASM) + asm( + ASM("addl %[x],%[w0]") + ASM("adcl $0,%[w1]") + ASM("adcl $0,%[w2]") + + : [w0]"=r"(*w0), [w1]"=r"(*w1), [w2]"=r"(*w2) + : [x]"r"(x), "0"(*w0), "1"(*w1), "2"(*w2) + : "cc"); + +#elif defined(BOTAN_MP_USE_X86_64_ASM) + + asm( + ASM("addq %[x],%[w0]") + ASM("adcq $0,%[w1]") + ASM("adcq $0,%[w2]") + + : [w0]"=r"(*w0), [w1]"=r"(*w1), [w2]"=r"(*w2) + : [x]"r"(x), "0"(*w0), "1"(*w1), "2"(*w2) + : "cc"); + +#else + *w0 += x; + word c1 = (*w0 < x); + *w1 += c1; + word c2 = (*w1 < c1); + *w2 += c2; +#endif + } + +/* +* Multiply-Add Accumulator +* (w2,w1,w0) += 2 * x * y +*/ +inline void word3_muladd_2(word* w2, word* w1, word* w0, word x, word y) + { +#if defined(BOTAN_MP_USE_X86_32_ASM) + + word z0 = 0, z1 = 0; + + asm ("mull %[y]" + : "=a"(z0),"=d"(z1) + : "a"(x), [y]"rm"(y) + : "cc"); + + asm( + ASM("addl %[z0],%[w0]") + ASM("adcl %[z1],%[w1]") + ASM("adcl $0,%[w2]") + + ASM("addl %[z0],%[w0]") + ASM("adcl %[z1],%[w1]") + ASM("adcl $0,%[w2]") + + : [w0]"=r"(*w0), [w1]"=r"(*w1), [w2]"=r"(*w2) + : [z0]"r"(z0), [z1]"r"(z1), "0"(*w0), "1"(*w1), "2"(*w2) + : "cc"); + +#elif defined(BOTAN_MP_USE_X86_64_ASM) + + word z0 = 0, z1 = 0; + + asm ("mulq %[y]" + : "=a"(z0),"=d"(z1) + : "a"(x), [y]"rm"(y) + : "cc"); + + asm( + ASM("addq %[z0],%[w0]") + ASM("adcq %[z1],%[w1]") + ASM("adcq $0,%[w2]") + + ASM("addq %[z0],%[w0]") + ASM("adcq %[z1],%[w1]") + ASM("adcq $0,%[w2]") + + : [w0]"=r"(*w0), [w1]"=r"(*w1), [w2]"=r"(*w2) + : [z0]"r"(z0), [z1]"r"(z1), "0"(*w0), "1"(*w1), "2"(*w2) + : "cc"); + +#else + word carry = 0; + x = word_madd2(x, y, &carry); + y = carry; + + word top = (y >> (BOTAN_MP_WORD_BITS-1)); + y <<= 1; + y |= (x >> (BOTAN_MP_WORD_BITS-1)); + x <<= 1; + + carry = 0; + *w0 = word_add(*w0, x, &carry); + *w1 = word_add(*w1, y, &carry); + *w2 = word_add(*w2, top, &carry); +#endif + } + +#if defined(ASM) + #undef ASM + #undef DO_8_TIMES + #undef ADD_OR_SUBTRACT + #undef ADDSUB2_OP + #undef ADDSUB3_OP + #undef LINMUL_OP + #undef MULADD_OP +#endif + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/math/mp/mp_comba.cpp b/src/libs/3rdparty/botan/src/lib/math/mp/mp_comba.cpp new file mode 100644 index 0000000000..ec527224c8 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/math/mp/mp_comba.cpp @@ -0,0 +1,2211 @@ +/* +* Comba Multiplication and Squaring +* +* This file was automatically generated by ./src/scripts/comba.py on 2018-05-08 +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include + +namespace Botan { + +/* +* Comba 4x4 Squaring +*/ +void bigint_comba_sqr4(word z[8], const word x[4]) + { + word w2 = 0, w1 = 0, w0 = 0; + + word3_muladd (&w2, &w1, &w0, x[ 0], x[ 0]); + z[ 0] = w0; w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[ 0], x[ 1]); + z[ 1] = w1; w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[ 0], x[ 2]); + word3_muladd (&w1, &w0, &w2, x[ 1], x[ 1]); + z[ 2] = w2; w2 = 0; + + word3_muladd_2(&w2, &w1, &w0, x[ 0], x[ 3]); + word3_muladd_2(&w2, &w1, &w0, x[ 1], x[ 2]); + z[ 3] = w0; w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[ 1], x[ 3]); + word3_muladd (&w0, &w2, &w1, x[ 2], x[ 2]); + z[ 4] = w1; w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[ 2], x[ 3]); + z[ 5] = w2; w2 = 0; + + word3_muladd (&w2, &w1, &w0, x[ 3], x[ 3]); + z[ 6] = w0; + z[ 7] = w1; + } + +/* +* Comba 4x4 Multiplication +*/ +void bigint_comba_mul4(word z[8], const word x[4], const word y[4]) + { + word w2 = 0, w1 = 0, w0 = 0; + + word3_muladd(&w2, &w1, &w0, x[ 0], y[ 0]); + z[ 0] = w0; w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[ 0], y[ 1]); + word3_muladd(&w0, &w2, &w1, x[ 1], y[ 0]); + z[ 1] = w1; w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[ 0], y[ 2]); + word3_muladd(&w1, &w0, &w2, x[ 1], y[ 1]); + word3_muladd(&w1, &w0, &w2, x[ 2], y[ 0]); + z[ 2] = w2; w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[ 0], y[ 3]); + word3_muladd(&w2, &w1, &w0, x[ 1], y[ 2]); + word3_muladd(&w2, &w1, &w0, x[ 2], y[ 1]); + word3_muladd(&w2, &w1, &w0, x[ 3], y[ 0]); + z[ 3] = w0; w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[ 1], y[ 3]); + word3_muladd(&w0, &w2, &w1, x[ 2], y[ 2]); + word3_muladd(&w0, &w2, &w1, x[ 3], y[ 1]); + z[ 4] = w1; w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[ 2], y[ 3]); + word3_muladd(&w1, &w0, &w2, x[ 3], y[ 2]); + z[ 5] = w2; w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[ 3], y[ 3]); + z[ 6] = w0; + z[ 7] = w1; + } + +/* +* Comba 6x6 Squaring +*/ +void bigint_comba_sqr6(word z[12], const word x[6]) + { + word w2 = 0, w1 = 0, w0 = 0; + + word3_muladd (&w2, &w1, &w0, x[ 0], x[ 0]); + z[ 0] = w0; w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[ 0], x[ 1]); + z[ 1] = w1; w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[ 0], x[ 2]); + word3_muladd (&w1, &w0, &w2, x[ 1], x[ 1]); + z[ 2] = w2; w2 = 0; + + word3_muladd_2(&w2, &w1, &w0, x[ 0], x[ 3]); + word3_muladd_2(&w2, &w1, &w0, x[ 1], x[ 2]); + z[ 3] = w0; w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[ 0], x[ 4]); + word3_muladd_2(&w0, &w2, &w1, x[ 1], x[ 3]); + word3_muladd (&w0, &w2, &w1, x[ 2], x[ 2]); + z[ 4] = w1; w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[ 0], x[ 5]); + word3_muladd_2(&w1, &w0, &w2, x[ 1], x[ 4]); + word3_muladd_2(&w1, &w0, &w2, x[ 2], x[ 3]); + z[ 5] = w2; w2 = 0; + + word3_muladd_2(&w2, &w1, &w0, x[ 1], x[ 5]); + word3_muladd_2(&w2, &w1, &w0, x[ 2], x[ 4]); + word3_muladd (&w2, &w1, &w0, x[ 3], x[ 3]); + z[ 6] = w0; w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[ 2], x[ 5]); + word3_muladd_2(&w0, &w2, &w1, x[ 3], x[ 4]); + z[ 7] = w1; w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[ 3], x[ 5]); + word3_muladd (&w1, &w0, &w2, x[ 4], x[ 4]); + z[ 8] = w2; w2 = 0; + + word3_muladd_2(&w2, &w1, &w0, x[ 4], x[ 5]); + z[ 9] = w0; w0 = 0; + + word3_muladd (&w0, &w2, &w1, x[ 5], x[ 5]); + z[10] = w1; + z[11] = w2; + } + +/* +* Comba 6x6 Multiplication +*/ +void bigint_comba_mul6(word z[12], const word x[6], const word y[6]) + { + word w2 = 0, w1 = 0, w0 = 0; + + word3_muladd(&w2, &w1, &w0, x[ 0], y[ 0]); + z[ 0] = w0; w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[ 0], y[ 1]); + word3_muladd(&w0, &w2, &w1, x[ 1], y[ 0]); + z[ 1] = w1; w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[ 0], y[ 2]); + word3_muladd(&w1, &w0, &w2, x[ 1], y[ 1]); + word3_muladd(&w1, &w0, &w2, x[ 2], y[ 0]); + z[ 2] = w2; w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[ 0], y[ 3]); + word3_muladd(&w2, &w1, &w0, x[ 1], y[ 2]); + word3_muladd(&w2, &w1, &w0, x[ 2], y[ 1]); + word3_muladd(&w2, &w1, &w0, x[ 3], y[ 0]); + z[ 3] = w0; w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[ 0], y[ 4]); + word3_muladd(&w0, &w2, &w1, x[ 1], y[ 3]); + word3_muladd(&w0, &w2, &w1, x[ 2], y[ 2]); + word3_muladd(&w0, &w2, &w1, x[ 3], y[ 1]); + word3_muladd(&w0, &w2, &w1, x[ 4], y[ 0]); + z[ 4] = w1; w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[ 0], y[ 5]); + word3_muladd(&w1, &w0, &w2, x[ 1], y[ 4]); + word3_muladd(&w1, &w0, &w2, x[ 2], y[ 3]); + word3_muladd(&w1, &w0, &w2, x[ 3], y[ 2]); + word3_muladd(&w1, &w0, &w2, x[ 4], y[ 1]); + word3_muladd(&w1, &w0, &w2, x[ 5], y[ 0]); + z[ 5] = w2; w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[ 1], y[ 5]); + word3_muladd(&w2, &w1, &w0, x[ 2], y[ 4]); + word3_muladd(&w2, &w1, &w0, x[ 3], y[ 3]); + word3_muladd(&w2, &w1, &w0, x[ 4], y[ 2]); + word3_muladd(&w2, &w1, &w0, x[ 5], y[ 1]); + z[ 6] = w0; w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[ 2], y[ 5]); + word3_muladd(&w0, &w2, &w1, x[ 3], y[ 4]); + word3_muladd(&w0, &w2, &w1, x[ 4], y[ 3]); + word3_muladd(&w0, &w2, &w1, x[ 5], y[ 2]); + z[ 7] = w1; w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[ 3], y[ 5]); + word3_muladd(&w1, &w0, &w2, x[ 4], y[ 4]); + word3_muladd(&w1, &w0, &w2, x[ 5], y[ 3]); + z[ 8] = w2; w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[ 4], y[ 5]); + word3_muladd(&w2, &w1, &w0, x[ 5], y[ 4]); + z[ 9] = w0; w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[ 5], y[ 5]); + z[10] = w1; + z[11] = w2; + } + +/* +* Comba 8x8 Squaring +*/ +void bigint_comba_sqr8(word z[16], const word x[8]) + { + word w2 = 0, w1 = 0, w0 = 0; + + word3_muladd (&w2, &w1, &w0, x[ 0], x[ 0]); + z[ 0] = w0; w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[ 0], x[ 1]); + z[ 1] = w1; w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[ 0], x[ 2]); + word3_muladd (&w1, &w0, &w2, x[ 1], x[ 1]); + z[ 2] = w2; w2 = 0; + + word3_muladd_2(&w2, &w1, &w0, x[ 0], x[ 3]); + word3_muladd_2(&w2, &w1, &w0, x[ 1], x[ 2]); + z[ 3] = w0; w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[ 0], x[ 4]); + word3_muladd_2(&w0, &w2, &w1, x[ 1], x[ 3]); + word3_muladd (&w0, &w2, &w1, x[ 2], x[ 2]); + z[ 4] = w1; w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[ 0], x[ 5]); + word3_muladd_2(&w1, &w0, &w2, x[ 1], x[ 4]); + word3_muladd_2(&w1, &w0, &w2, x[ 2], x[ 3]); + z[ 5] = w2; w2 = 0; + + word3_muladd_2(&w2, &w1, &w0, x[ 0], x[ 6]); + word3_muladd_2(&w2, &w1, &w0, x[ 1], x[ 5]); + word3_muladd_2(&w2, &w1, &w0, x[ 2], x[ 4]); + word3_muladd (&w2, &w1, &w0, x[ 3], x[ 3]); + z[ 6] = w0; w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[ 0], x[ 7]); + word3_muladd_2(&w0, &w2, &w1, x[ 1], x[ 6]); + word3_muladd_2(&w0, &w2, &w1, x[ 2], x[ 5]); + word3_muladd_2(&w0, &w2, &w1, x[ 3], x[ 4]); + z[ 7] = w1; w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[ 1], x[ 7]); + word3_muladd_2(&w1, &w0, &w2, x[ 2], x[ 6]); + word3_muladd_2(&w1, &w0, &w2, x[ 3], x[ 5]); + word3_muladd (&w1, &w0, &w2, x[ 4], x[ 4]); + z[ 8] = w2; w2 = 0; + + word3_muladd_2(&w2, &w1, &w0, x[ 2], x[ 7]); + word3_muladd_2(&w2, &w1, &w0, x[ 3], x[ 6]); + word3_muladd_2(&w2, &w1, &w0, x[ 4], x[ 5]); + z[ 9] = w0; w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[ 3], x[ 7]); + word3_muladd_2(&w0, &w2, &w1, x[ 4], x[ 6]); + word3_muladd (&w0, &w2, &w1, x[ 5], x[ 5]); + z[10] = w1; w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[ 4], x[ 7]); + word3_muladd_2(&w1, &w0, &w2, x[ 5], x[ 6]); + z[11] = w2; w2 = 0; + + word3_muladd_2(&w2, &w1, &w0, x[ 5], x[ 7]); + word3_muladd (&w2, &w1, &w0, x[ 6], x[ 6]); + z[12] = w0; w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[ 6], x[ 7]); + z[13] = w1; w1 = 0; + + word3_muladd (&w1, &w0, &w2, x[ 7], x[ 7]); + z[14] = w2; + z[15] = w0; + } + +/* +* Comba 8x8 Multiplication +*/ +void bigint_comba_mul8(word z[16], const word x[8], const word y[8]) + { + word w2 = 0, w1 = 0, w0 = 0; + + word3_muladd(&w2, &w1, &w0, x[ 0], y[ 0]); + z[ 0] = w0; w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[ 0], y[ 1]); + word3_muladd(&w0, &w2, &w1, x[ 1], y[ 0]); + z[ 1] = w1; w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[ 0], y[ 2]); + word3_muladd(&w1, &w0, &w2, x[ 1], y[ 1]); + word3_muladd(&w1, &w0, &w2, x[ 2], y[ 0]); + z[ 2] = w2; w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[ 0], y[ 3]); + word3_muladd(&w2, &w1, &w0, x[ 1], y[ 2]); + word3_muladd(&w2, &w1, &w0, x[ 2], y[ 1]); + word3_muladd(&w2, &w1, &w0, x[ 3], y[ 0]); + z[ 3] = w0; w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[ 0], y[ 4]); + word3_muladd(&w0, &w2, &w1, x[ 1], y[ 3]); + word3_muladd(&w0, &w2, &w1, x[ 2], y[ 2]); + word3_muladd(&w0, &w2, &w1, x[ 3], y[ 1]); + word3_muladd(&w0, &w2, &w1, x[ 4], y[ 0]); + z[ 4] = w1; w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[ 0], y[ 5]); + word3_muladd(&w1, &w0, &w2, x[ 1], y[ 4]); + word3_muladd(&w1, &w0, &w2, x[ 2], y[ 3]); + word3_muladd(&w1, &w0, &w2, x[ 3], y[ 2]); + word3_muladd(&w1, &w0, &w2, x[ 4], y[ 1]); + word3_muladd(&w1, &w0, &w2, x[ 5], y[ 0]); + z[ 5] = w2; w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[ 0], y[ 6]); + word3_muladd(&w2, &w1, &w0, x[ 1], y[ 5]); + word3_muladd(&w2, &w1, &w0, x[ 2], y[ 4]); + word3_muladd(&w2, &w1, &w0, x[ 3], y[ 3]); + word3_muladd(&w2, &w1, &w0, x[ 4], y[ 2]); + word3_muladd(&w2, &w1, &w0, x[ 5], y[ 1]); + word3_muladd(&w2, &w1, &w0, x[ 6], y[ 0]); + z[ 6] = w0; w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[ 0], y[ 7]); + word3_muladd(&w0, &w2, &w1, x[ 1], y[ 6]); + word3_muladd(&w0, &w2, &w1, x[ 2], y[ 5]); + word3_muladd(&w0, &w2, &w1, x[ 3], y[ 4]); + word3_muladd(&w0, &w2, &w1, x[ 4], y[ 3]); + word3_muladd(&w0, &w2, &w1, x[ 5], y[ 2]); + word3_muladd(&w0, &w2, &w1, x[ 6], y[ 1]); + word3_muladd(&w0, &w2, &w1, x[ 7], y[ 0]); + z[ 7] = w1; w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[ 1], y[ 7]); + word3_muladd(&w1, &w0, &w2, x[ 2], y[ 6]); + word3_muladd(&w1, &w0, &w2, x[ 3], y[ 5]); + word3_muladd(&w1, &w0, &w2, x[ 4], y[ 4]); + word3_muladd(&w1, &w0, &w2, x[ 5], y[ 3]); + word3_muladd(&w1, &w0, &w2, x[ 6], y[ 2]); + word3_muladd(&w1, &w0, &w2, x[ 7], y[ 1]); + z[ 8] = w2; w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[ 2], y[ 7]); + word3_muladd(&w2, &w1, &w0, x[ 3], y[ 6]); + word3_muladd(&w2, &w1, &w0, x[ 4], y[ 5]); + word3_muladd(&w2, &w1, &w0, x[ 5], y[ 4]); + word3_muladd(&w2, &w1, &w0, x[ 6], y[ 3]); + word3_muladd(&w2, &w1, &w0, x[ 7], y[ 2]); + z[ 9] = w0; w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[ 3], y[ 7]); + word3_muladd(&w0, &w2, &w1, x[ 4], y[ 6]); + word3_muladd(&w0, &w2, &w1, x[ 5], y[ 5]); + word3_muladd(&w0, &w2, &w1, x[ 6], y[ 4]); + word3_muladd(&w0, &w2, &w1, x[ 7], y[ 3]); + z[10] = w1; w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[ 4], y[ 7]); + word3_muladd(&w1, &w0, &w2, x[ 5], y[ 6]); + word3_muladd(&w1, &w0, &w2, x[ 6], y[ 5]); + word3_muladd(&w1, &w0, &w2, x[ 7], y[ 4]); + z[11] = w2; w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[ 5], y[ 7]); + word3_muladd(&w2, &w1, &w0, x[ 6], y[ 6]); + word3_muladd(&w2, &w1, &w0, x[ 7], y[ 5]); + z[12] = w0; w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[ 6], y[ 7]); + word3_muladd(&w0, &w2, &w1, x[ 7], y[ 6]); + z[13] = w1; w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[ 7], y[ 7]); + z[14] = w2; + z[15] = w0; + } + +/* +* Comba 9x9 Squaring +*/ +void bigint_comba_sqr9(word z[18], const word x[9]) + { + word w2 = 0, w1 = 0, w0 = 0; + + word3_muladd (&w2, &w1, &w0, x[ 0], x[ 0]); + z[ 0] = w0; w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[ 0], x[ 1]); + z[ 1] = w1; w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[ 0], x[ 2]); + word3_muladd (&w1, &w0, &w2, x[ 1], x[ 1]); + z[ 2] = w2; w2 = 0; + + word3_muladd_2(&w2, &w1, &w0, x[ 0], x[ 3]); + word3_muladd_2(&w2, &w1, &w0, x[ 1], x[ 2]); + z[ 3] = w0; w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[ 0], x[ 4]); + word3_muladd_2(&w0, &w2, &w1, x[ 1], x[ 3]); + word3_muladd (&w0, &w2, &w1, x[ 2], x[ 2]); + z[ 4] = w1; w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[ 0], x[ 5]); + word3_muladd_2(&w1, &w0, &w2, x[ 1], x[ 4]); + word3_muladd_2(&w1, &w0, &w2, x[ 2], x[ 3]); + z[ 5] = w2; w2 = 0; + + word3_muladd_2(&w2, &w1, &w0, x[ 0], x[ 6]); + word3_muladd_2(&w2, &w1, &w0, x[ 1], x[ 5]); + word3_muladd_2(&w2, &w1, &w0, x[ 2], x[ 4]); + word3_muladd (&w2, &w1, &w0, x[ 3], x[ 3]); + z[ 6] = w0; w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[ 0], x[ 7]); + word3_muladd_2(&w0, &w2, &w1, x[ 1], x[ 6]); + word3_muladd_2(&w0, &w2, &w1, x[ 2], x[ 5]); + word3_muladd_2(&w0, &w2, &w1, x[ 3], x[ 4]); + z[ 7] = w1; w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[ 0], x[ 8]); + word3_muladd_2(&w1, &w0, &w2, x[ 1], x[ 7]); + word3_muladd_2(&w1, &w0, &w2, x[ 2], x[ 6]); + word3_muladd_2(&w1, &w0, &w2, x[ 3], x[ 5]); + word3_muladd (&w1, &w0, &w2, x[ 4], x[ 4]); + z[ 8] = w2; w2 = 0; + + word3_muladd_2(&w2, &w1, &w0, x[ 1], x[ 8]); + word3_muladd_2(&w2, &w1, &w0, x[ 2], x[ 7]); + word3_muladd_2(&w2, &w1, &w0, x[ 3], x[ 6]); + word3_muladd_2(&w2, &w1, &w0, x[ 4], x[ 5]); + z[ 9] = w0; w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[ 2], x[ 8]); + word3_muladd_2(&w0, &w2, &w1, x[ 3], x[ 7]); + word3_muladd_2(&w0, &w2, &w1, x[ 4], x[ 6]); + word3_muladd (&w0, &w2, &w1, x[ 5], x[ 5]); + z[10] = w1; w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[ 3], x[ 8]); + word3_muladd_2(&w1, &w0, &w2, x[ 4], x[ 7]); + word3_muladd_2(&w1, &w0, &w2, x[ 5], x[ 6]); + z[11] = w2; w2 = 0; + + word3_muladd_2(&w2, &w1, &w0, x[ 4], x[ 8]); + word3_muladd_2(&w2, &w1, &w0, x[ 5], x[ 7]); + word3_muladd (&w2, &w1, &w0, x[ 6], x[ 6]); + z[12] = w0; w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[ 5], x[ 8]); + word3_muladd_2(&w0, &w2, &w1, x[ 6], x[ 7]); + z[13] = w1; w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[ 6], x[ 8]); + word3_muladd (&w1, &w0, &w2, x[ 7], x[ 7]); + z[14] = w2; w2 = 0; + + word3_muladd_2(&w2, &w1, &w0, x[ 7], x[ 8]); + z[15] = w0; w0 = 0; + + word3_muladd (&w0, &w2, &w1, x[ 8], x[ 8]); + z[16] = w1; + z[17] = w2; + } + +/* +* Comba 9x9 Multiplication +*/ +void bigint_comba_mul9(word z[18], const word x[9], const word y[9]) + { + word w2 = 0, w1 = 0, w0 = 0; + + word3_muladd(&w2, &w1, &w0, x[ 0], y[ 0]); + z[ 0] = w0; w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[ 0], y[ 1]); + word3_muladd(&w0, &w2, &w1, x[ 1], y[ 0]); + z[ 1] = w1; w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[ 0], y[ 2]); + word3_muladd(&w1, &w0, &w2, x[ 1], y[ 1]); + word3_muladd(&w1, &w0, &w2, x[ 2], y[ 0]); + z[ 2] = w2; w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[ 0], y[ 3]); + word3_muladd(&w2, &w1, &w0, x[ 1], y[ 2]); + word3_muladd(&w2, &w1, &w0, x[ 2], y[ 1]); + word3_muladd(&w2, &w1, &w0, x[ 3], y[ 0]); + z[ 3] = w0; w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[ 0], y[ 4]); + word3_muladd(&w0, &w2, &w1, x[ 1], y[ 3]); + word3_muladd(&w0, &w2, &w1, x[ 2], y[ 2]); + word3_muladd(&w0, &w2, &w1, x[ 3], y[ 1]); + word3_muladd(&w0, &w2, &w1, x[ 4], y[ 0]); + z[ 4] = w1; w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[ 0], y[ 5]); + word3_muladd(&w1, &w0, &w2, x[ 1], y[ 4]); + word3_muladd(&w1, &w0, &w2, x[ 2], y[ 3]); + word3_muladd(&w1, &w0, &w2, x[ 3], y[ 2]); + word3_muladd(&w1, &w0, &w2, x[ 4], y[ 1]); + word3_muladd(&w1, &w0, &w2, x[ 5], y[ 0]); + z[ 5] = w2; w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[ 0], y[ 6]); + word3_muladd(&w2, &w1, &w0, x[ 1], y[ 5]); + word3_muladd(&w2, &w1, &w0, x[ 2], y[ 4]); + word3_muladd(&w2, &w1, &w0, x[ 3], y[ 3]); + word3_muladd(&w2, &w1, &w0, x[ 4], y[ 2]); + word3_muladd(&w2, &w1, &w0, x[ 5], y[ 1]); + word3_muladd(&w2, &w1, &w0, x[ 6], y[ 0]); + z[ 6] = w0; w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[ 0], y[ 7]); + word3_muladd(&w0, &w2, &w1, x[ 1], y[ 6]); + word3_muladd(&w0, &w2, &w1, x[ 2], y[ 5]); + word3_muladd(&w0, &w2, &w1, x[ 3], y[ 4]); + word3_muladd(&w0, &w2, &w1, x[ 4], y[ 3]); + word3_muladd(&w0, &w2, &w1, x[ 5], y[ 2]); + word3_muladd(&w0, &w2, &w1, x[ 6], y[ 1]); + word3_muladd(&w0, &w2, &w1, x[ 7], y[ 0]); + z[ 7] = w1; w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[ 0], y[ 8]); + word3_muladd(&w1, &w0, &w2, x[ 1], y[ 7]); + word3_muladd(&w1, &w0, &w2, x[ 2], y[ 6]); + word3_muladd(&w1, &w0, &w2, x[ 3], y[ 5]); + word3_muladd(&w1, &w0, &w2, x[ 4], y[ 4]); + word3_muladd(&w1, &w0, &w2, x[ 5], y[ 3]); + word3_muladd(&w1, &w0, &w2, x[ 6], y[ 2]); + word3_muladd(&w1, &w0, &w2, x[ 7], y[ 1]); + word3_muladd(&w1, &w0, &w2, x[ 8], y[ 0]); + z[ 8] = w2; w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[ 1], y[ 8]); + word3_muladd(&w2, &w1, &w0, x[ 2], y[ 7]); + word3_muladd(&w2, &w1, &w0, x[ 3], y[ 6]); + word3_muladd(&w2, &w1, &w0, x[ 4], y[ 5]); + word3_muladd(&w2, &w1, &w0, x[ 5], y[ 4]); + word3_muladd(&w2, &w1, &w0, x[ 6], y[ 3]); + word3_muladd(&w2, &w1, &w0, x[ 7], y[ 2]); + word3_muladd(&w2, &w1, &w0, x[ 8], y[ 1]); + z[ 9] = w0; w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[ 2], y[ 8]); + word3_muladd(&w0, &w2, &w1, x[ 3], y[ 7]); + word3_muladd(&w0, &w2, &w1, x[ 4], y[ 6]); + word3_muladd(&w0, &w2, &w1, x[ 5], y[ 5]); + word3_muladd(&w0, &w2, &w1, x[ 6], y[ 4]); + word3_muladd(&w0, &w2, &w1, x[ 7], y[ 3]); + word3_muladd(&w0, &w2, &w1, x[ 8], y[ 2]); + z[10] = w1; w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[ 3], y[ 8]); + word3_muladd(&w1, &w0, &w2, x[ 4], y[ 7]); + word3_muladd(&w1, &w0, &w2, x[ 5], y[ 6]); + word3_muladd(&w1, &w0, &w2, x[ 6], y[ 5]); + word3_muladd(&w1, &w0, &w2, x[ 7], y[ 4]); + word3_muladd(&w1, &w0, &w2, x[ 8], y[ 3]); + z[11] = w2; w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[ 4], y[ 8]); + word3_muladd(&w2, &w1, &w0, x[ 5], y[ 7]); + word3_muladd(&w2, &w1, &w0, x[ 6], y[ 6]); + word3_muladd(&w2, &w1, &w0, x[ 7], y[ 5]); + word3_muladd(&w2, &w1, &w0, x[ 8], y[ 4]); + z[12] = w0; w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[ 5], y[ 8]); + word3_muladd(&w0, &w2, &w1, x[ 6], y[ 7]); + word3_muladd(&w0, &w2, &w1, x[ 7], y[ 6]); + word3_muladd(&w0, &w2, &w1, x[ 8], y[ 5]); + z[13] = w1; w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[ 6], y[ 8]); + word3_muladd(&w1, &w0, &w2, x[ 7], y[ 7]); + word3_muladd(&w1, &w0, &w2, x[ 8], y[ 6]); + z[14] = w2; w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[ 7], y[ 8]); + word3_muladd(&w2, &w1, &w0, x[ 8], y[ 7]); + z[15] = w0; w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[ 8], y[ 8]); + z[16] = w1; + z[17] = w2; + } + +/* +* Comba 16x16 Squaring +*/ +void bigint_comba_sqr16(word z[32], const word x[16]) + { + word w2 = 0, w1 = 0, w0 = 0; + + word3_muladd (&w2, &w1, &w0, x[ 0], x[ 0]); + z[ 0] = w0; w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[ 0], x[ 1]); + z[ 1] = w1; w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[ 0], x[ 2]); + word3_muladd (&w1, &w0, &w2, x[ 1], x[ 1]); + z[ 2] = w2; w2 = 0; + + word3_muladd_2(&w2, &w1, &w0, x[ 0], x[ 3]); + word3_muladd_2(&w2, &w1, &w0, x[ 1], x[ 2]); + z[ 3] = w0; w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[ 0], x[ 4]); + word3_muladd_2(&w0, &w2, &w1, x[ 1], x[ 3]); + word3_muladd (&w0, &w2, &w1, x[ 2], x[ 2]); + z[ 4] = w1; w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[ 0], x[ 5]); + word3_muladd_2(&w1, &w0, &w2, x[ 1], x[ 4]); + word3_muladd_2(&w1, &w0, &w2, x[ 2], x[ 3]); + z[ 5] = w2; w2 = 0; + + word3_muladd_2(&w2, &w1, &w0, x[ 0], x[ 6]); + word3_muladd_2(&w2, &w1, &w0, x[ 1], x[ 5]); + word3_muladd_2(&w2, &w1, &w0, x[ 2], x[ 4]); + word3_muladd (&w2, &w1, &w0, x[ 3], x[ 3]); + z[ 6] = w0; w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[ 0], x[ 7]); + word3_muladd_2(&w0, &w2, &w1, x[ 1], x[ 6]); + word3_muladd_2(&w0, &w2, &w1, x[ 2], x[ 5]); + word3_muladd_2(&w0, &w2, &w1, x[ 3], x[ 4]); + z[ 7] = w1; w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[ 0], x[ 8]); + word3_muladd_2(&w1, &w0, &w2, x[ 1], x[ 7]); + word3_muladd_2(&w1, &w0, &w2, x[ 2], x[ 6]); + word3_muladd_2(&w1, &w0, &w2, x[ 3], x[ 5]); + word3_muladd (&w1, &w0, &w2, x[ 4], x[ 4]); + z[ 8] = w2; w2 = 0; + + word3_muladd_2(&w2, &w1, &w0, x[ 0], x[ 9]); + word3_muladd_2(&w2, &w1, &w0, x[ 1], x[ 8]); + word3_muladd_2(&w2, &w1, &w0, x[ 2], x[ 7]); + word3_muladd_2(&w2, &w1, &w0, x[ 3], x[ 6]); + word3_muladd_2(&w2, &w1, &w0, x[ 4], x[ 5]); + z[ 9] = w0; w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[ 0], x[10]); + word3_muladd_2(&w0, &w2, &w1, x[ 1], x[ 9]); + word3_muladd_2(&w0, &w2, &w1, x[ 2], x[ 8]); + word3_muladd_2(&w0, &w2, &w1, x[ 3], x[ 7]); + word3_muladd_2(&w0, &w2, &w1, x[ 4], x[ 6]); + word3_muladd (&w0, &w2, &w1, x[ 5], x[ 5]); + z[10] = w1; w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[ 0], x[11]); + word3_muladd_2(&w1, &w0, &w2, x[ 1], x[10]); + word3_muladd_2(&w1, &w0, &w2, x[ 2], x[ 9]); + word3_muladd_2(&w1, &w0, &w2, x[ 3], x[ 8]); + word3_muladd_2(&w1, &w0, &w2, x[ 4], x[ 7]); + word3_muladd_2(&w1, &w0, &w2, x[ 5], x[ 6]); + z[11] = w2; w2 = 0; + + word3_muladd_2(&w2, &w1, &w0, x[ 0], x[12]); + word3_muladd_2(&w2, &w1, &w0, x[ 1], x[11]); + word3_muladd_2(&w2, &w1, &w0, x[ 2], x[10]); + word3_muladd_2(&w2, &w1, &w0, x[ 3], x[ 9]); + word3_muladd_2(&w2, &w1, &w0, x[ 4], x[ 8]); + word3_muladd_2(&w2, &w1, &w0, x[ 5], x[ 7]); + word3_muladd (&w2, &w1, &w0, x[ 6], x[ 6]); + z[12] = w0; w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[ 0], x[13]); + word3_muladd_2(&w0, &w2, &w1, x[ 1], x[12]); + word3_muladd_2(&w0, &w2, &w1, x[ 2], x[11]); + word3_muladd_2(&w0, &w2, &w1, x[ 3], x[10]); + word3_muladd_2(&w0, &w2, &w1, x[ 4], x[ 9]); + word3_muladd_2(&w0, &w2, &w1, x[ 5], x[ 8]); + word3_muladd_2(&w0, &w2, &w1, x[ 6], x[ 7]); + z[13] = w1; w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[ 0], x[14]); + word3_muladd_2(&w1, &w0, &w2, x[ 1], x[13]); + word3_muladd_2(&w1, &w0, &w2, x[ 2], x[12]); + word3_muladd_2(&w1, &w0, &w2, x[ 3], x[11]); + word3_muladd_2(&w1, &w0, &w2, x[ 4], x[10]); + word3_muladd_2(&w1, &w0, &w2, x[ 5], x[ 9]); + word3_muladd_2(&w1, &w0, &w2, x[ 6], x[ 8]); + word3_muladd (&w1, &w0, &w2, x[ 7], x[ 7]); + z[14] = w2; w2 = 0; + + word3_muladd_2(&w2, &w1, &w0, x[ 0], x[15]); + word3_muladd_2(&w2, &w1, &w0, x[ 1], x[14]); + word3_muladd_2(&w2, &w1, &w0, x[ 2], x[13]); + word3_muladd_2(&w2, &w1, &w0, x[ 3], x[12]); + word3_muladd_2(&w2, &w1, &w0, x[ 4], x[11]); + word3_muladd_2(&w2, &w1, &w0, x[ 5], x[10]); + word3_muladd_2(&w2, &w1, &w0, x[ 6], x[ 9]); + word3_muladd_2(&w2, &w1, &w0, x[ 7], x[ 8]); + z[15] = w0; w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[ 1], x[15]); + word3_muladd_2(&w0, &w2, &w1, x[ 2], x[14]); + word3_muladd_2(&w0, &w2, &w1, x[ 3], x[13]); + word3_muladd_2(&w0, &w2, &w1, x[ 4], x[12]); + word3_muladd_2(&w0, &w2, &w1, x[ 5], x[11]); + word3_muladd_2(&w0, &w2, &w1, x[ 6], x[10]); + word3_muladd_2(&w0, &w2, &w1, x[ 7], x[ 9]); + word3_muladd (&w0, &w2, &w1, x[ 8], x[ 8]); + z[16] = w1; w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[ 2], x[15]); + word3_muladd_2(&w1, &w0, &w2, x[ 3], x[14]); + word3_muladd_2(&w1, &w0, &w2, x[ 4], x[13]); + word3_muladd_2(&w1, &w0, &w2, x[ 5], x[12]); + word3_muladd_2(&w1, &w0, &w2, x[ 6], x[11]); + word3_muladd_2(&w1, &w0, &w2, x[ 7], x[10]); + word3_muladd_2(&w1, &w0, &w2, x[ 8], x[ 9]); + z[17] = w2; w2 = 0; + + word3_muladd_2(&w2, &w1, &w0, x[ 3], x[15]); + word3_muladd_2(&w2, &w1, &w0, x[ 4], x[14]); + word3_muladd_2(&w2, &w1, &w0, x[ 5], x[13]); + word3_muladd_2(&w2, &w1, &w0, x[ 6], x[12]); + word3_muladd_2(&w2, &w1, &w0, x[ 7], x[11]); + word3_muladd_2(&w2, &w1, &w0, x[ 8], x[10]); + word3_muladd (&w2, &w1, &w0, x[ 9], x[ 9]); + z[18] = w0; w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[ 4], x[15]); + word3_muladd_2(&w0, &w2, &w1, x[ 5], x[14]); + word3_muladd_2(&w0, &w2, &w1, x[ 6], x[13]); + word3_muladd_2(&w0, &w2, &w1, x[ 7], x[12]); + word3_muladd_2(&w0, &w2, &w1, x[ 8], x[11]); + word3_muladd_2(&w0, &w2, &w1, x[ 9], x[10]); + z[19] = w1; w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[ 5], x[15]); + word3_muladd_2(&w1, &w0, &w2, x[ 6], x[14]); + word3_muladd_2(&w1, &w0, &w2, x[ 7], x[13]); + word3_muladd_2(&w1, &w0, &w2, x[ 8], x[12]); + word3_muladd_2(&w1, &w0, &w2, x[ 9], x[11]); + word3_muladd (&w1, &w0, &w2, x[10], x[10]); + z[20] = w2; w2 = 0; + + word3_muladd_2(&w2, &w1, &w0, x[ 6], x[15]); + word3_muladd_2(&w2, &w1, &w0, x[ 7], x[14]); + word3_muladd_2(&w2, &w1, &w0, x[ 8], x[13]); + word3_muladd_2(&w2, &w1, &w0, x[ 9], x[12]); + word3_muladd_2(&w2, &w1, &w0, x[10], x[11]); + z[21] = w0; w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[ 7], x[15]); + word3_muladd_2(&w0, &w2, &w1, x[ 8], x[14]); + word3_muladd_2(&w0, &w2, &w1, x[ 9], x[13]); + word3_muladd_2(&w0, &w2, &w1, x[10], x[12]); + word3_muladd (&w0, &w2, &w1, x[11], x[11]); + z[22] = w1; w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[ 8], x[15]); + word3_muladd_2(&w1, &w0, &w2, x[ 9], x[14]); + word3_muladd_2(&w1, &w0, &w2, x[10], x[13]); + word3_muladd_2(&w1, &w0, &w2, x[11], x[12]); + z[23] = w2; w2 = 0; + + word3_muladd_2(&w2, &w1, &w0, x[ 9], x[15]); + word3_muladd_2(&w2, &w1, &w0, x[10], x[14]); + word3_muladd_2(&w2, &w1, &w0, x[11], x[13]); + word3_muladd (&w2, &w1, &w0, x[12], x[12]); + z[24] = w0; w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[10], x[15]); + word3_muladd_2(&w0, &w2, &w1, x[11], x[14]); + word3_muladd_2(&w0, &w2, &w1, x[12], x[13]); + z[25] = w1; w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[11], x[15]); + word3_muladd_2(&w1, &w0, &w2, x[12], x[14]); + word3_muladd (&w1, &w0, &w2, x[13], x[13]); + z[26] = w2; w2 = 0; + + word3_muladd_2(&w2, &w1, &w0, x[12], x[15]); + word3_muladd_2(&w2, &w1, &w0, x[13], x[14]); + z[27] = w0; w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[13], x[15]); + word3_muladd (&w0, &w2, &w1, x[14], x[14]); + z[28] = w1; w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[14], x[15]); + z[29] = w2; w2 = 0; + + word3_muladd (&w2, &w1, &w0, x[15], x[15]); + z[30] = w0; + z[31] = w1; + } + +/* +* Comba 16x16 Multiplication +*/ +void bigint_comba_mul16(word z[32], const word x[16], const word y[16]) + { + word w2 = 0, w1 = 0, w0 = 0; + + word3_muladd(&w2, &w1, &w0, x[ 0], y[ 0]); + z[ 0] = w0; w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[ 0], y[ 1]); + word3_muladd(&w0, &w2, &w1, x[ 1], y[ 0]); + z[ 1] = w1; w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[ 0], y[ 2]); + word3_muladd(&w1, &w0, &w2, x[ 1], y[ 1]); + word3_muladd(&w1, &w0, &w2, x[ 2], y[ 0]); + z[ 2] = w2; w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[ 0], y[ 3]); + word3_muladd(&w2, &w1, &w0, x[ 1], y[ 2]); + word3_muladd(&w2, &w1, &w0, x[ 2], y[ 1]); + word3_muladd(&w2, &w1, &w0, x[ 3], y[ 0]); + z[ 3] = w0; w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[ 0], y[ 4]); + word3_muladd(&w0, &w2, &w1, x[ 1], y[ 3]); + word3_muladd(&w0, &w2, &w1, x[ 2], y[ 2]); + word3_muladd(&w0, &w2, &w1, x[ 3], y[ 1]); + word3_muladd(&w0, &w2, &w1, x[ 4], y[ 0]); + z[ 4] = w1; w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[ 0], y[ 5]); + word3_muladd(&w1, &w0, &w2, x[ 1], y[ 4]); + word3_muladd(&w1, &w0, &w2, x[ 2], y[ 3]); + word3_muladd(&w1, &w0, &w2, x[ 3], y[ 2]); + word3_muladd(&w1, &w0, &w2, x[ 4], y[ 1]); + word3_muladd(&w1, &w0, &w2, x[ 5], y[ 0]); + z[ 5] = w2; w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[ 0], y[ 6]); + word3_muladd(&w2, &w1, &w0, x[ 1], y[ 5]); + word3_muladd(&w2, &w1, &w0, x[ 2], y[ 4]); + word3_muladd(&w2, &w1, &w0, x[ 3], y[ 3]); + word3_muladd(&w2, &w1, &w0, x[ 4], y[ 2]); + word3_muladd(&w2, &w1, &w0, x[ 5], y[ 1]); + word3_muladd(&w2, &w1, &w0, x[ 6], y[ 0]); + z[ 6] = w0; w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[ 0], y[ 7]); + word3_muladd(&w0, &w2, &w1, x[ 1], y[ 6]); + word3_muladd(&w0, &w2, &w1, x[ 2], y[ 5]); + word3_muladd(&w0, &w2, &w1, x[ 3], y[ 4]); + word3_muladd(&w0, &w2, &w1, x[ 4], y[ 3]); + word3_muladd(&w0, &w2, &w1, x[ 5], y[ 2]); + word3_muladd(&w0, &w2, &w1, x[ 6], y[ 1]); + word3_muladd(&w0, &w2, &w1, x[ 7], y[ 0]); + z[ 7] = w1; w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[ 0], y[ 8]); + word3_muladd(&w1, &w0, &w2, x[ 1], y[ 7]); + word3_muladd(&w1, &w0, &w2, x[ 2], y[ 6]); + word3_muladd(&w1, &w0, &w2, x[ 3], y[ 5]); + word3_muladd(&w1, &w0, &w2, x[ 4], y[ 4]); + word3_muladd(&w1, &w0, &w2, x[ 5], y[ 3]); + word3_muladd(&w1, &w0, &w2, x[ 6], y[ 2]); + word3_muladd(&w1, &w0, &w2, x[ 7], y[ 1]); + word3_muladd(&w1, &w0, &w2, x[ 8], y[ 0]); + z[ 8] = w2; w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[ 0], y[ 9]); + word3_muladd(&w2, &w1, &w0, x[ 1], y[ 8]); + word3_muladd(&w2, &w1, &w0, x[ 2], y[ 7]); + word3_muladd(&w2, &w1, &w0, x[ 3], y[ 6]); + word3_muladd(&w2, &w1, &w0, x[ 4], y[ 5]); + word3_muladd(&w2, &w1, &w0, x[ 5], y[ 4]); + word3_muladd(&w2, &w1, &w0, x[ 6], y[ 3]); + word3_muladd(&w2, &w1, &w0, x[ 7], y[ 2]); + word3_muladd(&w2, &w1, &w0, x[ 8], y[ 1]); + word3_muladd(&w2, &w1, &w0, x[ 9], y[ 0]); + z[ 9] = w0; w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[ 0], y[10]); + word3_muladd(&w0, &w2, &w1, x[ 1], y[ 9]); + word3_muladd(&w0, &w2, &w1, x[ 2], y[ 8]); + word3_muladd(&w0, &w2, &w1, x[ 3], y[ 7]); + word3_muladd(&w0, &w2, &w1, x[ 4], y[ 6]); + word3_muladd(&w0, &w2, &w1, x[ 5], y[ 5]); + word3_muladd(&w0, &w2, &w1, x[ 6], y[ 4]); + word3_muladd(&w0, &w2, &w1, x[ 7], y[ 3]); + word3_muladd(&w0, &w2, &w1, x[ 8], y[ 2]); + word3_muladd(&w0, &w2, &w1, x[ 9], y[ 1]); + word3_muladd(&w0, &w2, &w1, x[10], y[ 0]); + z[10] = w1; w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[ 0], y[11]); + word3_muladd(&w1, &w0, &w2, x[ 1], y[10]); + word3_muladd(&w1, &w0, &w2, x[ 2], y[ 9]); + word3_muladd(&w1, &w0, &w2, x[ 3], y[ 8]); + word3_muladd(&w1, &w0, &w2, x[ 4], y[ 7]); + word3_muladd(&w1, &w0, &w2, x[ 5], y[ 6]); + word3_muladd(&w1, &w0, &w2, x[ 6], y[ 5]); + word3_muladd(&w1, &w0, &w2, x[ 7], y[ 4]); + word3_muladd(&w1, &w0, &w2, x[ 8], y[ 3]); + word3_muladd(&w1, &w0, &w2, x[ 9], y[ 2]); + word3_muladd(&w1, &w0, &w2, x[10], y[ 1]); + word3_muladd(&w1, &w0, &w2, x[11], y[ 0]); + z[11] = w2; w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[ 0], y[12]); + word3_muladd(&w2, &w1, &w0, x[ 1], y[11]); + word3_muladd(&w2, &w1, &w0, x[ 2], y[10]); + word3_muladd(&w2, &w1, &w0, x[ 3], y[ 9]); + word3_muladd(&w2, &w1, &w0, x[ 4], y[ 8]); + word3_muladd(&w2, &w1, &w0, x[ 5], y[ 7]); + word3_muladd(&w2, &w1, &w0, x[ 6], y[ 6]); + word3_muladd(&w2, &w1, &w0, x[ 7], y[ 5]); + word3_muladd(&w2, &w1, &w0, x[ 8], y[ 4]); + word3_muladd(&w2, &w1, &w0, x[ 9], y[ 3]); + word3_muladd(&w2, &w1, &w0, x[10], y[ 2]); + word3_muladd(&w2, &w1, &w0, x[11], y[ 1]); + word3_muladd(&w2, &w1, &w0, x[12], y[ 0]); + z[12] = w0; w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[ 0], y[13]); + word3_muladd(&w0, &w2, &w1, x[ 1], y[12]); + word3_muladd(&w0, &w2, &w1, x[ 2], y[11]); + word3_muladd(&w0, &w2, &w1, x[ 3], y[10]); + word3_muladd(&w0, &w2, &w1, x[ 4], y[ 9]); + word3_muladd(&w0, &w2, &w1, x[ 5], y[ 8]); + word3_muladd(&w0, &w2, &w1, x[ 6], y[ 7]); + word3_muladd(&w0, &w2, &w1, x[ 7], y[ 6]); + word3_muladd(&w0, &w2, &w1, x[ 8], y[ 5]); + word3_muladd(&w0, &w2, &w1, x[ 9], y[ 4]); + word3_muladd(&w0, &w2, &w1, x[10], y[ 3]); + word3_muladd(&w0, &w2, &w1, x[11], y[ 2]); + word3_muladd(&w0, &w2, &w1, x[12], y[ 1]); + word3_muladd(&w0, &w2, &w1, x[13], y[ 0]); + z[13] = w1; w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[ 0], y[14]); + word3_muladd(&w1, &w0, &w2, x[ 1], y[13]); + word3_muladd(&w1, &w0, &w2, x[ 2], y[12]); + word3_muladd(&w1, &w0, &w2, x[ 3], y[11]); + word3_muladd(&w1, &w0, &w2, x[ 4], y[10]); + word3_muladd(&w1, &w0, &w2, x[ 5], y[ 9]); + word3_muladd(&w1, &w0, &w2, x[ 6], y[ 8]); + word3_muladd(&w1, &w0, &w2, x[ 7], y[ 7]); + word3_muladd(&w1, &w0, &w2, x[ 8], y[ 6]); + word3_muladd(&w1, &w0, &w2, x[ 9], y[ 5]); + word3_muladd(&w1, &w0, &w2, x[10], y[ 4]); + word3_muladd(&w1, &w0, &w2, x[11], y[ 3]); + word3_muladd(&w1, &w0, &w2, x[12], y[ 2]); + word3_muladd(&w1, &w0, &w2, x[13], y[ 1]); + word3_muladd(&w1, &w0, &w2, x[14], y[ 0]); + z[14] = w2; w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[ 0], y[15]); + word3_muladd(&w2, &w1, &w0, x[ 1], y[14]); + word3_muladd(&w2, &w1, &w0, x[ 2], y[13]); + word3_muladd(&w2, &w1, &w0, x[ 3], y[12]); + word3_muladd(&w2, &w1, &w0, x[ 4], y[11]); + word3_muladd(&w2, &w1, &w0, x[ 5], y[10]); + word3_muladd(&w2, &w1, &w0, x[ 6], y[ 9]); + word3_muladd(&w2, &w1, &w0, x[ 7], y[ 8]); + word3_muladd(&w2, &w1, &w0, x[ 8], y[ 7]); + word3_muladd(&w2, &w1, &w0, x[ 9], y[ 6]); + word3_muladd(&w2, &w1, &w0, x[10], y[ 5]); + word3_muladd(&w2, &w1, &w0, x[11], y[ 4]); + word3_muladd(&w2, &w1, &w0, x[12], y[ 3]); + word3_muladd(&w2, &w1, &w0, x[13], y[ 2]); + word3_muladd(&w2, &w1, &w0, x[14], y[ 1]); + word3_muladd(&w2, &w1, &w0, x[15], y[ 0]); + z[15] = w0; w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[ 1], y[15]); + word3_muladd(&w0, &w2, &w1, x[ 2], y[14]); + word3_muladd(&w0, &w2, &w1, x[ 3], y[13]); + word3_muladd(&w0, &w2, &w1, x[ 4], y[12]); + word3_muladd(&w0, &w2, &w1, x[ 5], y[11]); + word3_muladd(&w0, &w2, &w1, x[ 6], y[10]); + word3_muladd(&w0, &w2, &w1, x[ 7], y[ 9]); + word3_muladd(&w0, &w2, &w1, x[ 8], y[ 8]); + word3_muladd(&w0, &w2, &w1, x[ 9], y[ 7]); + word3_muladd(&w0, &w2, &w1, x[10], y[ 6]); + word3_muladd(&w0, &w2, &w1, x[11], y[ 5]); + word3_muladd(&w0, &w2, &w1, x[12], y[ 4]); + word3_muladd(&w0, &w2, &w1, x[13], y[ 3]); + word3_muladd(&w0, &w2, &w1, x[14], y[ 2]); + word3_muladd(&w0, &w2, &w1, x[15], y[ 1]); + z[16] = w1; w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[ 2], y[15]); + word3_muladd(&w1, &w0, &w2, x[ 3], y[14]); + word3_muladd(&w1, &w0, &w2, x[ 4], y[13]); + word3_muladd(&w1, &w0, &w2, x[ 5], y[12]); + word3_muladd(&w1, &w0, &w2, x[ 6], y[11]); + word3_muladd(&w1, &w0, &w2, x[ 7], y[10]); + word3_muladd(&w1, &w0, &w2, x[ 8], y[ 9]); + word3_muladd(&w1, &w0, &w2, x[ 9], y[ 8]); + word3_muladd(&w1, &w0, &w2, x[10], y[ 7]); + word3_muladd(&w1, &w0, &w2, x[11], y[ 6]); + word3_muladd(&w1, &w0, &w2, x[12], y[ 5]); + word3_muladd(&w1, &w0, &w2, x[13], y[ 4]); + word3_muladd(&w1, &w0, &w2, x[14], y[ 3]); + word3_muladd(&w1, &w0, &w2, x[15], y[ 2]); + z[17] = w2; w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[ 3], y[15]); + word3_muladd(&w2, &w1, &w0, x[ 4], y[14]); + word3_muladd(&w2, &w1, &w0, x[ 5], y[13]); + word3_muladd(&w2, &w1, &w0, x[ 6], y[12]); + word3_muladd(&w2, &w1, &w0, x[ 7], y[11]); + word3_muladd(&w2, &w1, &w0, x[ 8], y[10]); + word3_muladd(&w2, &w1, &w0, x[ 9], y[ 9]); + word3_muladd(&w2, &w1, &w0, x[10], y[ 8]); + word3_muladd(&w2, &w1, &w0, x[11], y[ 7]); + word3_muladd(&w2, &w1, &w0, x[12], y[ 6]); + word3_muladd(&w2, &w1, &w0, x[13], y[ 5]); + word3_muladd(&w2, &w1, &w0, x[14], y[ 4]); + word3_muladd(&w2, &w1, &w0, x[15], y[ 3]); + z[18] = w0; w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[ 4], y[15]); + word3_muladd(&w0, &w2, &w1, x[ 5], y[14]); + word3_muladd(&w0, &w2, &w1, x[ 6], y[13]); + word3_muladd(&w0, &w2, &w1, x[ 7], y[12]); + word3_muladd(&w0, &w2, &w1, x[ 8], y[11]); + word3_muladd(&w0, &w2, &w1, x[ 9], y[10]); + word3_muladd(&w0, &w2, &w1, x[10], y[ 9]); + word3_muladd(&w0, &w2, &w1, x[11], y[ 8]); + word3_muladd(&w0, &w2, &w1, x[12], y[ 7]); + word3_muladd(&w0, &w2, &w1, x[13], y[ 6]); + word3_muladd(&w0, &w2, &w1, x[14], y[ 5]); + word3_muladd(&w0, &w2, &w1, x[15], y[ 4]); + z[19] = w1; w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[ 5], y[15]); + word3_muladd(&w1, &w0, &w2, x[ 6], y[14]); + word3_muladd(&w1, &w0, &w2, x[ 7], y[13]); + word3_muladd(&w1, &w0, &w2, x[ 8], y[12]); + word3_muladd(&w1, &w0, &w2, x[ 9], y[11]); + word3_muladd(&w1, &w0, &w2, x[10], y[10]); + word3_muladd(&w1, &w0, &w2, x[11], y[ 9]); + word3_muladd(&w1, &w0, &w2, x[12], y[ 8]); + word3_muladd(&w1, &w0, &w2, x[13], y[ 7]); + word3_muladd(&w1, &w0, &w2, x[14], y[ 6]); + word3_muladd(&w1, &w0, &w2, x[15], y[ 5]); + z[20] = w2; w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[ 6], y[15]); + word3_muladd(&w2, &w1, &w0, x[ 7], y[14]); + word3_muladd(&w2, &w1, &w0, x[ 8], y[13]); + word3_muladd(&w2, &w1, &w0, x[ 9], y[12]); + word3_muladd(&w2, &w1, &w0, x[10], y[11]); + word3_muladd(&w2, &w1, &w0, x[11], y[10]); + word3_muladd(&w2, &w1, &w0, x[12], y[ 9]); + word3_muladd(&w2, &w1, &w0, x[13], y[ 8]); + word3_muladd(&w2, &w1, &w0, x[14], y[ 7]); + word3_muladd(&w2, &w1, &w0, x[15], y[ 6]); + z[21] = w0; w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[ 7], y[15]); + word3_muladd(&w0, &w2, &w1, x[ 8], y[14]); + word3_muladd(&w0, &w2, &w1, x[ 9], y[13]); + word3_muladd(&w0, &w2, &w1, x[10], y[12]); + word3_muladd(&w0, &w2, &w1, x[11], y[11]); + word3_muladd(&w0, &w2, &w1, x[12], y[10]); + word3_muladd(&w0, &w2, &w1, x[13], y[ 9]); + word3_muladd(&w0, &w2, &w1, x[14], y[ 8]); + word3_muladd(&w0, &w2, &w1, x[15], y[ 7]); + z[22] = w1; w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[ 8], y[15]); + word3_muladd(&w1, &w0, &w2, x[ 9], y[14]); + word3_muladd(&w1, &w0, &w2, x[10], y[13]); + word3_muladd(&w1, &w0, &w2, x[11], y[12]); + word3_muladd(&w1, &w0, &w2, x[12], y[11]); + word3_muladd(&w1, &w0, &w2, x[13], y[10]); + word3_muladd(&w1, &w0, &w2, x[14], y[ 9]); + word3_muladd(&w1, &w0, &w2, x[15], y[ 8]); + z[23] = w2; w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[ 9], y[15]); + word3_muladd(&w2, &w1, &w0, x[10], y[14]); + word3_muladd(&w2, &w1, &w0, x[11], y[13]); + word3_muladd(&w2, &w1, &w0, x[12], y[12]); + word3_muladd(&w2, &w1, &w0, x[13], y[11]); + word3_muladd(&w2, &w1, &w0, x[14], y[10]); + word3_muladd(&w2, &w1, &w0, x[15], y[ 9]); + z[24] = w0; w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[10], y[15]); + word3_muladd(&w0, &w2, &w1, x[11], y[14]); + word3_muladd(&w0, &w2, &w1, x[12], y[13]); + word3_muladd(&w0, &w2, &w1, x[13], y[12]); + word3_muladd(&w0, &w2, &w1, x[14], y[11]); + word3_muladd(&w0, &w2, &w1, x[15], y[10]); + z[25] = w1; w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[11], y[15]); + word3_muladd(&w1, &w0, &w2, x[12], y[14]); + word3_muladd(&w1, &w0, &w2, x[13], y[13]); + word3_muladd(&w1, &w0, &w2, x[14], y[12]); + word3_muladd(&w1, &w0, &w2, x[15], y[11]); + z[26] = w2; w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[12], y[15]); + word3_muladd(&w2, &w1, &w0, x[13], y[14]); + word3_muladd(&w2, &w1, &w0, x[14], y[13]); + word3_muladd(&w2, &w1, &w0, x[15], y[12]); + z[27] = w0; w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[13], y[15]); + word3_muladd(&w0, &w2, &w1, x[14], y[14]); + word3_muladd(&w0, &w2, &w1, x[15], y[13]); + z[28] = w1; w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[14], y[15]); + word3_muladd(&w1, &w0, &w2, x[15], y[14]); + z[29] = w2; w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[15], y[15]); + z[30] = w0; + z[31] = w1; + } + +/* +* Comba 24x24 Squaring +*/ +void bigint_comba_sqr24(word z[48], const word x[24]) + { + word w2 = 0, w1 = 0, w0 = 0; + + word3_muladd (&w2, &w1, &w0, x[ 0], x[ 0]); + z[ 0] = w0; w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[ 0], x[ 1]); + z[ 1] = w1; w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[ 0], x[ 2]); + word3_muladd (&w1, &w0, &w2, x[ 1], x[ 1]); + z[ 2] = w2; w2 = 0; + + word3_muladd_2(&w2, &w1, &w0, x[ 0], x[ 3]); + word3_muladd_2(&w2, &w1, &w0, x[ 1], x[ 2]); + z[ 3] = w0; w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[ 0], x[ 4]); + word3_muladd_2(&w0, &w2, &w1, x[ 1], x[ 3]); + word3_muladd (&w0, &w2, &w1, x[ 2], x[ 2]); + z[ 4] = w1; w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[ 0], x[ 5]); + word3_muladd_2(&w1, &w0, &w2, x[ 1], x[ 4]); + word3_muladd_2(&w1, &w0, &w2, x[ 2], x[ 3]); + z[ 5] = w2; w2 = 0; + + word3_muladd_2(&w2, &w1, &w0, x[ 0], x[ 6]); + word3_muladd_2(&w2, &w1, &w0, x[ 1], x[ 5]); + word3_muladd_2(&w2, &w1, &w0, x[ 2], x[ 4]); + word3_muladd (&w2, &w1, &w0, x[ 3], x[ 3]); + z[ 6] = w0; w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[ 0], x[ 7]); + word3_muladd_2(&w0, &w2, &w1, x[ 1], x[ 6]); + word3_muladd_2(&w0, &w2, &w1, x[ 2], x[ 5]); + word3_muladd_2(&w0, &w2, &w1, x[ 3], x[ 4]); + z[ 7] = w1; w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[ 0], x[ 8]); + word3_muladd_2(&w1, &w0, &w2, x[ 1], x[ 7]); + word3_muladd_2(&w1, &w0, &w2, x[ 2], x[ 6]); + word3_muladd_2(&w1, &w0, &w2, x[ 3], x[ 5]); + word3_muladd (&w1, &w0, &w2, x[ 4], x[ 4]); + z[ 8] = w2; w2 = 0; + + word3_muladd_2(&w2, &w1, &w0, x[ 0], x[ 9]); + word3_muladd_2(&w2, &w1, &w0, x[ 1], x[ 8]); + word3_muladd_2(&w2, &w1, &w0, x[ 2], x[ 7]); + word3_muladd_2(&w2, &w1, &w0, x[ 3], x[ 6]); + word3_muladd_2(&w2, &w1, &w0, x[ 4], x[ 5]); + z[ 9] = w0; w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[ 0], x[10]); + word3_muladd_2(&w0, &w2, &w1, x[ 1], x[ 9]); + word3_muladd_2(&w0, &w2, &w1, x[ 2], x[ 8]); + word3_muladd_2(&w0, &w2, &w1, x[ 3], x[ 7]); + word3_muladd_2(&w0, &w2, &w1, x[ 4], x[ 6]); + word3_muladd (&w0, &w2, &w1, x[ 5], x[ 5]); + z[10] = w1; w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[ 0], x[11]); + word3_muladd_2(&w1, &w0, &w2, x[ 1], x[10]); + word3_muladd_2(&w1, &w0, &w2, x[ 2], x[ 9]); + word3_muladd_2(&w1, &w0, &w2, x[ 3], x[ 8]); + word3_muladd_2(&w1, &w0, &w2, x[ 4], x[ 7]); + word3_muladd_2(&w1, &w0, &w2, x[ 5], x[ 6]); + z[11] = w2; w2 = 0; + + word3_muladd_2(&w2, &w1, &w0, x[ 0], x[12]); + word3_muladd_2(&w2, &w1, &w0, x[ 1], x[11]); + word3_muladd_2(&w2, &w1, &w0, x[ 2], x[10]); + word3_muladd_2(&w2, &w1, &w0, x[ 3], x[ 9]); + word3_muladd_2(&w2, &w1, &w0, x[ 4], x[ 8]); + word3_muladd_2(&w2, &w1, &w0, x[ 5], x[ 7]); + word3_muladd (&w2, &w1, &w0, x[ 6], x[ 6]); + z[12] = w0; w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[ 0], x[13]); + word3_muladd_2(&w0, &w2, &w1, x[ 1], x[12]); + word3_muladd_2(&w0, &w2, &w1, x[ 2], x[11]); + word3_muladd_2(&w0, &w2, &w1, x[ 3], x[10]); + word3_muladd_2(&w0, &w2, &w1, x[ 4], x[ 9]); + word3_muladd_2(&w0, &w2, &w1, x[ 5], x[ 8]); + word3_muladd_2(&w0, &w2, &w1, x[ 6], x[ 7]); + z[13] = w1; w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[ 0], x[14]); + word3_muladd_2(&w1, &w0, &w2, x[ 1], x[13]); + word3_muladd_2(&w1, &w0, &w2, x[ 2], x[12]); + word3_muladd_2(&w1, &w0, &w2, x[ 3], x[11]); + word3_muladd_2(&w1, &w0, &w2, x[ 4], x[10]); + word3_muladd_2(&w1, &w0, &w2, x[ 5], x[ 9]); + word3_muladd_2(&w1, &w0, &w2, x[ 6], x[ 8]); + word3_muladd (&w1, &w0, &w2, x[ 7], x[ 7]); + z[14] = w2; w2 = 0; + + word3_muladd_2(&w2, &w1, &w0, x[ 0], x[15]); + word3_muladd_2(&w2, &w1, &w0, x[ 1], x[14]); + word3_muladd_2(&w2, &w1, &w0, x[ 2], x[13]); + word3_muladd_2(&w2, &w1, &w0, x[ 3], x[12]); + word3_muladd_2(&w2, &w1, &w0, x[ 4], x[11]); + word3_muladd_2(&w2, &w1, &w0, x[ 5], x[10]); + word3_muladd_2(&w2, &w1, &w0, x[ 6], x[ 9]); + word3_muladd_2(&w2, &w1, &w0, x[ 7], x[ 8]); + z[15] = w0; w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[ 0], x[16]); + word3_muladd_2(&w0, &w2, &w1, x[ 1], x[15]); + word3_muladd_2(&w0, &w2, &w1, x[ 2], x[14]); + word3_muladd_2(&w0, &w2, &w1, x[ 3], x[13]); + word3_muladd_2(&w0, &w2, &w1, x[ 4], x[12]); + word3_muladd_2(&w0, &w2, &w1, x[ 5], x[11]); + word3_muladd_2(&w0, &w2, &w1, x[ 6], x[10]); + word3_muladd_2(&w0, &w2, &w1, x[ 7], x[ 9]); + word3_muladd (&w0, &w2, &w1, x[ 8], x[ 8]); + z[16] = w1; w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[ 0], x[17]); + word3_muladd_2(&w1, &w0, &w2, x[ 1], x[16]); + word3_muladd_2(&w1, &w0, &w2, x[ 2], x[15]); + word3_muladd_2(&w1, &w0, &w2, x[ 3], x[14]); + word3_muladd_2(&w1, &w0, &w2, x[ 4], x[13]); + word3_muladd_2(&w1, &w0, &w2, x[ 5], x[12]); + word3_muladd_2(&w1, &w0, &w2, x[ 6], x[11]); + word3_muladd_2(&w1, &w0, &w2, x[ 7], x[10]); + word3_muladd_2(&w1, &w0, &w2, x[ 8], x[ 9]); + z[17] = w2; w2 = 0; + + word3_muladd_2(&w2, &w1, &w0, x[ 0], x[18]); + word3_muladd_2(&w2, &w1, &w0, x[ 1], x[17]); + word3_muladd_2(&w2, &w1, &w0, x[ 2], x[16]); + word3_muladd_2(&w2, &w1, &w0, x[ 3], x[15]); + word3_muladd_2(&w2, &w1, &w0, x[ 4], x[14]); + word3_muladd_2(&w2, &w1, &w0, x[ 5], x[13]); + word3_muladd_2(&w2, &w1, &w0, x[ 6], x[12]); + word3_muladd_2(&w2, &w1, &w0, x[ 7], x[11]); + word3_muladd_2(&w2, &w1, &w0, x[ 8], x[10]); + word3_muladd (&w2, &w1, &w0, x[ 9], x[ 9]); + z[18] = w0; w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[ 0], x[19]); + word3_muladd_2(&w0, &w2, &w1, x[ 1], x[18]); + word3_muladd_2(&w0, &w2, &w1, x[ 2], x[17]); + word3_muladd_2(&w0, &w2, &w1, x[ 3], x[16]); + word3_muladd_2(&w0, &w2, &w1, x[ 4], x[15]); + word3_muladd_2(&w0, &w2, &w1, x[ 5], x[14]); + word3_muladd_2(&w0, &w2, &w1, x[ 6], x[13]); + word3_muladd_2(&w0, &w2, &w1, x[ 7], x[12]); + word3_muladd_2(&w0, &w2, &w1, x[ 8], x[11]); + word3_muladd_2(&w0, &w2, &w1, x[ 9], x[10]); + z[19] = w1; w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[ 0], x[20]); + word3_muladd_2(&w1, &w0, &w2, x[ 1], x[19]); + word3_muladd_2(&w1, &w0, &w2, x[ 2], x[18]); + word3_muladd_2(&w1, &w0, &w2, x[ 3], x[17]); + word3_muladd_2(&w1, &w0, &w2, x[ 4], x[16]); + word3_muladd_2(&w1, &w0, &w2, x[ 5], x[15]); + word3_muladd_2(&w1, &w0, &w2, x[ 6], x[14]); + word3_muladd_2(&w1, &w0, &w2, x[ 7], x[13]); + word3_muladd_2(&w1, &w0, &w2, x[ 8], x[12]); + word3_muladd_2(&w1, &w0, &w2, x[ 9], x[11]); + word3_muladd (&w1, &w0, &w2, x[10], x[10]); + z[20] = w2; w2 = 0; + + word3_muladd_2(&w2, &w1, &w0, x[ 0], x[21]); + word3_muladd_2(&w2, &w1, &w0, x[ 1], x[20]); + word3_muladd_2(&w2, &w1, &w0, x[ 2], x[19]); + word3_muladd_2(&w2, &w1, &w0, x[ 3], x[18]); + word3_muladd_2(&w2, &w1, &w0, x[ 4], x[17]); + word3_muladd_2(&w2, &w1, &w0, x[ 5], x[16]); + word3_muladd_2(&w2, &w1, &w0, x[ 6], x[15]); + word3_muladd_2(&w2, &w1, &w0, x[ 7], x[14]); + word3_muladd_2(&w2, &w1, &w0, x[ 8], x[13]); + word3_muladd_2(&w2, &w1, &w0, x[ 9], x[12]); + word3_muladd_2(&w2, &w1, &w0, x[10], x[11]); + z[21] = w0; w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[ 0], x[22]); + word3_muladd_2(&w0, &w2, &w1, x[ 1], x[21]); + word3_muladd_2(&w0, &w2, &w1, x[ 2], x[20]); + word3_muladd_2(&w0, &w2, &w1, x[ 3], x[19]); + word3_muladd_2(&w0, &w2, &w1, x[ 4], x[18]); + word3_muladd_2(&w0, &w2, &w1, x[ 5], x[17]); + word3_muladd_2(&w0, &w2, &w1, x[ 6], x[16]); + word3_muladd_2(&w0, &w2, &w1, x[ 7], x[15]); + word3_muladd_2(&w0, &w2, &w1, x[ 8], x[14]); + word3_muladd_2(&w0, &w2, &w1, x[ 9], x[13]); + word3_muladd_2(&w0, &w2, &w1, x[10], x[12]); + word3_muladd (&w0, &w2, &w1, x[11], x[11]); + z[22] = w1; w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[ 0], x[23]); + word3_muladd_2(&w1, &w0, &w2, x[ 1], x[22]); + word3_muladd_2(&w1, &w0, &w2, x[ 2], x[21]); + word3_muladd_2(&w1, &w0, &w2, x[ 3], x[20]); + word3_muladd_2(&w1, &w0, &w2, x[ 4], x[19]); + word3_muladd_2(&w1, &w0, &w2, x[ 5], x[18]); + word3_muladd_2(&w1, &w0, &w2, x[ 6], x[17]); + word3_muladd_2(&w1, &w0, &w2, x[ 7], x[16]); + word3_muladd_2(&w1, &w0, &w2, x[ 8], x[15]); + word3_muladd_2(&w1, &w0, &w2, x[ 9], x[14]); + word3_muladd_2(&w1, &w0, &w2, x[10], x[13]); + word3_muladd_2(&w1, &w0, &w2, x[11], x[12]); + z[23] = w2; w2 = 0; + + word3_muladd_2(&w2, &w1, &w0, x[ 1], x[23]); + word3_muladd_2(&w2, &w1, &w0, x[ 2], x[22]); + word3_muladd_2(&w2, &w1, &w0, x[ 3], x[21]); + word3_muladd_2(&w2, &w1, &w0, x[ 4], x[20]); + word3_muladd_2(&w2, &w1, &w0, x[ 5], x[19]); + word3_muladd_2(&w2, &w1, &w0, x[ 6], x[18]); + word3_muladd_2(&w2, &w1, &w0, x[ 7], x[17]); + word3_muladd_2(&w2, &w1, &w0, x[ 8], x[16]); + word3_muladd_2(&w2, &w1, &w0, x[ 9], x[15]); + word3_muladd_2(&w2, &w1, &w0, x[10], x[14]); + word3_muladd_2(&w2, &w1, &w0, x[11], x[13]); + word3_muladd (&w2, &w1, &w0, x[12], x[12]); + z[24] = w0; w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[ 2], x[23]); + word3_muladd_2(&w0, &w2, &w1, x[ 3], x[22]); + word3_muladd_2(&w0, &w2, &w1, x[ 4], x[21]); + word3_muladd_2(&w0, &w2, &w1, x[ 5], x[20]); + word3_muladd_2(&w0, &w2, &w1, x[ 6], x[19]); + word3_muladd_2(&w0, &w2, &w1, x[ 7], x[18]); + word3_muladd_2(&w0, &w2, &w1, x[ 8], x[17]); + word3_muladd_2(&w0, &w2, &w1, x[ 9], x[16]); + word3_muladd_2(&w0, &w2, &w1, x[10], x[15]); + word3_muladd_2(&w0, &w2, &w1, x[11], x[14]); + word3_muladd_2(&w0, &w2, &w1, x[12], x[13]); + z[25] = w1; w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[ 3], x[23]); + word3_muladd_2(&w1, &w0, &w2, x[ 4], x[22]); + word3_muladd_2(&w1, &w0, &w2, x[ 5], x[21]); + word3_muladd_2(&w1, &w0, &w2, x[ 6], x[20]); + word3_muladd_2(&w1, &w0, &w2, x[ 7], x[19]); + word3_muladd_2(&w1, &w0, &w2, x[ 8], x[18]); + word3_muladd_2(&w1, &w0, &w2, x[ 9], x[17]); + word3_muladd_2(&w1, &w0, &w2, x[10], x[16]); + word3_muladd_2(&w1, &w0, &w2, x[11], x[15]); + word3_muladd_2(&w1, &w0, &w2, x[12], x[14]); + word3_muladd (&w1, &w0, &w2, x[13], x[13]); + z[26] = w2; w2 = 0; + + word3_muladd_2(&w2, &w1, &w0, x[ 4], x[23]); + word3_muladd_2(&w2, &w1, &w0, x[ 5], x[22]); + word3_muladd_2(&w2, &w1, &w0, x[ 6], x[21]); + word3_muladd_2(&w2, &w1, &w0, x[ 7], x[20]); + word3_muladd_2(&w2, &w1, &w0, x[ 8], x[19]); + word3_muladd_2(&w2, &w1, &w0, x[ 9], x[18]); + word3_muladd_2(&w2, &w1, &w0, x[10], x[17]); + word3_muladd_2(&w2, &w1, &w0, x[11], x[16]); + word3_muladd_2(&w2, &w1, &w0, x[12], x[15]); + word3_muladd_2(&w2, &w1, &w0, x[13], x[14]); + z[27] = w0; w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[ 5], x[23]); + word3_muladd_2(&w0, &w2, &w1, x[ 6], x[22]); + word3_muladd_2(&w0, &w2, &w1, x[ 7], x[21]); + word3_muladd_2(&w0, &w2, &w1, x[ 8], x[20]); + word3_muladd_2(&w0, &w2, &w1, x[ 9], x[19]); + word3_muladd_2(&w0, &w2, &w1, x[10], x[18]); + word3_muladd_2(&w0, &w2, &w1, x[11], x[17]); + word3_muladd_2(&w0, &w2, &w1, x[12], x[16]); + word3_muladd_2(&w0, &w2, &w1, x[13], x[15]); + word3_muladd (&w0, &w2, &w1, x[14], x[14]); + z[28] = w1; w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[ 6], x[23]); + word3_muladd_2(&w1, &w0, &w2, x[ 7], x[22]); + word3_muladd_2(&w1, &w0, &w2, x[ 8], x[21]); + word3_muladd_2(&w1, &w0, &w2, x[ 9], x[20]); + word3_muladd_2(&w1, &w0, &w2, x[10], x[19]); + word3_muladd_2(&w1, &w0, &w2, x[11], x[18]); + word3_muladd_2(&w1, &w0, &w2, x[12], x[17]); + word3_muladd_2(&w1, &w0, &w2, x[13], x[16]); + word3_muladd_2(&w1, &w0, &w2, x[14], x[15]); + z[29] = w2; w2 = 0; + + word3_muladd_2(&w2, &w1, &w0, x[ 7], x[23]); + word3_muladd_2(&w2, &w1, &w0, x[ 8], x[22]); + word3_muladd_2(&w2, &w1, &w0, x[ 9], x[21]); + word3_muladd_2(&w2, &w1, &w0, x[10], x[20]); + word3_muladd_2(&w2, &w1, &w0, x[11], x[19]); + word3_muladd_2(&w2, &w1, &w0, x[12], x[18]); + word3_muladd_2(&w2, &w1, &w0, x[13], x[17]); + word3_muladd_2(&w2, &w1, &w0, x[14], x[16]); + word3_muladd (&w2, &w1, &w0, x[15], x[15]); + z[30] = w0; w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[ 8], x[23]); + word3_muladd_2(&w0, &w2, &w1, x[ 9], x[22]); + word3_muladd_2(&w0, &w2, &w1, x[10], x[21]); + word3_muladd_2(&w0, &w2, &w1, x[11], x[20]); + word3_muladd_2(&w0, &w2, &w1, x[12], x[19]); + word3_muladd_2(&w0, &w2, &w1, x[13], x[18]); + word3_muladd_2(&w0, &w2, &w1, x[14], x[17]); + word3_muladd_2(&w0, &w2, &w1, x[15], x[16]); + z[31] = w1; w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[ 9], x[23]); + word3_muladd_2(&w1, &w0, &w2, x[10], x[22]); + word3_muladd_2(&w1, &w0, &w2, x[11], x[21]); + word3_muladd_2(&w1, &w0, &w2, x[12], x[20]); + word3_muladd_2(&w1, &w0, &w2, x[13], x[19]); + word3_muladd_2(&w1, &w0, &w2, x[14], x[18]); + word3_muladd_2(&w1, &w0, &w2, x[15], x[17]); + word3_muladd (&w1, &w0, &w2, x[16], x[16]); + z[32] = w2; w2 = 0; + + word3_muladd_2(&w2, &w1, &w0, x[10], x[23]); + word3_muladd_2(&w2, &w1, &w0, x[11], x[22]); + word3_muladd_2(&w2, &w1, &w0, x[12], x[21]); + word3_muladd_2(&w2, &w1, &w0, x[13], x[20]); + word3_muladd_2(&w2, &w1, &w0, x[14], x[19]); + word3_muladd_2(&w2, &w1, &w0, x[15], x[18]); + word3_muladd_2(&w2, &w1, &w0, x[16], x[17]); + z[33] = w0; w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[11], x[23]); + word3_muladd_2(&w0, &w2, &w1, x[12], x[22]); + word3_muladd_2(&w0, &w2, &w1, x[13], x[21]); + word3_muladd_2(&w0, &w2, &w1, x[14], x[20]); + word3_muladd_2(&w0, &w2, &w1, x[15], x[19]); + word3_muladd_2(&w0, &w2, &w1, x[16], x[18]); + word3_muladd (&w0, &w2, &w1, x[17], x[17]); + z[34] = w1; w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[12], x[23]); + word3_muladd_2(&w1, &w0, &w2, x[13], x[22]); + word3_muladd_2(&w1, &w0, &w2, x[14], x[21]); + word3_muladd_2(&w1, &w0, &w2, x[15], x[20]); + word3_muladd_2(&w1, &w0, &w2, x[16], x[19]); + word3_muladd_2(&w1, &w0, &w2, x[17], x[18]); + z[35] = w2; w2 = 0; + + word3_muladd_2(&w2, &w1, &w0, x[13], x[23]); + word3_muladd_2(&w2, &w1, &w0, x[14], x[22]); + word3_muladd_2(&w2, &w1, &w0, x[15], x[21]); + word3_muladd_2(&w2, &w1, &w0, x[16], x[20]); + word3_muladd_2(&w2, &w1, &w0, x[17], x[19]); + word3_muladd (&w2, &w1, &w0, x[18], x[18]); + z[36] = w0; w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[14], x[23]); + word3_muladd_2(&w0, &w2, &w1, x[15], x[22]); + word3_muladd_2(&w0, &w2, &w1, x[16], x[21]); + word3_muladd_2(&w0, &w2, &w1, x[17], x[20]); + word3_muladd_2(&w0, &w2, &w1, x[18], x[19]); + z[37] = w1; w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[15], x[23]); + word3_muladd_2(&w1, &w0, &w2, x[16], x[22]); + word3_muladd_2(&w1, &w0, &w2, x[17], x[21]); + word3_muladd_2(&w1, &w0, &w2, x[18], x[20]); + word3_muladd (&w1, &w0, &w2, x[19], x[19]); + z[38] = w2; w2 = 0; + + word3_muladd_2(&w2, &w1, &w0, x[16], x[23]); + word3_muladd_2(&w2, &w1, &w0, x[17], x[22]); + word3_muladd_2(&w2, &w1, &w0, x[18], x[21]); + word3_muladd_2(&w2, &w1, &w0, x[19], x[20]); + z[39] = w0; w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[17], x[23]); + word3_muladd_2(&w0, &w2, &w1, x[18], x[22]); + word3_muladd_2(&w0, &w2, &w1, x[19], x[21]); + word3_muladd (&w0, &w2, &w1, x[20], x[20]); + z[40] = w1; w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[18], x[23]); + word3_muladd_2(&w1, &w0, &w2, x[19], x[22]); + word3_muladd_2(&w1, &w0, &w2, x[20], x[21]); + z[41] = w2; w2 = 0; + + word3_muladd_2(&w2, &w1, &w0, x[19], x[23]); + word3_muladd_2(&w2, &w1, &w0, x[20], x[22]); + word3_muladd (&w2, &w1, &w0, x[21], x[21]); + z[42] = w0; w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[20], x[23]); + word3_muladd_2(&w0, &w2, &w1, x[21], x[22]); + z[43] = w1; w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[21], x[23]); + word3_muladd (&w1, &w0, &w2, x[22], x[22]); + z[44] = w2; w2 = 0; + + word3_muladd_2(&w2, &w1, &w0, x[22], x[23]); + z[45] = w0; w0 = 0; + + word3_muladd (&w0, &w2, &w1, x[23], x[23]); + z[46] = w1; + z[47] = w2; + } + +/* +* Comba 24x24 Multiplication +*/ +void bigint_comba_mul24(word z[48], const word x[24], const word y[24]) + { + word w2 = 0, w1 = 0, w0 = 0; + + word3_muladd(&w2, &w1, &w0, x[ 0], y[ 0]); + z[ 0] = w0; w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[ 0], y[ 1]); + word3_muladd(&w0, &w2, &w1, x[ 1], y[ 0]); + z[ 1] = w1; w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[ 0], y[ 2]); + word3_muladd(&w1, &w0, &w2, x[ 1], y[ 1]); + word3_muladd(&w1, &w0, &w2, x[ 2], y[ 0]); + z[ 2] = w2; w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[ 0], y[ 3]); + word3_muladd(&w2, &w1, &w0, x[ 1], y[ 2]); + word3_muladd(&w2, &w1, &w0, x[ 2], y[ 1]); + word3_muladd(&w2, &w1, &w0, x[ 3], y[ 0]); + z[ 3] = w0; w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[ 0], y[ 4]); + word3_muladd(&w0, &w2, &w1, x[ 1], y[ 3]); + word3_muladd(&w0, &w2, &w1, x[ 2], y[ 2]); + word3_muladd(&w0, &w2, &w1, x[ 3], y[ 1]); + word3_muladd(&w0, &w2, &w1, x[ 4], y[ 0]); + z[ 4] = w1; w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[ 0], y[ 5]); + word3_muladd(&w1, &w0, &w2, x[ 1], y[ 4]); + word3_muladd(&w1, &w0, &w2, x[ 2], y[ 3]); + word3_muladd(&w1, &w0, &w2, x[ 3], y[ 2]); + word3_muladd(&w1, &w0, &w2, x[ 4], y[ 1]); + word3_muladd(&w1, &w0, &w2, x[ 5], y[ 0]); + z[ 5] = w2; w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[ 0], y[ 6]); + word3_muladd(&w2, &w1, &w0, x[ 1], y[ 5]); + word3_muladd(&w2, &w1, &w0, x[ 2], y[ 4]); + word3_muladd(&w2, &w1, &w0, x[ 3], y[ 3]); + word3_muladd(&w2, &w1, &w0, x[ 4], y[ 2]); + word3_muladd(&w2, &w1, &w0, x[ 5], y[ 1]); + word3_muladd(&w2, &w1, &w0, x[ 6], y[ 0]); + z[ 6] = w0; w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[ 0], y[ 7]); + word3_muladd(&w0, &w2, &w1, x[ 1], y[ 6]); + word3_muladd(&w0, &w2, &w1, x[ 2], y[ 5]); + word3_muladd(&w0, &w2, &w1, x[ 3], y[ 4]); + word3_muladd(&w0, &w2, &w1, x[ 4], y[ 3]); + word3_muladd(&w0, &w2, &w1, x[ 5], y[ 2]); + word3_muladd(&w0, &w2, &w1, x[ 6], y[ 1]); + word3_muladd(&w0, &w2, &w1, x[ 7], y[ 0]); + z[ 7] = w1; w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[ 0], y[ 8]); + word3_muladd(&w1, &w0, &w2, x[ 1], y[ 7]); + word3_muladd(&w1, &w0, &w2, x[ 2], y[ 6]); + word3_muladd(&w1, &w0, &w2, x[ 3], y[ 5]); + word3_muladd(&w1, &w0, &w2, x[ 4], y[ 4]); + word3_muladd(&w1, &w0, &w2, x[ 5], y[ 3]); + word3_muladd(&w1, &w0, &w2, x[ 6], y[ 2]); + word3_muladd(&w1, &w0, &w2, x[ 7], y[ 1]); + word3_muladd(&w1, &w0, &w2, x[ 8], y[ 0]); + z[ 8] = w2; w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[ 0], y[ 9]); + word3_muladd(&w2, &w1, &w0, x[ 1], y[ 8]); + word3_muladd(&w2, &w1, &w0, x[ 2], y[ 7]); + word3_muladd(&w2, &w1, &w0, x[ 3], y[ 6]); + word3_muladd(&w2, &w1, &w0, x[ 4], y[ 5]); + word3_muladd(&w2, &w1, &w0, x[ 5], y[ 4]); + word3_muladd(&w2, &w1, &w0, x[ 6], y[ 3]); + word3_muladd(&w2, &w1, &w0, x[ 7], y[ 2]); + word3_muladd(&w2, &w1, &w0, x[ 8], y[ 1]); + word3_muladd(&w2, &w1, &w0, x[ 9], y[ 0]); + z[ 9] = w0; w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[ 0], y[10]); + word3_muladd(&w0, &w2, &w1, x[ 1], y[ 9]); + word3_muladd(&w0, &w2, &w1, x[ 2], y[ 8]); + word3_muladd(&w0, &w2, &w1, x[ 3], y[ 7]); + word3_muladd(&w0, &w2, &w1, x[ 4], y[ 6]); + word3_muladd(&w0, &w2, &w1, x[ 5], y[ 5]); + word3_muladd(&w0, &w2, &w1, x[ 6], y[ 4]); + word3_muladd(&w0, &w2, &w1, x[ 7], y[ 3]); + word3_muladd(&w0, &w2, &w1, x[ 8], y[ 2]); + word3_muladd(&w0, &w2, &w1, x[ 9], y[ 1]); + word3_muladd(&w0, &w2, &w1, x[10], y[ 0]); + z[10] = w1; w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[ 0], y[11]); + word3_muladd(&w1, &w0, &w2, x[ 1], y[10]); + word3_muladd(&w1, &w0, &w2, x[ 2], y[ 9]); + word3_muladd(&w1, &w0, &w2, x[ 3], y[ 8]); + word3_muladd(&w1, &w0, &w2, x[ 4], y[ 7]); + word3_muladd(&w1, &w0, &w2, x[ 5], y[ 6]); + word3_muladd(&w1, &w0, &w2, x[ 6], y[ 5]); + word3_muladd(&w1, &w0, &w2, x[ 7], y[ 4]); + word3_muladd(&w1, &w0, &w2, x[ 8], y[ 3]); + word3_muladd(&w1, &w0, &w2, x[ 9], y[ 2]); + word3_muladd(&w1, &w0, &w2, x[10], y[ 1]); + word3_muladd(&w1, &w0, &w2, x[11], y[ 0]); + z[11] = w2; w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[ 0], y[12]); + word3_muladd(&w2, &w1, &w0, x[ 1], y[11]); + word3_muladd(&w2, &w1, &w0, x[ 2], y[10]); + word3_muladd(&w2, &w1, &w0, x[ 3], y[ 9]); + word3_muladd(&w2, &w1, &w0, x[ 4], y[ 8]); + word3_muladd(&w2, &w1, &w0, x[ 5], y[ 7]); + word3_muladd(&w2, &w1, &w0, x[ 6], y[ 6]); + word3_muladd(&w2, &w1, &w0, x[ 7], y[ 5]); + word3_muladd(&w2, &w1, &w0, x[ 8], y[ 4]); + word3_muladd(&w2, &w1, &w0, x[ 9], y[ 3]); + word3_muladd(&w2, &w1, &w0, x[10], y[ 2]); + word3_muladd(&w2, &w1, &w0, x[11], y[ 1]); + word3_muladd(&w2, &w1, &w0, x[12], y[ 0]); + z[12] = w0; w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[ 0], y[13]); + word3_muladd(&w0, &w2, &w1, x[ 1], y[12]); + word3_muladd(&w0, &w2, &w1, x[ 2], y[11]); + word3_muladd(&w0, &w2, &w1, x[ 3], y[10]); + word3_muladd(&w0, &w2, &w1, x[ 4], y[ 9]); + word3_muladd(&w0, &w2, &w1, x[ 5], y[ 8]); + word3_muladd(&w0, &w2, &w1, x[ 6], y[ 7]); + word3_muladd(&w0, &w2, &w1, x[ 7], y[ 6]); + word3_muladd(&w0, &w2, &w1, x[ 8], y[ 5]); + word3_muladd(&w0, &w2, &w1, x[ 9], y[ 4]); + word3_muladd(&w0, &w2, &w1, x[10], y[ 3]); + word3_muladd(&w0, &w2, &w1, x[11], y[ 2]); + word3_muladd(&w0, &w2, &w1, x[12], y[ 1]); + word3_muladd(&w0, &w2, &w1, x[13], y[ 0]); + z[13] = w1; w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[ 0], y[14]); + word3_muladd(&w1, &w0, &w2, x[ 1], y[13]); + word3_muladd(&w1, &w0, &w2, x[ 2], y[12]); + word3_muladd(&w1, &w0, &w2, x[ 3], y[11]); + word3_muladd(&w1, &w0, &w2, x[ 4], y[10]); + word3_muladd(&w1, &w0, &w2, x[ 5], y[ 9]); + word3_muladd(&w1, &w0, &w2, x[ 6], y[ 8]); + word3_muladd(&w1, &w0, &w2, x[ 7], y[ 7]); + word3_muladd(&w1, &w0, &w2, x[ 8], y[ 6]); + word3_muladd(&w1, &w0, &w2, x[ 9], y[ 5]); + word3_muladd(&w1, &w0, &w2, x[10], y[ 4]); + word3_muladd(&w1, &w0, &w2, x[11], y[ 3]); + word3_muladd(&w1, &w0, &w2, x[12], y[ 2]); + word3_muladd(&w1, &w0, &w2, x[13], y[ 1]); + word3_muladd(&w1, &w0, &w2, x[14], y[ 0]); + z[14] = w2; w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[ 0], y[15]); + word3_muladd(&w2, &w1, &w0, x[ 1], y[14]); + word3_muladd(&w2, &w1, &w0, x[ 2], y[13]); + word3_muladd(&w2, &w1, &w0, x[ 3], y[12]); + word3_muladd(&w2, &w1, &w0, x[ 4], y[11]); + word3_muladd(&w2, &w1, &w0, x[ 5], y[10]); + word3_muladd(&w2, &w1, &w0, x[ 6], y[ 9]); + word3_muladd(&w2, &w1, &w0, x[ 7], y[ 8]); + word3_muladd(&w2, &w1, &w0, x[ 8], y[ 7]); + word3_muladd(&w2, &w1, &w0, x[ 9], y[ 6]); + word3_muladd(&w2, &w1, &w0, x[10], y[ 5]); + word3_muladd(&w2, &w1, &w0, x[11], y[ 4]); + word3_muladd(&w2, &w1, &w0, x[12], y[ 3]); + word3_muladd(&w2, &w1, &w0, x[13], y[ 2]); + word3_muladd(&w2, &w1, &w0, x[14], y[ 1]); + word3_muladd(&w2, &w1, &w0, x[15], y[ 0]); + z[15] = w0; w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[ 0], y[16]); + word3_muladd(&w0, &w2, &w1, x[ 1], y[15]); + word3_muladd(&w0, &w2, &w1, x[ 2], y[14]); + word3_muladd(&w0, &w2, &w1, x[ 3], y[13]); + word3_muladd(&w0, &w2, &w1, x[ 4], y[12]); + word3_muladd(&w0, &w2, &w1, x[ 5], y[11]); + word3_muladd(&w0, &w2, &w1, x[ 6], y[10]); + word3_muladd(&w0, &w2, &w1, x[ 7], y[ 9]); + word3_muladd(&w0, &w2, &w1, x[ 8], y[ 8]); + word3_muladd(&w0, &w2, &w1, x[ 9], y[ 7]); + word3_muladd(&w0, &w2, &w1, x[10], y[ 6]); + word3_muladd(&w0, &w2, &w1, x[11], y[ 5]); + word3_muladd(&w0, &w2, &w1, x[12], y[ 4]); + word3_muladd(&w0, &w2, &w1, x[13], y[ 3]); + word3_muladd(&w0, &w2, &w1, x[14], y[ 2]); + word3_muladd(&w0, &w2, &w1, x[15], y[ 1]); + word3_muladd(&w0, &w2, &w1, x[16], y[ 0]); + z[16] = w1; w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[ 0], y[17]); + word3_muladd(&w1, &w0, &w2, x[ 1], y[16]); + word3_muladd(&w1, &w0, &w2, x[ 2], y[15]); + word3_muladd(&w1, &w0, &w2, x[ 3], y[14]); + word3_muladd(&w1, &w0, &w2, x[ 4], y[13]); + word3_muladd(&w1, &w0, &w2, x[ 5], y[12]); + word3_muladd(&w1, &w0, &w2, x[ 6], y[11]); + word3_muladd(&w1, &w0, &w2, x[ 7], y[10]); + word3_muladd(&w1, &w0, &w2, x[ 8], y[ 9]); + word3_muladd(&w1, &w0, &w2, x[ 9], y[ 8]); + word3_muladd(&w1, &w0, &w2, x[10], y[ 7]); + word3_muladd(&w1, &w0, &w2, x[11], y[ 6]); + word3_muladd(&w1, &w0, &w2, x[12], y[ 5]); + word3_muladd(&w1, &w0, &w2, x[13], y[ 4]); + word3_muladd(&w1, &w0, &w2, x[14], y[ 3]); + word3_muladd(&w1, &w0, &w2, x[15], y[ 2]); + word3_muladd(&w1, &w0, &w2, x[16], y[ 1]); + word3_muladd(&w1, &w0, &w2, x[17], y[ 0]); + z[17] = w2; w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[ 0], y[18]); + word3_muladd(&w2, &w1, &w0, x[ 1], y[17]); + word3_muladd(&w2, &w1, &w0, x[ 2], y[16]); + word3_muladd(&w2, &w1, &w0, x[ 3], y[15]); + word3_muladd(&w2, &w1, &w0, x[ 4], y[14]); + word3_muladd(&w2, &w1, &w0, x[ 5], y[13]); + word3_muladd(&w2, &w1, &w0, x[ 6], y[12]); + word3_muladd(&w2, &w1, &w0, x[ 7], y[11]); + word3_muladd(&w2, &w1, &w0, x[ 8], y[10]); + word3_muladd(&w2, &w1, &w0, x[ 9], y[ 9]); + word3_muladd(&w2, &w1, &w0, x[10], y[ 8]); + word3_muladd(&w2, &w1, &w0, x[11], y[ 7]); + word3_muladd(&w2, &w1, &w0, x[12], y[ 6]); + word3_muladd(&w2, &w1, &w0, x[13], y[ 5]); + word3_muladd(&w2, &w1, &w0, x[14], y[ 4]); + word3_muladd(&w2, &w1, &w0, x[15], y[ 3]); + word3_muladd(&w2, &w1, &w0, x[16], y[ 2]); + word3_muladd(&w2, &w1, &w0, x[17], y[ 1]); + word3_muladd(&w2, &w1, &w0, x[18], y[ 0]); + z[18] = w0; w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[ 0], y[19]); + word3_muladd(&w0, &w2, &w1, x[ 1], y[18]); + word3_muladd(&w0, &w2, &w1, x[ 2], y[17]); + word3_muladd(&w0, &w2, &w1, x[ 3], y[16]); + word3_muladd(&w0, &w2, &w1, x[ 4], y[15]); + word3_muladd(&w0, &w2, &w1, x[ 5], y[14]); + word3_muladd(&w0, &w2, &w1, x[ 6], y[13]); + word3_muladd(&w0, &w2, &w1, x[ 7], y[12]); + word3_muladd(&w0, &w2, &w1, x[ 8], y[11]); + word3_muladd(&w0, &w2, &w1, x[ 9], y[10]); + word3_muladd(&w0, &w2, &w1, x[10], y[ 9]); + word3_muladd(&w0, &w2, &w1, x[11], y[ 8]); + word3_muladd(&w0, &w2, &w1, x[12], y[ 7]); + word3_muladd(&w0, &w2, &w1, x[13], y[ 6]); + word3_muladd(&w0, &w2, &w1, x[14], y[ 5]); + word3_muladd(&w0, &w2, &w1, x[15], y[ 4]); + word3_muladd(&w0, &w2, &w1, x[16], y[ 3]); + word3_muladd(&w0, &w2, &w1, x[17], y[ 2]); + word3_muladd(&w0, &w2, &w1, x[18], y[ 1]); + word3_muladd(&w0, &w2, &w1, x[19], y[ 0]); + z[19] = w1; w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[ 0], y[20]); + word3_muladd(&w1, &w0, &w2, x[ 1], y[19]); + word3_muladd(&w1, &w0, &w2, x[ 2], y[18]); + word3_muladd(&w1, &w0, &w2, x[ 3], y[17]); + word3_muladd(&w1, &w0, &w2, x[ 4], y[16]); + word3_muladd(&w1, &w0, &w2, x[ 5], y[15]); + word3_muladd(&w1, &w0, &w2, x[ 6], y[14]); + word3_muladd(&w1, &w0, &w2, x[ 7], y[13]); + word3_muladd(&w1, &w0, &w2, x[ 8], y[12]); + word3_muladd(&w1, &w0, &w2, x[ 9], y[11]); + word3_muladd(&w1, &w0, &w2, x[10], y[10]); + word3_muladd(&w1, &w0, &w2, x[11], y[ 9]); + word3_muladd(&w1, &w0, &w2, x[12], y[ 8]); + word3_muladd(&w1, &w0, &w2, x[13], y[ 7]); + word3_muladd(&w1, &w0, &w2, x[14], y[ 6]); + word3_muladd(&w1, &w0, &w2, x[15], y[ 5]); + word3_muladd(&w1, &w0, &w2, x[16], y[ 4]); + word3_muladd(&w1, &w0, &w2, x[17], y[ 3]); + word3_muladd(&w1, &w0, &w2, x[18], y[ 2]); + word3_muladd(&w1, &w0, &w2, x[19], y[ 1]); + word3_muladd(&w1, &w0, &w2, x[20], y[ 0]); + z[20] = w2; w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[ 0], y[21]); + word3_muladd(&w2, &w1, &w0, x[ 1], y[20]); + word3_muladd(&w2, &w1, &w0, x[ 2], y[19]); + word3_muladd(&w2, &w1, &w0, x[ 3], y[18]); + word3_muladd(&w2, &w1, &w0, x[ 4], y[17]); + word3_muladd(&w2, &w1, &w0, x[ 5], y[16]); + word3_muladd(&w2, &w1, &w0, x[ 6], y[15]); + word3_muladd(&w2, &w1, &w0, x[ 7], y[14]); + word3_muladd(&w2, &w1, &w0, x[ 8], y[13]); + word3_muladd(&w2, &w1, &w0, x[ 9], y[12]); + word3_muladd(&w2, &w1, &w0, x[10], y[11]); + word3_muladd(&w2, &w1, &w0, x[11], y[10]); + word3_muladd(&w2, &w1, &w0, x[12], y[ 9]); + word3_muladd(&w2, &w1, &w0, x[13], y[ 8]); + word3_muladd(&w2, &w1, &w0, x[14], y[ 7]); + word3_muladd(&w2, &w1, &w0, x[15], y[ 6]); + word3_muladd(&w2, &w1, &w0, x[16], y[ 5]); + word3_muladd(&w2, &w1, &w0, x[17], y[ 4]); + word3_muladd(&w2, &w1, &w0, x[18], y[ 3]); + word3_muladd(&w2, &w1, &w0, x[19], y[ 2]); + word3_muladd(&w2, &w1, &w0, x[20], y[ 1]); + word3_muladd(&w2, &w1, &w0, x[21], y[ 0]); + z[21] = w0; w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[ 0], y[22]); + word3_muladd(&w0, &w2, &w1, x[ 1], y[21]); + word3_muladd(&w0, &w2, &w1, x[ 2], y[20]); + word3_muladd(&w0, &w2, &w1, x[ 3], y[19]); + word3_muladd(&w0, &w2, &w1, x[ 4], y[18]); + word3_muladd(&w0, &w2, &w1, x[ 5], y[17]); + word3_muladd(&w0, &w2, &w1, x[ 6], y[16]); + word3_muladd(&w0, &w2, &w1, x[ 7], y[15]); + word3_muladd(&w0, &w2, &w1, x[ 8], y[14]); + word3_muladd(&w0, &w2, &w1, x[ 9], y[13]); + word3_muladd(&w0, &w2, &w1, x[10], y[12]); + word3_muladd(&w0, &w2, &w1, x[11], y[11]); + word3_muladd(&w0, &w2, &w1, x[12], y[10]); + word3_muladd(&w0, &w2, &w1, x[13], y[ 9]); + word3_muladd(&w0, &w2, &w1, x[14], y[ 8]); + word3_muladd(&w0, &w2, &w1, x[15], y[ 7]); + word3_muladd(&w0, &w2, &w1, x[16], y[ 6]); + word3_muladd(&w0, &w2, &w1, x[17], y[ 5]); + word3_muladd(&w0, &w2, &w1, x[18], y[ 4]); + word3_muladd(&w0, &w2, &w1, x[19], y[ 3]); + word3_muladd(&w0, &w2, &w1, x[20], y[ 2]); + word3_muladd(&w0, &w2, &w1, x[21], y[ 1]); + word3_muladd(&w0, &w2, &w1, x[22], y[ 0]); + z[22] = w1; w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[ 0], y[23]); + word3_muladd(&w1, &w0, &w2, x[ 1], y[22]); + word3_muladd(&w1, &w0, &w2, x[ 2], y[21]); + word3_muladd(&w1, &w0, &w2, x[ 3], y[20]); + word3_muladd(&w1, &w0, &w2, x[ 4], y[19]); + word3_muladd(&w1, &w0, &w2, x[ 5], y[18]); + word3_muladd(&w1, &w0, &w2, x[ 6], y[17]); + word3_muladd(&w1, &w0, &w2, x[ 7], y[16]); + word3_muladd(&w1, &w0, &w2, x[ 8], y[15]); + word3_muladd(&w1, &w0, &w2, x[ 9], y[14]); + word3_muladd(&w1, &w0, &w2, x[10], y[13]); + word3_muladd(&w1, &w0, &w2, x[11], y[12]); + word3_muladd(&w1, &w0, &w2, x[12], y[11]); + word3_muladd(&w1, &w0, &w2, x[13], y[10]); + word3_muladd(&w1, &w0, &w2, x[14], y[ 9]); + word3_muladd(&w1, &w0, &w2, x[15], y[ 8]); + word3_muladd(&w1, &w0, &w2, x[16], y[ 7]); + word3_muladd(&w1, &w0, &w2, x[17], y[ 6]); + word3_muladd(&w1, &w0, &w2, x[18], y[ 5]); + word3_muladd(&w1, &w0, &w2, x[19], y[ 4]); + word3_muladd(&w1, &w0, &w2, x[20], y[ 3]); + word3_muladd(&w1, &w0, &w2, x[21], y[ 2]); + word3_muladd(&w1, &w0, &w2, x[22], y[ 1]); + word3_muladd(&w1, &w0, &w2, x[23], y[ 0]); + z[23] = w2; w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[ 1], y[23]); + word3_muladd(&w2, &w1, &w0, x[ 2], y[22]); + word3_muladd(&w2, &w1, &w0, x[ 3], y[21]); + word3_muladd(&w2, &w1, &w0, x[ 4], y[20]); + word3_muladd(&w2, &w1, &w0, x[ 5], y[19]); + word3_muladd(&w2, &w1, &w0, x[ 6], y[18]); + word3_muladd(&w2, &w1, &w0, x[ 7], y[17]); + word3_muladd(&w2, &w1, &w0, x[ 8], y[16]); + word3_muladd(&w2, &w1, &w0, x[ 9], y[15]); + word3_muladd(&w2, &w1, &w0, x[10], y[14]); + word3_muladd(&w2, &w1, &w0, x[11], y[13]); + word3_muladd(&w2, &w1, &w0, x[12], y[12]); + word3_muladd(&w2, &w1, &w0, x[13], y[11]); + word3_muladd(&w2, &w1, &w0, x[14], y[10]); + word3_muladd(&w2, &w1, &w0, x[15], y[ 9]); + word3_muladd(&w2, &w1, &w0, x[16], y[ 8]); + word3_muladd(&w2, &w1, &w0, x[17], y[ 7]); + word3_muladd(&w2, &w1, &w0, x[18], y[ 6]); + word3_muladd(&w2, &w1, &w0, x[19], y[ 5]); + word3_muladd(&w2, &w1, &w0, x[20], y[ 4]); + word3_muladd(&w2, &w1, &w0, x[21], y[ 3]); + word3_muladd(&w2, &w1, &w0, x[22], y[ 2]); + word3_muladd(&w2, &w1, &w0, x[23], y[ 1]); + z[24] = w0; w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[ 2], y[23]); + word3_muladd(&w0, &w2, &w1, x[ 3], y[22]); + word3_muladd(&w0, &w2, &w1, x[ 4], y[21]); + word3_muladd(&w0, &w2, &w1, x[ 5], y[20]); + word3_muladd(&w0, &w2, &w1, x[ 6], y[19]); + word3_muladd(&w0, &w2, &w1, x[ 7], y[18]); + word3_muladd(&w0, &w2, &w1, x[ 8], y[17]); + word3_muladd(&w0, &w2, &w1, x[ 9], y[16]); + word3_muladd(&w0, &w2, &w1, x[10], y[15]); + word3_muladd(&w0, &w2, &w1, x[11], y[14]); + word3_muladd(&w0, &w2, &w1, x[12], y[13]); + word3_muladd(&w0, &w2, &w1, x[13], y[12]); + word3_muladd(&w0, &w2, &w1, x[14], y[11]); + word3_muladd(&w0, &w2, &w1, x[15], y[10]); + word3_muladd(&w0, &w2, &w1, x[16], y[ 9]); + word3_muladd(&w0, &w2, &w1, x[17], y[ 8]); + word3_muladd(&w0, &w2, &w1, x[18], y[ 7]); + word3_muladd(&w0, &w2, &w1, x[19], y[ 6]); + word3_muladd(&w0, &w2, &w1, x[20], y[ 5]); + word3_muladd(&w0, &w2, &w1, x[21], y[ 4]); + word3_muladd(&w0, &w2, &w1, x[22], y[ 3]); + word3_muladd(&w0, &w2, &w1, x[23], y[ 2]); + z[25] = w1; w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[ 3], y[23]); + word3_muladd(&w1, &w0, &w2, x[ 4], y[22]); + word3_muladd(&w1, &w0, &w2, x[ 5], y[21]); + word3_muladd(&w1, &w0, &w2, x[ 6], y[20]); + word3_muladd(&w1, &w0, &w2, x[ 7], y[19]); + word3_muladd(&w1, &w0, &w2, x[ 8], y[18]); + word3_muladd(&w1, &w0, &w2, x[ 9], y[17]); + word3_muladd(&w1, &w0, &w2, x[10], y[16]); + word3_muladd(&w1, &w0, &w2, x[11], y[15]); + word3_muladd(&w1, &w0, &w2, x[12], y[14]); + word3_muladd(&w1, &w0, &w2, x[13], y[13]); + word3_muladd(&w1, &w0, &w2, x[14], y[12]); + word3_muladd(&w1, &w0, &w2, x[15], y[11]); + word3_muladd(&w1, &w0, &w2, x[16], y[10]); + word3_muladd(&w1, &w0, &w2, x[17], y[ 9]); + word3_muladd(&w1, &w0, &w2, x[18], y[ 8]); + word3_muladd(&w1, &w0, &w2, x[19], y[ 7]); + word3_muladd(&w1, &w0, &w2, x[20], y[ 6]); + word3_muladd(&w1, &w0, &w2, x[21], y[ 5]); + word3_muladd(&w1, &w0, &w2, x[22], y[ 4]); + word3_muladd(&w1, &w0, &w2, x[23], y[ 3]); + z[26] = w2; w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[ 4], y[23]); + word3_muladd(&w2, &w1, &w0, x[ 5], y[22]); + word3_muladd(&w2, &w1, &w0, x[ 6], y[21]); + word3_muladd(&w2, &w1, &w0, x[ 7], y[20]); + word3_muladd(&w2, &w1, &w0, x[ 8], y[19]); + word3_muladd(&w2, &w1, &w0, x[ 9], y[18]); + word3_muladd(&w2, &w1, &w0, x[10], y[17]); + word3_muladd(&w2, &w1, &w0, x[11], y[16]); + word3_muladd(&w2, &w1, &w0, x[12], y[15]); + word3_muladd(&w2, &w1, &w0, x[13], y[14]); + word3_muladd(&w2, &w1, &w0, x[14], y[13]); + word3_muladd(&w2, &w1, &w0, x[15], y[12]); + word3_muladd(&w2, &w1, &w0, x[16], y[11]); + word3_muladd(&w2, &w1, &w0, x[17], y[10]); + word3_muladd(&w2, &w1, &w0, x[18], y[ 9]); + word3_muladd(&w2, &w1, &w0, x[19], y[ 8]); + word3_muladd(&w2, &w1, &w0, x[20], y[ 7]); + word3_muladd(&w2, &w1, &w0, x[21], y[ 6]); + word3_muladd(&w2, &w1, &w0, x[22], y[ 5]); + word3_muladd(&w2, &w1, &w0, x[23], y[ 4]); + z[27] = w0; w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[ 5], y[23]); + word3_muladd(&w0, &w2, &w1, x[ 6], y[22]); + word3_muladd(&w0, &w2, &w1, x[ 7], y[21]); + word3_muladd(&w0, &w2, &w1, x[ 8], y[20]); + word3_muladd(&w0, &w2, &w1, x[ 9], y[19]); + word3_muladd(&w0, &w2, &w1, x[10], y[18]); + word3_muladd(&w0, &w2, &w1, x[11], y[17]); + word3_muladd(&w0, &w2, &w1, x[12], y[16]); + word3_muladd(&w0, &w2, &w1, x[13], y[15]); + word3_muladd(&w0, &w2, &w1, x[14], y[14]); + word3_muladd(&w0, &w2, &w1, x[15], y[13]); + word3_muladd(&w0, &w2, &w1, x[16], y[12]); + word3_muladd(&w0, &w2, &w1, x[17], y[11]); + word3_muladd(&w0, &w2, &w1, x[18], y[10]); + word3_muladd(&w0, &w2, &w1, x[19], y[ 9]); + word3_muladd(&w0, &w2, &w1, x[20], y[ 8]); + word3_muladd(&w0, &w2, &w1, x[21], y[ 7]); + word3_muladd(&w0, &w2, &w1, x[22], y[ 6]); + word3_muladd(&w0, &w2, &w1, x[23], y[ 5]); + z[28] = w1; w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[ 6], y[23]); + word3_muladd(&w1, &w0, &w2, x[ 7], y[22]); + word3_muladd(&w1, &w0, &w2, x[ 8], y[21]); + word3_muladd(&w1, &w0, &w2, x[ 9], y[20]); + word3_muladd(&w1, &w0, &w2, x[10], y[19]); + word3_muladd(&w1, &w0, &w2, x[11], y[18]); + word3_muladd(&w1, &w0, &w2, x[12], y[17]); + word3_muladd(&w1, &w0, &w2, x[13], y[16]); + word3_muladd(&w1, &w0, &w2, x[14], y[15]); + word3_muladd(&w1, &w0, &w2, x[15], y[14]); + word3_muladd(&w1, &w0, &w2, x[16], y[13]); + word3_muladd(&w1, &w0, &w2, x[17], y[12]); + word3_muladd(&w1, &w0, &w2, x[18], y[11]); + word3_muladd(&w1, &w0, &w2, x[19], y[10]); + word3_muladd(&w1, &w0, &w2, x[20], y[ 9]); + word3_muladd(&w1, &w0, &w2, x[21], y[ 8]); + word3_muladd(&w1, &w0, &w2, x[22], y[ 7]); + word3_muladd(&w1, &w0, &w2, x[23], y[ 6]); + z[29] = w2; w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[ 7], y[23]); + word3_muladd(&w2, &w1, &w0, x[ 8], y[22]); + word3_muladd(&w2, &w1, &w0, x[ 9], y[21]); + word3_muladd(&w2, &w1, &w0, x[10], y[20]); + word3_muladd(&w2, &w1, &w0, x[11], y[19]); + word3_muladd(&w2, &w1, &w0, x[12], y[18]); + word3_muladd(&w2, &w1, &w0, x[13], y[17]); + word3_muladd(&w2, &w1, &w0, x[14], y[16]); + word3_muladd(&w2, &w1, &w0, x[15], y[15]); + word3_muladd(&w2, &w1, &w0, x[16], y[14]); + word3_muladd(&w2, &w1, &w0, x[17], y[13]); + word3_muladd(&w2, &w1, &w0, x[18], y[12]); + word3_muladd(&w2, &w1, &w0, x[19], y[11]); + word3_muladd(&w2, &w1, &w0, x[20], y[10]); + word3_muladd(&w2, &w1, &w0, x[21], y[ 9]); + word3_muladd(&w2, &w1, &w0, x[22], y[ 8]); + word3_muladd(&w2, &w1, &w0, x[23], y[ 7]); + z[30] = w0; w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[ 8], y[23]); + word3_muladd(&w0, &w2, &w1, x[ 9], y[22]); + word3_muladd(&w0, &w2, &w1, x[10], y[21]); + word3_muladd(&w0, &w2, &w1, x[11], y[20]); + word3_muladd(&w0, &w2, &w1, x[12], y[19]); + word3_muladd(&w0, &w2, &w1, x[13], y[18]); + word3_muladd(&w0, &w2, &w1, x[14], y[17]); + word3_muladd(&w0, &w2, &w1, x[15], y[16]); + word3_muladd(&w0, &w2, &w1, x[16], y[15]); + word3_muladd(&w0, &w2, &w1, x[17], y[14]); + word3_muladd(&w0, &w2, &w1, x[18], y[13]); + word3_muladd(&w0, &w2, &w1, x[19], y[12]); + word3_muladd(&w0, &w2, &w1, x[20], y[11]); + word3_muladd(&w0, &w2, &w1, x[21], y[10]); + word3_muladd(&w0, &w2, &w1, x[22], y[ 9]); + word3_muladd(&w0, &w2, &w1, x[23], y[ 8]); + z[31] = w1; w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[ 9], y[23]); + word3_muladd(&w1, &w0, &w2, x[10], y[22]); + word3_muladd(&w1, &w0, &w2, x[11], y[21]); + word3_muladd(&w1, &w0, &w2, x[12], y[20]); + word3_muladd(&w1, &w0, &w2, x[13], y[19]); + word3_muladd(&w1, &w0, &w2, x[14], y[18]); + word3_muladd(&w1, &w0, &w2, x[15], y[17]); + word3_muladd(&w1, &w0, &w2, x[16], y[16]); + word3_muladd(&w1, &w0, &w2, x[17], y[15]); + word3_muladd(&w1, &w0, &w2, x[18], y[14]); + word3_muladd(&w1, &w0, &w2, x[19], y[13]); + word3_muladd(&w1, &w0, &w2, x[20], y[12]); + word3_muladd(&w1, &w0, &w2, x[21], y[11]); + word3_muladd(&w1, &w0, &w2, x[22], y[10]); + word3_muladd(&w1, &w0, &w2, x[23], y[ 9]); + z[32] = w2; w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[10], y[23]); + word3_muladd(&w2, &w1, &w0, x[11], y[22]); + word3_muladd(&w2, &w1, &w0, x[12], y[21]); + word3_muladd(&w2, &w1, &w0, x[13], y[20]); + word3_muladd(&w2, &w1, &w0, x[14], y[19]); + word3_muladd(&w2, &w1, &w0, x[15], y[18]); + word3_muladd(&w2, &w1, &w0, x[16], y[17]); + word3_muladd(&w2, &w1, &w0, x[17], y[16]); + word3_muladd(&w2, &w1, &w0, x[18], y[15]); + word3_muladd(&w2, &w1, &w0, x[19], y[14]); + word3_muladd(&w2, &w1, &w0, x[20], y[13]); + word3_muladd(&w2, &w1, &w0, x[21], y[12]); + word3_muladd(&w2, &w1, &w0, x[22], y[11]); + word3_muladd(&w2, &w1, &w0, x[23], y[10]); + z[33] = w0; w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[11], y[23]); + word3_muladd(&w0, &w2, &w1, x[12], y[22]); + word3_muladd(&w0, &w2, &w1, x[13], y[21]); + word3_muladd(&w0, &w2, &w1, x[14], y[20]); + word3_muladd(&w0, &w2, &w1, x[15], y[19]); + word3_muladd(&w0, &w2, &w1, x[16], y[18]); + word3_muladd(&w0, &w2, &w1, x[17], y[17]); + word3_muladd(&w0, &w2, &w1, x[18], y[16]); + word3_muladd(&w0, &w2, &w1, x[19], y[15]); + word3_muladd(&w0, &w2, &w1, x[20], y[14]); + word3_muladd(&w0, &w2, &w1, x[21], y[13]); + word3_muladd(&w0, &w2, &w1, x[22], y[12]); + word3_muladd(&w0, &w2, &w1, x[23], y[11]); + z[34] = w1; w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[12], y[23]); + word3_muladd(&w1, &w0, &w2, x[13], y[22]); + word3_muladd(&w1, &w0, &w2, x[14], y[21]); + word3_muladd(&w1, &w0, &w2, x[15], y[20]); + word3_muladd(&w1, &w0, &w2, x[16], y[19]); + word3_muladd(&w1, &w0, &w2, x[17], y[18]); + word3_muladd(&w1, &w0, &w2, x[18], y[17]); + word3_muladd(&w1, &w0, &w2, x[19], y[16]); + word3_muladd(&w1, &w0, &w2, x[20], y[15]); + word3_muladd(&w1, &w0, &w2, x[21], y[14]); + word3_muladd(&w1, &w0, &w2, x[22], y[13]); + word3_muladd(&w1, &w0, &w2, x[23], y[12]); + z[35] = w2; w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[13], y[23]); + word3_muladd(&w2, &w1, &w0, x[14], y[22]); + word3_muladd(&w2, &w1, &w0, x[15], y[21]); + word3_muladd(&w2, &w1, &w0, x[16], y[20]); + word3_muladd(&w2, &w1, &w0, x[17], y[19]); + word3_muladd(&w2, &w1, &w0, x[18], y[18]); + word3_muladd(&w2, &w1, &w0, x[19], y[17]); + word3_muladd(&w2, &w1, &w0, x[20], y[16]); + word3_muladd(&w2, &w1, &w0, x[21], y[15]); + word3_muladd(&w2, &w1, &w0, x[22], y[14]); + word3_muladd(&w2, &w1, &w0, x[23], y[13]); + z[36] = w0; w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[14], y[23]); + word3_muladd(&w0, &w2, &w1, x[15], y[22]); + word3_muladd(&w0, &w2, &w1, x[16], y[21]); + word3_muladd(&w0, &w2, &w1, x[17], y[20]); + word3_muladd(&w0, &w2, &w1, x[18], y[19]); + word3_muladd(&w0, &w2, &w1, x[19], y[18]); + word3_muladd(&w0, &w2, &w1, x[20], y[17]); + word3_muladd(&w0, &w2, &w1, x[21], y[16]); + word3_muladd(&w0, &w2, &w1, x[22], y[15]); + word3_muladd(&w0, &w2, &w1, x[23], y[14]); + z[37] = w1; w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[15], y[23]); + word3_muladd(&w1, &w0, &w2, x[16], y[22]); + word3_muladd(&w1, &w0, &w2, x[17], y[21]); + word3_muladd(&w1, &w0, &w2, x[18], y[20]); + word3_muladd(&w1, &w0, &w2, x[19], y[19]); + word3_muladd(&w1, &w0, &w2, x[20], y[18]); + word3_muladd(&w1, &w0, &w2, x[21], y[17]); + word3_muladd(&w1, &w0, &w2, x[22], y[16]); + word3_muladd(&w1, &w0, &w2, x[23], y[15]); + z[38] = w2; w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[16], y[23]); + word3_muladd(&w2, &w1, &w0, x[17], y[22]); + word3_muladd(&w2, &w1, &w0, x[18], y[21]); + word3_muladd(&w2, &w1, &w0, x[19], y[20]); + word3_muladd(&w2, &w1, &w0, x[20], y[19]); + word3_muladd(&w2, &w1, &w0, x[21], y[18]); + word3_muladd(&w2, &w1, &w0, x[22], y[17]); + word3_muladd(&w2, &w1, &w0, x[23], y[16]); + z[39] = w0; w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[17], y[23]); + word3_muladd(&w0, &w2, &w1, x[18], y[22]); + word3_muladd(&w0, &w2, &w1, x[19], y[21]); + word3_muladd(&w0, &w2, &w1, x[20], y[20]); + word3_muladd(&w0, &w2, &w1, x[21], y[19]); + word3_muladd(&w0, &w2, &w1, x[22], y[18]); + word3_muladd(&w0, &w2, &w1, x[23], y[17]); + z[40] = w1; w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[18], y[23]); + word3_muladd(&w1, &w0, &w2, x[19], y[22]); + word3_muladd(&w1, &w0, &w2, x[20], y[21]); + word3_muladd(&w1, &w0, &w2, x[21], y[20]); + word3_muladd(&w1, &w0, &w2, x[22], y[19]); + word3_muladd(&w1, &w0, &w2, x[23], y[18]); + z[41] = w2; w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[19], y[23]); + word3_muladd(&w2, &w1, &w0, x[20], y[22]); + word3_muladd(&w2, &w1, &w0, x[21], y[21]); + word3_muladd(&w2, &w1, &w0, x[22], y[20]); + word3_muladd(&w2, &w1, &w0, x[23], y[19]); + z[42] = w0; w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[20], y[23]); + word3_muladd(&w0, &w2, &w1, x[21], y[22]); + word3_muladd(&w0, &w2, &w1, x[22], y[21]); + word3_muladd(&w0, &w2, &w1, x[23], y[20]); + z[43] = w1; w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[21], y[23]); + word3_muladd(&w1, &w0, &w2, x[22], y[22]); + word3_muladd(&w1, &w0, &w2, x[23], y[21]); + z[44] = w2; w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[22], y[23]); + word3_muladd(&w2, &w1, &w0, x[23], y[22]); + z[45] = w0; w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[23], y[23]); + z[46] = w1; + z[47] = w2; + } + +} 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 new file mode 100644 index 0000000000..2ae65e508f --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/math/mp/mp_core.cpp @@ -0,0 +1,527 @@ +/* +* MPI Add, Subtract, Word Multiply +* (C) 1999-2010,2016 Jack Lloyd +* 2006 Luca Piccarreta +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include +#include + +namespace Botan { + +/* +* If cond == 0, does nothing. +* If cond > 0, swaps x[0:size] with y[0:size] +* Runs in constant time +*/ +void bigint_cnd_swap(word cnd, word x[], word y[], size_t size) + { + const word mask = CT::expand_mask(cnd); + + for(size_t i = 0; i != size; ++i) + { + const word a = x[i]; + const word b = y[i]; + x[i] = CT::select(mask, b, a); + y[i] = CT::select(mask, a, b); + } + } + +/* +* If cond > 0 adds x[0:size] to y[0:size] and returns carry +* Runs in constant time +*/ +word bigint_cnd_add(word cnd, word x[], const word y[], size_t size) + { + const word mask = CT::expand_mask(cnd); + + word carry = 0; + + const size_t blocks = size - (size % 8); + word z[8] = { 0 }; + + for(size_t i = 0; i != blocks; i += 8) + { + carry = word8_add3(z, x + i, y + i, carry); + + for(size_t j = 0; j != 8; ++j) + x[i+j] = CT::select(mask, z[j], x[i+j]); + } + + for(size_t i = blocks; i != size; ++i) + { + z[0] = word_add(x[i], y[i], &carry); + x[i] = CT::select(mask, z[0], x[i]); + } + + return carry & mask; + } + +/* +* If cond > 0 subs x[0:size] to y[0:size] and returns borrow +* Runs in constant time +*/ +word bigint_cnd_sub(word cnd, word x[], const word y[], size_t size) + { + const word mask = CT::expand_mask(cnd); + + word carry = 0; + + const size_t blocks = size - (size % 8); + word z[8] = { 0 }; + + for(size_t i = 0; i != blocks; i += 8) + { + carry = word8_sub3(z, x + i, y + i, carry); + + for(size_t j = 0; j != 8; ++j) + x[i+j] = CT::select(mask, z[j], x[i+j]); + } + + for(size_t i = blocks; i != size; ++i) + { + z[0] = word_sub(x[i], y[i], &carry); + x[i] = CT::select(mask, z[0], x[i]); + } + + return carry & mask; + } + +void bigint_cnd_addsub(word mask, word x[], const word y[], size_t size) + { + const size_t blocks = size - (size % 8); + + word carry = 0; + word borrow = 0; + + word t0[8] = { 0 }; + word t1[8] = { 0 }; + + for(size_t i = 0; i != blocks; i += 8) + { + carry = word8_add3(t0, x + i, y + i, carry); + borrow = word8_sub3(t1, x + i, y + i, borrow); + + for(size_t j = 0; j != 8; ++j) + x[i+j] = CT::select(mask, t0[j], t1[j]); + } + + for(size_t i = blocks; i != size; ++i) + { + const word a = word_add(x[i], y[i], &carry); + const word s = word_sub(x[i], y[i], &borrow); + + x[i] = CT::select(mask, a, s); + } + } + +void bigint_cnd_abs(word cnd, word x[], size_t size) + { + const word mask = CT::expand_mask(cnd); + + word carry = mask & 1; + for(size_t i = 0; i != size; ++i) + { + const word z = word_add(~x[i], 0, &carry); + x[i] = CT::select(mask, z, x[i]); + } + } + +/* +* Two Operand Addition, No Carry +*/ +word bigint_add2_nc(word x[], size_t x_size, const word y[], size_t y_size) + { + word carry = 0; + + BOTAN_ASSERT(x_size >= y_size, "Expected sizes"); + + const size_t blocks = y_size - (y_size % 8); + + for(size_t i = 0; i != blocks; i += 8) + carry = word8_add2(x + i, y + i, carry); + + for(size_t i = blocks; i != y_size; ++i) + x[i] = word_add(x[i], y[i], &carry); + + for(size_t i = y_size; i != x_size; ++i) + x[i] = word_add(x[i], 0, &carry); + + return carry; + } + +/* +* Three Operand Addition, No Carry +*/ +word bigint_add3_nc(word z[], const word x[], size_t x_size, + const word y[], size_t y_size) + { + if(x_size < y_size) + { return bigint_add3_nc(z, y, y_size, x, x_size); } + + word carry = 0; + + const size_t blocks = y_size - (y_size % 8); + + for(size_t i = 0; i != blocks; i += 8) + carry = word8_add3(z + i, x + i, y + i, carry); + + for(size_t i = blocks; i != y_size; ++i) + z[i] = word_add(x[i], y[i], &carry); + + for(size_t i = y_size; i != x_size; ++i) + z[i] = word_add(x[i], 0, &carry); + + return carry; + } + +/* +* Two Operand Addition +*/ +void bigint_add2(word x[], size_t x_size, const word y[], size_t y_size) + { + x[x_size] += bigint_add2_nc(x, x_size, y, y_size); + } + +/* +* Three Operand Addition +*/ +void bigint_add3(word z[], const word x[], size_t x_size, + const word y[], size_t y_size) + { + z[x_size > y_size ? x_size : y_size] += + bigint_add3_nc(z, x, x_size, y, y_size); + } + +/* +* Two Operand Subtraction +*/ +word bigint_sub2(word x[], size_t x_size, const word y[], size_t y_size) + { + word borrow = 0; + + BOTAN_ASSERT(x_size >= y_size, "Expected sizes"); + + const size_t blocks = y_size - (y_size % 8); + + for(size_t i = 0; i != blocks; i += 8) + borrow = word8_sub2(x + i, y + i, borrow); + + for(size_t i = blocks; i != y_size; ++i) + x[i] = word_sub(x[i], y[i], &borrow); + + for(size_t i = y_size; i != x_size; ++i) + x[i] = word_sub(x[i], 0, &borrow); + + return borrow; + } + +/* +* Two Operand Subtraction x = y - x +*/ +void bigint_sub2_rev(word x[], const word y[], size_t y_size) + { + word borrow = 0; + + const size_t blocks = y_size - (y_size % 8); + + for(size_t i = 0; i != blocks; i += 8) + borrow = word8_sub2_rev(x + i, y + i, borrow); + + for(size_t i = blocks; i != y_size; ++i) + x[i] = word_sub(y[i], x[i], &borrow); + + BOTAN_ASSERT(!borrow, "y must be greater than x"); + } + +word bigint_sub_abs(word z[], + const word x[], const word y[], size_t N, + word ws[]) + { + // Subtract in both direction then conditional copy out the result + + word* ws0 = ws; + word* ws1 = ws + N; + + word borrow0 = 0; + word borrow1 = 0; + + const size_t blocks = N - (N % 8); + + for(size_t i = 0; i != blocks; i += 8) + { + borrow0 = word8_sub3(ws0 + i, x + i, y + i, borrow0); + borrow1 = word8_sub3(ws1 + i, y + i, x + i, borrow1); + } + + for(size_t i = blocks; i != N; ++i) + { + ws0[i] = word_sub(x[i], y[i], &borrow0); + ws1[i] = word_sub(y[i], x[i], &borrow1); + } + + word mask = CT::conditional_copy_mem(borrow1, z, ws0, ws1, N); + + return CT::select(mask, 0, 1); + } + +/* +* Three Operand Subtraction +*/ +word bigint_sub3(word z[], const word x[], size_t x_size, + const word y[], size_t y_size) + { + word borrow = 0; + + BOTAN_ASSERT(x_size >= y_size, "Expected sizes"); + + const size_t blocks = y_size - (y_size % 8); + + for(size_t i = 0; i != blocks; i += 8) + borrow = word8_sub3(z + i, x + i, y + i, borrow); + + for(size_t i = blocks; i != y_size; ++i) + z[i] = word_sub(x[i], y[i], &borrow); + + for(size_t i = y_size; i != x_size; ++i) + z[i] = word_sub(x[i], 0, &borrow); + + return borrow; + } + +/* +* Two Operand Linear Multiply +*/ +void bigint_linmul2(word x[], size_t x_size, word y) + { + const size_t blocks = x_size - (x_size % 8); + + word carry = 0; + + for(size_t i = 0; i != blocks; i += 8) + carry = word8_linmul2(x + i, y, carry); + + for(size_t i = blocks; i != x_size; ++i) + x[i] = word_madd2(x[i], y, &carry); + + x[x_size] = carry; + } + +/* +* Three Operand Linear Multiply +*/ +void bigint_linmul3(word z[], const word x[], size_t x_size, word y) + { + const size_t blocks = x_size - (x_size % 8); + + word carry = 0; + + for(size_t i = 0; i != blocks; i += 8) + carry = word8_linmul3(z + i, x + i, y, carry); + + for(size_t i = blocks; i != x_size; ++i) + z[i] = word_madd2(x[i], y, &carry); + + z[x_size] = carry; + } + +/* +* Single Operand Left Shift +*/ +void bigint_shl1(word x[], size_t x_size, size_t word_shift, size_t bit_shift) + { + if(word_shift) + { + copy_mem(x + word_shift, x, x_size); + clear_mem(x, word_shift); + } + + if(bit_shift) + { + word carry = 0; + for(size_t j = word_shift; j != x_size + word_shift + 1; ++j) + { + word temp = x[j]; + x[j] = (temp << bit_shift) | carry; + carry = (temp >> (BOTAN_MP_WORD_BITS - bit_shift)); + } + } + } + +/* +* Single Operand Right Shift +*/ +void bigint_shr1(word x[], size_t x_size, size_t word_shift, size_t bit_shift) + { + if(x_size < word_shift) + { + clear_mem(x, x_size); + return; + } + + if(word_shift) + { + copy_mem(x, x + word_shift, x_size - word_shift); + clear_mem(x + x_size - word_shift, word_shift); + } + + if(bit_shift) + { + word carry = 0; + + size_t top = x_size - word_shift; + + while(top >= 4) + { + word w = x[top-1]; + x[top-1] = (w >> bit_shift) | carry; + carry = (w << (BOTAN_MP_WORD_BITS - bit_shift)); + + w = x[top-2]; + x[top-2] = (w >> bit_shift) | carry; + carry = (w << (BOTAN_MP_WORD_BITS - bit_shift)); + + w = x[top-3]; + x[top-3] = (w >> bit_shift) | carry; + carry = (w << (BOTAN_MP_WORD_BITS - bit_shift)); + + w = x[top-4]; + x[top-4] = (w >> bit_shift) | carry; + carry = (w << (BOTAN_MP_WORD_BITS - bit_shift)); + + top -= 4; + } + + while(top) + { + word w = x[top-1]; + x[top-1] = (w >> bit_shift) | carry; + carry = (w << (BOTAN_MP_WORD_BITS - bit_shift)); + + top--; + } + } + } + +/* +* Two Operand Left Shift +*/ +void bigint_shl2(word y[], const word x[], size_t x_size, + size_t word_shift, size_t bit_shift) + { + for(size_t j = 0; j != x_size; ++j) + y[j + word_shift] = x[j]; + if(bit_shift) + { + word carry = 0; + for(size_t j = word_shift; j != x_size + word_shift + 1; ++j) + { + word w = y[j]; + y[j] = (w << bit_shift) | carry; + carry = (w >> (BOTAN_MP_WORD_BITS - bit_shift)); + } + } + } + +/* +* Two Operand Right Shift +*/ +void bigint_shr2(word y[], const word x[], size_t x_size, + size_t word_shift, size_t bit_shift) + { + if(x_size < word_shift) return; + + for(size_t j = 0; j != x_size - word_shift; ++j) + y[j] = x[j + word_shift]; + if(bit_shift) + { + word carry = 0; + for(size_t j = x_size - word_shift; j > 0; --j) + { + word w = y[j-1]; + y[j-1] = (w >> bit_shift) | carry; + carry = (w << (BOTAN_MP_WORD_BITS - bit_shift)); + } + } + } + +/* +* Compare two MP integers +*/ +int32_t bigint_cmp(const word x[], size_t x_size, + const word y[], size_t y_size) + { + if(x_size < y_size) { return (-bigint_cmp(y, y_size, x, x_size)); } + + while(x_size > y_size) + { + if(x[x_size-1]) + return 1; + x_size--; + } + + for(size_t i = x_size; i > 0; --i) + { + if(x[i-1] > y[i-1]) + return 1; + if(x[i-1] < y[i-1]) + return -1; + } + + return 0; + } + +/* +* Do a 2-word/1-word Division +*/ +word bigint_divop(word n1, word n0, word d) + { + if(d == 0) + throw Invalid_Argument("bigint_divop divide by zero"); + +#if defined(BOTAN_HAS_MP_DWORD) + return ((static_cast(n1) << BOTAN_MP_WORD_BITS) | n0) / d; +#else + + word high = n1 % d, quotient = 0; + + for(size_t i = 0; i != BOTAN_MP_WORD_BITS; ++i) + { + word high_top_bit = (high & MP_WORD_TOP_BIT); + + high <<= 1; + high |= (n0 >> (BOTAN_MP_WORD_BITS-1-i)) & 1; + quotient <<= 1; + + if(high_top_bit || high >= d) + { + high -= d; + quotient |= 1; + } + } + + return quotient; +#endif + } + +/* +* Do a 2-word/1-word Modulo +*/ +word bigint_modop(word n1, word n0, word d) + { +#if defined(BOTAN_HAS_MP_DWORD) + return ((static_cast(n1) << BOTAN_MP_WORD_BITS) | n0) % d; +#else + word z = bigint_divop(n1, n0, d); + word dummy = 0; + z = word_madd2(z, d, &dummy); + return (n0-z); +#endif + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/math/mp/mp_core.h b/src/libs/3rdparty/botan/src/lib/math/mp/mp_core.h new file mode 100644 index 0000000000..9430c3753f --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/math/mp/mp_core.h @@ -0,0 +1,209 @@ +/* +* MPI Algorithms +* (C) 1999-2010 Jack Lloyd +* 2006 Luca Piccarreta +* 2016 Matthias Gierlings +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_MP_CORE_OPS_H_ +#define BOTAN_MP_CORE_OPS_H_ + +#include + +namespace Botan { + +const word MP_WORD_MASK = ~static_cast(0); +const word MP_WORD_TOP_BIT = static_cast(1) << (8*sizeof(word) - 1); +const word MP_WORD_MAX = MP_WORD_MASK; + +/* +* If cond == 0, does nothing. +* If cond > 0, swaps x[0:size] with y[0:size] +* Runs in constant time +*/ +BOTAN_TEST_API +void bigint_cnd_swap(word cnd, word x[], word y[], size_t size); + +/* +* If cond > 0 adds x[0:size] and y[0:size] and returns carry +* Runs in constant time +*/ +BOTAN_TEST_API +word bigint_cnd_add(word cnd, word x[], const word y[], size_t size); + +/* +* If cond > 0 subtracts x[0:size] and y[0:size] and returns borrow +* Runs in constant time +*/ +BOTAN_TEST_API +word bigint_cnd_sub(word cnd, word x[], const word y[], size_t size); + +/* +* Equivalent to +* bigint_cnd_add( mask, x, y, size); +* bigint_cnd_sub(~mask, x, y, size); +* +* Mask must be either 0 or all 1 bits +*/ +void bigint_cnd_addsub(word mask, word x[], const word y[], size_t size); + +/* +* 2s complement absolute value +* If cond > 0 sets x to ~x + 1 +* Runs in constant time +*/ +BOTAN_TEST_API +void bigint_cnd_abs(word cnd, word x[], size_t size); + +/** +* Two operand addition +* @param x the first operand (and output) +* @param x_size size of x +* @param y the second operand +* @param y_size size of y (must be >= x_size) +*/ +void bigint_add2(word x[], size_t x_size, + const word y[], size_t y_size); + +/** +* Three operand addition +*/ +void bigint_add3(word z[], + const word x[], size_t x_size, + const word y[], size_t y_size); + +/** +* Two operand addition with carry out +*/ +word bigint_add2_nc(word x[], size_t x_size, const word y[], size_t y_size); + +/** +* Three operand addition with carry out +*/ +word bigint_add3_nc(word z[], + const word x[], size_t x_size, + const word y[], size_t y_size); + +/** +* Two operand subtraction +*/ +word bigint_sub2(word x[], size_t x_size, + const word y[], size_t y_size); + +/** +* Two operand subtraction, x = y - x; assumes y >= x +*/ +void bigint_sub2_rev(word x[], const word y[], size_t y_size); + +/** +* Three operand subtraction +*/ +word bigint_sub3(word z[], + const word x[], size_t x_size, + const word y[], size_t y_size); + +/** +* Return abs(x-y), ie if x >= y, then compute z = x - y +* Otherwise compute z = y - x +* No borrow is possible since the result is always >= 0 +* +* Returns 1 if x >= y or 0 if x < y +* @param z output array of at least N words +* @param x input array of N words +* @param y input array of N words +* @param N length of x and y +* @param ws array of at least 2*N words +*/ +word bigint_sub_abs(word z[], + const word x[], const word y[], size_t N, + word ws[]); + +/* +* Shift Operations +*/ +void bigint_shl1(word x[], size_t x_size, + size_t word_shift, size_t bit_shift); + +void bigint_shr1(word x[], size_t x_size, + size_t word_shift, size_t bit_shift); + +void bigint_shl2(word y[], const word x[], size_t x_size, + size_t word_shift, size_t bit_shift); + +void bigint_shr2(word y[], const word x[], size_t x_size, + size_t word_shift, size_t bit_shift); + +/* +* Linear Multiply +*/ +void bigint_linmul2(word x[], size_t x_size, word y); +void bigint_linmul3(word z[], const word x[], size_t x_size, word y); + +/** +* Montgomery Reduction +* @param z integer to reduce, of size exactly 2*(p_size+1). + Output is in the first p_size+1 words, higher + words are set to zero. +* @param p modulus +* @param p_size size of p +* @param p_dash Montgomery value +* @param workspace array of at least 2*(p_size+1) words +* @param ws_size size of workspace in words +*/ +void bigint_monty_redc(word z[], + const word p[], size_t p_size, + word p_dash, + word workspace[], + size_t ws_size); + +/** +* Compare x and y returning early +*/ +int32_t bigint_cmp(const word x[], size_t x_size, + const word y[], size_t y_size); + +/** +* Compute ((n1< +#include +#include +#include +#include + +namespace Botan { + +namespace { + +const size_t KARATSUBA_MULTIPLY_THRESHOLD = 32; +const size_t KARATSUBA_SQUARE_THRESHOLD = 32; + +/* +* Simple O(N^2) Multiplication +*/ +void basecase_mul(word z[], size_t z_size, + const word x[], size_t x_size, + const word y[], size_t y_size) + { + if(z_size < x_size + y_size) + throw Invalid_Argument("basecase_mul z_size too small"); + + const size_t x_size_8 = x_size - (x_size % 8); + + clear_mem(z, z_size); + + for(size_t i = 0; i != y_size; ++i) + { + const word y_i = y[i]; + + word carry = 0; + + for(size_t j = 0; j != x_size_8; j += 8) + carry = word8_madd3(z + i + j, x + j, y_i, carry); + + for(size_t j = x_size_8; j != x_size; ++j) + z[i+j] = word_madd3(x[j], y_i, z[i+j], &carry); + + z[x_size+i] = carry; + } + } + +void basecase_sqr(word z[], size_t z_size, + const word x[], size_t x_size) + { + if(z_size < 2*x_size) + throw Invalid_Argument("basecase_sqr z_size too small"); + + const size_t x_size_8 = x_size - (x_size % 8); + + clear_mem(z, z_size); + + for(size_t i = 0; i != x_size; ++i) + { + const word x_i = x[i]; + + word carry = 0; + + for(size_t j = 0; j != x_size_8; j += 8) + carry = word8_madd3(z + i + j, x + j, x_i, carry); + + for(size_t j = x_size_8; j != x_size; ++j) + z[i+j] = word_madd3(x[j], x_i, z[i+j], &carry); + + z[x_size+i] = carry; + } + } + +/* +* Karatsuba Multiplication Operation +*/ +void karatsuba_mul(word z[], const word x[], const word y[], size_t N, + word workspace[]) + { + if(N < KARATSUBA_MULTIPLY_THRESHOLD || N % 2) + { + if(N == 6) + return bigint_comba_mul6(z, x, y); + else if(N == 8) + return bigint_comba_mul8(z, x, y); + else if(N == 9) + return bigint_comba_mul9(z, x, y); + else if(N == 16) + return bigint_comba_mul16(z, x, y); + else if(N == 24) + return bigint_comba_mul24(z, x, y); + else + return basecase_mul(z, 2*N, x, N, y, N); + } + + const size_t N2 = N / 2; + + const word* x0 = x; + const word* x1 = x + N2; + const word* y0 = y; + const word* y1 = y + N2; + word* z0 = z; + word* z1 = z + N; + + word* ws0 = workspace; + word* ws1 = workspace + N; + + clear_mem(workspace, 2*N); + + /* + * If either of cmp0 or cmp1 is zero then z0 or z1 resp is zero here, + * resulting in a no-op - z0*z1 will be equal to zero so we don't need to do + * anything, clear_mem above already set the correct result. + * + * However we ignore the result of the comparisons and always perform the + * subtractions and recursively multiply to avoid the timing channel. + */ + + // First compute (X_lo - X_hi)*(Y_hi - Y_lo) + const word cmp0 = bigint_sub_abs(z0, x0, x1, N2, workspace); + const word cmp1 = bigint_sub_abs(z1, y1, y0, N2, workspace); + + karatsuba_mul(ws0, z0, z1, N2, ws1); + + // Compute X_lo * Y_lo + karatsuba_mul(z0, x0, y0, N2, ws1); + + // Compute X_hi * Y_hi + karatsuba_mul(z1, x1, y1, N2, ws1); + + const word ws_carry = bigint_add3_nc(ws1, z0, N, z1, N); + word z_carry = bigint_add2_nc(z + N2, N, ws1, N); + + z_carry += bigint_add2_nc(z + N + N2, N2, &ws_carry, 1); + bigint_add2_nc(z + N + N2, N2, &z_carry, 1); + + clear_mem(workspace + N, N2); + + const word neg_mask = CT::is_equal(cmp0, cmp1); + + bigint_cnd_addsub(neg_mask, z + N2, workspace, 2*N-N2); + } + +/* +* Karatsuba Squaring Operation +*/ +void karatsuba_sqr(word z[], const word x[], size_t N, word workspace[]) + { + if(N < KARATSUBA_SQUARE_THRESHOLD || N % 2) + { + if(N == 6) + return bigint_comba_sqr6(z, x); + else if(N == 8) + return bigint_comba_sqr8(z, x); + else if(N == 9) + return bigint_comba_sqr9(z, x); + else if(N == 16) + return bigint_comba_sqr16(z, x); + else if(N == 24) + return bigint_comba_sqr24(z, x); + else + return basecase_sqr(z, 2*N, x, N); + } + + const size_t N2 = N / 2; + + const word* x0 = x; + const word* x1 = x + N2; + word* z0 = z; + word* z1 = z + N; + + word* ws0 = workspace; + word* ws1 = workspace + N; + + clear_mem(workspace, 2*N); + + // See comment in karatsuba_mul + bigint_sub_abs(z0, x0, x1, N2, workspace); + karatsuba_sqr(ws0, z0, N2, ws1); + + karatsuba_sqr(z0, x0, N2, ws1); + karatsuba_sqr(z1, x1, N2, ws1); + + const word ws_carry = bigint_add3_nc(ws1, z0, N, z1, N); + word z_carry = bigint_add2_nc(z + N2, N, ws1, N); + + z_carry += bigint_add2_nc(z + N + N2, N2, &ws_carry, 1); + bigint_add2_nc(z + N + N2, N2, &z_carry, 1); + + /* + * This is only actually required if cmp (result of bigint_sub_abs) is != 0, + * however if cmp==0 then ws0[0:N] == 0 and avoiding the jump hides a + * timing channel. + */ + bigint_sub2(z + N2, 2*N-N2, ws0, N); + } + +/* +* Pick a good size for the Karatsuba multiply +*/ +size_t karatsuba_size(size_t z_size, + size_t x_size, size_t x_sw, + size_t y_size, size_t y_sw) + { + if(x_sw > x_size || x_sw > y_size || y_sw > x_size || y_sw > y_size) + return 0; + + if(((x_size == x_sw) && (x_size % 2)) || + ((y_size == y_sw) && (y_size % 2))) + return 0; + + const size_t start = (x_sw > y_sw) ? x_sw : y_sw; + const size_t end = (x_size < y_size) ? x_size : y_size; + + if(start == end) + { + if(start % 2) + return 0; + return start; + } + + for(size_t j = start; j <= end; ++j) + { + if(j % 2) + continue; + + if(2*j > z_size) + return 0; + + if(x_sw <= j && j <= x_size && y_sw <= j && j <= y_size) + { + if(j % 4 == 2 && + (j+2) <= x_size && (j+2) <= y_size && 2*(j+2) <= z_size) + return j+2; + return j; + } + } + + return 0; + } + +/* +* Pick a good size for the Karatsuba squaring +*/ +size_t karatsuba_size(size_t z_size, size_t x_size, size_t x_sw) + { + if(x_sw == x_size) + { + if(x_sw % 2) + return 0; + return x_sw; + } + + for(size_t j = x_sw; j <= x_size; ++j) + { + if(j % 2) + continue; + + if(2*j > z_size) + return 0; + + if(j % 4 == 2 && (j+2) <= x_size && 2*(j+2) <= z_size) + return j+2; + return j; + } + + return 0; + } + +template +inline bool sized_for_comba_mul(size_t x_sw, size_t x_size, + size_t y_sw, size_t y_size, + size_t z_size) + { + return (x_sw <= SZ && x_size >= SZ && + y_sw <= SZ && y_size >= SZ && + z_size >= 2*SZ); + } + +template +inline bool sized_for_comba_sqr(size_t x_sw, size_t x_size, + size_t z_size) + { + return (x_sw <= SZ && x_size >= SZ && z_size >= 2*SZ); + } + +} + +void bigint_mul(word z[], size_t z_size, + const word x[], size_t x_size, size_t x_sw, + const word y[], size_t y_size, size_t y_sw, + word workspace[], size_t ws_size) + { + clear_mem(z, z_size); + + if(x_sw == 1) + { + bigint_linmul3(z, y, y_sw, x[0]); + } + else if(y_sw == 1) + { + bigint_linmul3(z, x, x_sw, y[0]); + } + else if(sized_for_comba_mul<4>(x_sw, x_size, y_sw, y_size, z_size)) + { + bigint_comba_mul4(z, x, y); + } + else if(sized_for_comba_mul<6>(x_sw, x_size, y_sw, y_size, z_size)) + { + bigint_comba_mul6(z, x, y); + } + else if(sized_for_comba_mul<8>(x_sw, x_size, y_sw, y_size, z_size)) + { + bigint_comba_mul8(z, x, y); + } + else if(sized_for_comba_mul<9>(x_sw, x_size, y_sw, y_size, z_size)) + { + bigint_comba_mul9(z, x, y); + } + else if(sized_for_comba_mul<16>(x_sw, x_size, y_sw, y_size, z_size)) + { + bigint_comba_mul16(z, x, y); + } + else if(sized_for_comba_mul<24>(x_sw, x_size, y_sw, y_size, z_size)) + { + bigint_comba_mul24(z, x, y); + } + else if(x_sw < KARATSUBA_MULTIPLY_THRESHOLD || + y_sw < KARATSUBA_MULTIPLY_THRESHOLD || + !workspace) + { + basecase_mul(z, z_size, x, x_sw, y, y_sw); + } + else + { + const size_t N = karatsuba_size(z_size, x_size, x_sw, y_size, y_sw); + + if(N && z_size >= 2*N && ws_size >= 2*N) + karatsuba_mul(z, x, y, N, workspace); + else + basecase_mul(z, z_size, x, x_sw, y, y_sw); + } + } + +/* +* Squaring Algorithm Dispatcher +*/ +void bigint_sqr(word z[], size_t z_size, + const word x[], size_t x_size, size_t x_sw, + word workspace[], size_t ws_size) + { + clear_mem(z, z_size); + + BOTAN_ASSERT(z_size/2 >= x_sw, "Output size is sufficient"); + + if(x_sw == 1) + { + bigint_linmul3(z, x, x_sw, x[0]); + } + else if(sized_for_comba_sqr<4>(x_sw, x_size, z_size)) + { + bigint_comba_sqr4(z, x); + } + else if(sized_for_comba_sqr<6>(x_sw, x_size, z_size)) + { + bigint_comba_sqr6(z, x); + } + else if(sized_for_comba_sqr<8>(x_sw, x_size, z_size)) + { + bigint_comba_sqr8(z, x); + } + else if(sized_for_comba_sqr<9>(x_sw, x_size, z_size)) + { + bigint_comba_sqr9(z, x); + } + else if(sized_for_comba_sqr<16>(x_sw, x_size, z_size)) + { + bigint_comba_sqr16(z, x); + } + else if(sized_for_comba_sqr<24>(x_sw, x_size, z_size)) + { + bigint_comba_sqr24(z, x); + } + else if(x_size < KARATSUBA_SQUARE_THRESHOLD || !workspace) + { + basecase_sqr(z, z_size, x, x_sw); + } + else + { + const size_t N = karatsuba_size(z_size, x_size, x_sw); + + if(N && z_size >= 2*N && ws_size >= 2*N) + karatsuba_sqr(z, x, N, workspace); + else + basecase_sqr(z, z_size, x, x_sw); + } + } + +} 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 new file mode 100644 index 0000000000..4807fcd040 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/math/mp/mp_madd.h @@ -0,0 +1,165 @@ +/* +* Lowest Level MPI Algorithms +* (C) 1999-2008,2013 Jack Lloyd +* 2006 Luca Piccarreta +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_MP_WORD_MULADD_H_ +#define BOTAN_MP_WORD_MULADD_H_ + +#include +#include + +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) + 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; + #define BOTAN_HAS_MP_DWORD + #else + // No native 128 bit integer type; use mul64x64_128 instead + #endif + +#else + #error BOTAN_MP_WORD_BITS must be 8, 16, 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) + #define ASM(x) x "\n\t" +#endif + +/* +* Word Multiply/Add +*/ +inline word word_madd2(word a, word b, word* c) + { +#if defined(BOTAN_MP_USE_X86_32_ASM) + asm( + ASM("mull %[b]") + ASM("addl %[c],%[a]") + ASM("adcl $0,%[carry]") + + : [a]"=a"(a), [b]"=rm"(b), [carry]"=&d"(*c) + : "0"(a), "1"(b), [c]"g"(*c) : "cc"); + + return a; + +#elif defined(BOTAN_MP_USE_X86_64_ASM) + asm( + ASM("mulq %[b]") + ASM("addq %[c],%[a]") + ASM("adcq $0,%[carry]") + + : [a]"=a"(a), [b]"=rm"(b), [carry]"=&d"(*c) + : "0"(a), "1"(b), [c]"g"(*c) : "cc"); + + return a; + +#elif defined(BOTAN_HAS_MP_DWORD) + const dword s = static_cast(a) * b + *c; + *c = static_cast(s >> BOTAN_MP_WORD_BITS); + return static_cast(s); +#else + static_assert(BOTAN_MP_WORD_BITS == 64, "Unexpected word size"); + + word hi = 0, lo = 0; + + mul64x64_128(a, b, &lo, &hi); + + lo += *c; + hi += (lo < *c); // carry? + + *c = hi; + return lo; +#endif + } + +/* +* Word Multiply/Add +*/ +inline word word_madd3(word a, word b, word c, word* d) + { +#if defined(BOTAN_MP_USE_X86_32_ASM) + asm( + ASM("mull %[b]") + + ASM("addl %[c],%[a]") + ASM("adcl $0,%[carry]") + + ASM("addl %[d],%[a]") + ASM("adcl $0,%[carry]") + + : [a]"=a"(a), [b]"=rm"(b), [carry]"=&d"(*d) + : "0"(a), "1"(b), [c]"g"(c), [d]"g"(*d) : "cc"); + + return a; + +#elif defined(BOTAN_MP_USE_X86_64_ASM) + asm( + ASM("mulq %[b]") + + ASM("addq %[c],%[a]") + ASM("adcq $0,%[carry]") + + ASM("addq %[d],%[a]") + ASM("adcq $0,%[carry]") + + : [a]"=a"(a), [b]"=rm"(b), [carry]"=&d"(*d) + : "0"(a), "1"(b), [c]"g"(c), [d]"g"(*d) : "cc"); + + return a; + +#elif defined(BOTAN_HAS_MP_DWORD) + const dword s = static_cast(a) * b + c + *d; + *d = static_cast(s >> BOTAN_MP_WORD_BITS); + return static_cast(s); +#else + static_assert(BOTAN_MP_WORD_BITS == 64, "Unexpected word size"); + + word hi = 0, lo = 0; + + mul64x64_128(a, b, &lo, &hi); + + lo += c; + hi += (lo < c); // carry? + + lo += *d; + hi += (lo < *d); // carry? + + *d = hi; + return lo; +#endif + } + +#if defined(ASM) + #undef ASM +#endif + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/math/mp/mp_monty.cpp b/src/libs/3rdparty/botan/src/lib/math/mp/mp_monty.cpp new file mode 100644 index 0000000000..e5dda705ce --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/math/mp/mp_monty.cpp @@ -0,0 +1,135 @@ +/* +* Montgomery Reduction +* (C) 1999-2011 Jack Lloyd +* 2006 Luca Piccarreta +* 2016 Matthias Gierlings +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include +#include +#include +#include + +namespace Botan { + +namespace { + +/* +* Montgomery reduction - product scanning form +* +* https://www.iacr.org/archive/ches2005/006.pdf +* https://eprint.iacr.org/2013/882.pdf +* https://www.microsoft.com/en-us/research/wp-content/uploads/1996/01/j37acmon.pdf +*/ +void bigint_monty_redc_generic(word z[], size_t z_size, + const word p[], size_t p_size, word p_dash, + word ws[]) + { + word w2 = 0, w1 = 0, w0 = 0; + + w0 = z[0]; + + ws[0] = w0 * p_dash; + + word3_muladd(&w2, &w1, &w0, ws[0], p[0]); + + w0 = w1; + w1 = w2; + w2 = 0; + + for(size_t i = 1; i != p_size; ++i) + { + for(size_t j = 0; j < i; ++j) + { + word3_muladd(&w2, &w1, &w0, ws[j], p[i-j]); + } + + word3_add(&w2, &w1, &w0, z[i]); + + ws[i] = w0 * p_dash; + + word3_muladd(&w2, &w1, &w0, ws[i], p[0]); + + w0 = w1; + w1 = w2; + w2 = 0; + } + + for(size_t i = 0; i != p_size; ++i) + { + for(size_t j = i + 1; j != p_size; ++j) + { + word3_muladd(&w2, &w1, &w0, ws[j], p[p_size + i-j]); + } + + word3_add(&w2, &w1, &w0, z[p_size+i]); + + ws[i] = w0; + w0 = w1; + w1 = w2; + w2 = 0; + } + + word3_add(&w2, &w1, &w0, z[z_size-1]); + + ws[p_size] = w0; + ws[p_size+1] = w1; + + /* + * The result might need to be reduced mod p. To avoid a timing + * channel, always perform the subtraction. If in the compution + * of x - p a borrow is required then x was already < p. + * + * x starts at ws[0] and is p_size+1 bytes long. + * x - p starts at ws[p_size+1] and is also p_size+1 bytes log + * + * Select which address to copy from indexing off of the final + * borrow. + */ + + // word borrow = bigint_sub3(ws + p_size + 1, ws, p_size + 1, p, p_size); + word borrow = 0; + for(size_t i = 0; i != p_size; ++i) + ws[p_size + 1 + i] = word_sub(ws[i], p[i], &borrow); + ws[2*p_size+1] = word_sub(ws[p_size], 0, &borrow); + + CT::conditional_copy_mem(borrow, z, ws, ws + (p_size + 1), (p_size + 1)); + clear_mem(z + p_size, z_size - p_size - 2); + + // This check comes after we've used it but that's ok here + CT::unpoison(&borrow, 1); + BOTAN_ASSERT(borrow == 0 || borrow == 1, "Expected borrow"); + } + +} + +void bigint_monty_redc(word z[], + const word p[], size_t p_size, word p_dash, + word ws[], size_t ws_size) + { + const size_t z_size = 2*(p_size+1); + + BOTAN_ARG_CHECK(ws_size >= z_size, "workspace too small"); + + if(p_size == 4) + bigint_monty_redc_4(z, p, p_dash, ws); + else if(p_size == 6) + bigint_monty_redc_6(z, p, p_dash, ws); + else if(p_size == 8) + bigint_monty_redc_8(z, p, p_dash, ws); + else if(p_size == 16) + bigint_monty_redc_16(z, p, p_dash, ws); + else if(p_size == 24) + bigint_monty_redc_24(z, p, p_dash, ws); + else if(p_size == 32) + bigint_monty_redc_32(z, p, p_dash, ws); + else + bigint_monty_redc_generic(z, z_size, p, p_size, p_dash, ws); + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/math/mp/mp_monty.h b/src/libs/3rdparty/botan/src/lib/math/mp/mp_monty.h new file mode 100644 index 0000000000..7462272d5c --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/math/mp/mp_monty.h @@ -0,0 +1,31 @@ +/* +* (C) 2018 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_MP_MONTY_H_ +#define BOTAN_MP_MONTY_H_ + +#include + +namespace Botan { + +/* +* Each of these functions makes the following assumptions: +* +* z_size >= 2*(p_size + 1) +* ws_size >= z_size +*/ + +void bigint_monty_redc_4(word z[], const word p[], word p_dash, word ws[]); +void bigint_monty_redc_6(word z[], const word p[], word p_dash, word ws[]); +void bigint_monty_redc_8(word z[], const word p[], word p_dash, word ws[]); +void bigint_monty_redc_16(word z[], const word p[], word p_dash, word ws[]); +void bigint_monty_redc_24(word z[], const word p[], word p_dash, word ws[]); +void bigint_monty_redc_32(word z[], const word p[], word p_dash, word ws[]); + + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/math/mp/mp_monty_n.cpp b/src/libs/3rdparty/botan/src/lib/math/mp/mp_monty_n.cpp new file mode 100644 index 0000000000..0331d4a073 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/math/mp/mp_monty_n.cpp @@ -0,0 +1,2614 @@ +/* +* This file was automatically generated by ./src/scripts/monty.py on 2018-06-11 +* All manual changes will be lost. Edit the script instead. +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include + +namespace Botan { + +void bigint_monty_redc_4(word z[], const word p[4], word p_dash, word ws[]) + { + word w2 = 0, w1 = 0, w0 = 0; + w0 = z[0]; + ws[0] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[0], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[1]); + word3_add(&w2, &w1, &w0, z[1]); + ws[1] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[1], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[2]); + word3_muladd(&w2, &w1, &w0, ws[1], p[1]); + word3_add(&w2, &w1, &w0, z[2]); + ws[2] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[2], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[3]); + word3_muladd(&w2, &w1, &w0, ws[1], p[2]); + word3_muladd(&w2, &w1, &w0, ws[2], p[1]); + word3_add(&w2, &w1, &w0, z[3]); + ws[3] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[3], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[1], p[3]); + word3_muladd(&w2, &w1, &w0, ws[2], p[2]); + word3_muladd(&w2, &w1, &w0, ws[3], p[1]); + word3_add(&w2, &w1, &w0, z[4]); + ws[0] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[2], p[3]); + word3_muladd(&w2, &w1, &w0, ws[3], p[2]); + word3_add(&w2, &w1, &w0, z[5]); + ws[1] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[3], p[3]); + word3_add(&w2, &w1, &w0, z[6]); + ws[2] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_add(&w2, &w1, &w0, z[7]); + ws[3] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_add(&w2, &w1, &w0, z[9]); + ws[4] = w0; + ws[5] = w1; + word borrow = 0; + ws[5] = word_sub(ws[0], p[0], &borrow); + ws[6] = word_sub(ws[1], p[1], &borrow); + ws[7] = word_sub(ws[2], p[2], &borrow); + ws[8] = word_sub(ws[3], p[3], &borrow); + ws[9] = word_sub(ws[4], 0, &borrow); + CT::conditional_copy_mem(borrow, z, ws, ws + 5, 5); + clear_mem(z + 4, 2*(4+1) - 4); + } + +void bigint_monty_redc_6(word z[], const word p[6], word p_dash, word ws[]) + { + word w2 = 0, w1 = 0, w0 = 0; + w0 = z[0]; + ws[0] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[0], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[1]); + word3_add(&w2, &w1, &w0, z[1]); + ws[1] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[1], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[2]); + word3_muladd(&w2, &w1, &w0, ws[1], p[1]); + word3_add(&w2, &w1, &w0, z[2]); + ws[2] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[2], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[3]); + word3_muladd(&w2, &w1, &w0, ws[1], p[2]); + word3_muladd(&w2, &w1, &w0, ws[2], p[1]); + word3_add(&w2, &w1, &w0, z[3]); + ws[3] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[3], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[4]); + word3_muladd(&w2, &w1, &w0, ws[1], p[3]); + word3_muladd(&w2, &w1, &w0, ws[2], p[2]); + word3_muladd(&w2, &w1, &w0, ws[3], p[1]); + word3_add(&w2, &w1, &w0, z[4]); + ws[4] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[4], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[5]); + word3_muladd(&w2, &w1, &w0, ws[1], p[4]); + word3_muladd(&w2, &w1, &w0, ws[2], p[3]); + word3_muladd(&w2, &w1, &w0, ws[3], p[2]); + word3_muladd(&w2, &w1, &w0, ws[4], p[1]); + word3_add(&w2, &w1, &w0, z[5]); + ws[5] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[5], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[1], p[5]); + word3_muladd(&w2, &w1, &w0, ws[2], p[4]); + word3_muladd(&w2, &w1, &w0, ws[3], p[3]); + word3_muladd(&w2, &w1, &w0, ws[4], p[2]); + word3_muladd(&w2, &w1, &w0, ws[5], p[1]); + word3_add(&w2, &w1, &w0, z[6]); + ws[0] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[2], p[5]); + word3_muladd(&w2, &w1, &w0, ws[3], p[4]); + word3_muladd(&w2, &w1, &w0, ws[4], p[3]); + word3_muladd(&w2, &w1, &w0, ws[5], p[2]); + word3_add(&w2, &w1, &w0, z[7]); + ws[1] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[3], p[5]); + word3_muladd(&w2, &w1, &w0, ws[4], p[4]); + word3_muladd(&w2, &w1, &w0, ws[5], p[3]); + word3_add(&w2, &w1, &w0, z[8]); + ws[2] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[4], p[5]); + word3_muladd(&w2, &w1, &w0, ws[5], p[4]); + word3_add(&w2, &w1, &w0, z[9]); + ws[3] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[5], p[5]); + word3_add(&w2, &w1, &w0, z[10]); + ws[4] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_add(&w2, &w1, &w0, z[11]); + ws[5] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_add(&w2, &w1, &w0, z[13]); + ws[6] = w0; + ws[7] = w1; + word borrow = 0; + ws[7] = word_sub(ws[0], p[0], &borrow); + ws[8] = word_sub(ws[1], p[1], &borrow); + ws[9] = word_sub(ws[2], p[2], &borrow); + ws[10] = word_sub(ws[3], p[3], &borrow); + ws[11] = word_sub(ws[4], p[4], &borrow); + ws[12] = word_sub(ws[5], p[5], &borrow); + ws[13] = word_sub(ws[6], 0, &borrow); + CT::conditional_copy_mem(borrow, z, ws, ws + 7, 7); + clear_mem(z + 6, 2*(6+1) - 6); + } + +void bigint_monty_redc_8(word z[], const word p[8], word p_dash, word ws[]) + { + word w2 = 0, w1 = 0, w0 = 0; + w0 = z[0]; + ws[0] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[0], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[1]); + word3_add(&w2, &w1, &w0, z[1]); + ws[1] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[1], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[2]); + word3_muladd(&w2, &w1, &w0, ws[1], p[1]); + word3_add(&w2, &w1, &w0, z[2]); + ws[2] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[2], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[3]); + word3_muladd(&w2, &w1, &w0, ws[1], p[2]); + word3_muladd(&w2, &w1, &w0, ws[2], p[1]); + word3_add(&w2, &w1, &w0, z[3]); + ws[3] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[3], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[4]); + word3_muladd(&w2, &w1, &w0, ws[1], p[3]); + word3_muladd(&w2, &w1, &w0, ws[2], p[2]); + word3_muladd(&w2, &w1, &w0, ws[3], p[1]); + word3_add(&w2, &w1, &w0, z[4]); + ws[4] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[4], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[5]); + word3_muladd(&w2, &w1, &w0, ws[1], p[4]); + word3_muladd(&w2, &w1, &w0, ws[2], p[3]); + word3_muladd(&w2, &w1, &w0, ws[3], p[2]); + word3_muladd(&w2, &w1, &w0, ws[4], p[1]); + word3_add(&w2, &w1, &w0, z[5]); + ws[5] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[5], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[6]); + word3_muladd(&w2, &w1, &w0, ws[1], p[5]); + word3_muladd(&w2, &w1, &w0, ws[2], p[4]); + word3_muladd(&w2, &w1, &w0, ws[3], p[3]); + word3_muladd(&w2, &w1, &w0, ws[4], p[2]); + word3_muladd(&w2, &w1, &w0, ws[5], p[1]); + word3_add(&w2, &w1, &w0, z[6]); + ws[6] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[6], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[7]); + word3_muladd(&w2, &w1, &w0, ws[1], p[6]); + word3_muladd(&w2, &w1, &w0, ws[2], p[5]); + word3_muladd(&w2, &w1, &w0, ws[3], p[4]); + word3_muladd(&w2, &w1, &w0, ws[4], p[3]); + word3_muladd(&w2, &w1, &w0, ws[5], p[2]); + word3_muladd(&w2, &w1, &w0, ws[6], p[1]); + word3_add(&w2, &w1, &w0, z[7]); + ws[7] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[7], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[1], p[7]); + word3_muladd(&w2, &w1, &w0, ws[2], p[6]); + word3_muladd(&w2, &w1, &w0, ws[3], p[5]); + word3_muladd(&w2, &w1, &w0, ws[4], p[4]); + word3_muladd(&w2, &w1, &w0, ws[5], p[3]); + word3_muladd(&w2, &w1, &w0, ws[6], p[2]); + word3_muladd(&w2, &w1, &w0, ws[7], p[1]); + word3_add(&w2, &w1, &w0, z[8]); + ws[0] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[2], p[7]); + word3_muladd(&w2, &w1, &w0, ws[3], p[6]); + word3_muladd(&w2, &w1, &w0, ws[4], p[5]); + word3_muladd(&w2, &w1, &w0, ws[5], p[4]); + word3_muladd(&w2, &w1, &w0, ws[6], p[3]); + word3_muladd(&w2, &w1, &w0, ws[7], p[2]); + word3_add(&w2, &w1, &w0, z[9]); + ws[1] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[3], p[7]); + word3_muladd(&w2, &w1, &w0, ws[4], p[6]); + word3_muladd(&w2, &w1, &w0, ws[5], p[5]); + word3_muladd(&w2, &w1, &w0, ws[6], p[4]); + word3_muladd(&w2, &w1, &w0, ws[7], p[3]); + word3_add(&w2, &w1, &w0, z[10]); + ws[2] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[4], p[7]); + word3_muladd(&w2, &w1, &w0, ws[5], p[6]); + word3_muladd(&w2, &w1, &w0, ws[6], p[5]); + word3_muladd(&w2, &w1, &w0, ws[7], p[4]); + word3_add(&w2, &w1, &w0, z[11]); + ws[3] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[5], p[7]); + word3_muladd(&w2, &w1, &w0, ws[6], p[6]); + word3_muladd(&w2, &w1, &w0, ws[7], p[5]); + word3_add(&w2, &w1, &w0, z[12]); + ws[4] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[6], p[7]); + word3_muladd(&w2, &w1, &w0, ws[7], p[6]); + word3_add(&w2, &w1, &w0, z[13]); + ws[5] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[7], p[7]); + word3_add(&w2, &w1, &w0, z[14]); + ws[6] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_add(&w2, &w1, &w0, z[15]); + ws[7] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_add(&w2, &w1, &w0, z[17]); + ws[8] = w0; + ws[9] = w1; + word borrow = 0; + ws[9] = word_sub(ws[0], p[0], &borrow); + ws[10] = word_sub(ws[1], p[1], &borrow); + ws[11] = word_sub(ws[2], p[2], &borrow); + ws[12] = word_sub(ws[3], p[3], &borrow); + ws[13] = word_sub(ws[4], p[4], &borrow); + ws[14] = word_sub(ws[5], p[5], &borrow); + ws[15] = word_sub(ws[6], p[6], &borrow); + ws[16] = word_sub(ws[7], p[7], &borrow); + ws[17] = word_sub(ws[8], 0, &borrow); + CT::conditional_copy_mem(borrow, z, ws, ws + 9, 9); + clear_mem(z + 8, 2*(8+1) - 8); + } + +void bigint_monty_redc_16(word z[], const word p[16], word p_dash, word ws[]) + { + word w2 = 0, w1 = 0, w0 = 0; + w0 = z[0]; + ws[0] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[0], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[1]); + word3_add(&w2, &w1, &w0, z[1]); + ws[1] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[1], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[2]); + word3_muladd(&w2, &w1, &w0, ws[1], p[1]); + word3_add(&w2, &w1, &w0, z[2]); + ws[2] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[2], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[3]); + word3_muladd(&w2, &w1, &w0, ws[1], p[2]); + word3_muladd(&w2, &w1, &w0, ws[2], p[1]); + word3_add(&w2, &w1, &w0, z[3]); + ws[3] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[3], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[4]); + word3_muladd(&w2, &w1, &w0, ws[1], p[3]); + word3_muladd(&w2, &w1, &w0, ws[2], p[2]); + word3_muladd(&w2, &w1, &w0, ws[3], p[1]); + word3_add(&w2, &w1, &w0, z[4]); + ws[4] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[4], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[5]); + word3_muladd(&w2, &w1, &w0, ws[1], p[4]); + word3_muladd(&w2, &w1, &w0, ws[2], p[3]); + word3_muladd(&w2, &w1, &w0, ws[3], p[2]); + word3_muladd(&w2, &w1, &w0, ws[4], p[1]); + word3_add(&w2, &w1, &w0, z[5]); + ws[5] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[5], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[6]); + word3_muladd(&w2, &w1, &w0, ws[1], p[5]); + word3_muladd(&w2, &w1, &w0, ws[2], p[4]); + word3_muladd(&w2, &w1, &w0, ws[3], p[3]); + word3_muladd(&w2, &w1, &w0, ws[4], p[2]); + word3_muladd(&w2, &w1, &w0, ws[5], p[1]); + word3_add(&w2, &w1, &w0, z[6]); + ws[6] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[6], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[7]); + word3_muladd(&w2, &w1, &w0, ws[1], p[6]); + word3_muladd(&w2, &w1, &w0, ws[2], p[5]); + word3_muladd(&w2, &w1, &w0, ws[3], p[4]); + word3_muladd(&w2, &w1, &w0, ws[4], p[3]); + word3_muladd(&w2, &w1, &w0, ws[5], p[2]); + word3_muladd(&w2, &w1, &w0, ws[6], p[1]); + word3_add(&w2, &w1, &w0, z[7]); + ws[7] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[7], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[8]); + word3_muladd(&w2, &w1, &w0, ws[1], p[7]); + word3_muladd(&w2, &w1, &w0, ws[2], p[6]); + word3_muladd(&w2, &w1, &w0, ws[3], p[5]); + word3_muladd(&w2, &w1, &w0, ws[4], p[4]); + word3_muladd(&w2, &w1, &w0, ws[5], p[3]); + word3_muladd(&w2, &w1, &w0, ws[6], p[2]); + word3_muladd(&w2, &w1, &w0, ws[7], p[1]); + word3_add(&w2, &w1, &w0, z[8]); + ws[8] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[8], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[9]); + word3_muladd(&w2, &w1, &w0, ws[1], p[8]); + word3_muladd(&w2, &w1, &w0, ws[2], p[7]); + word3_muladd(&w2, &w1, &w0, ws[3], p[6]); + word3_muladd(&w2, &w1, &w0, ws[4], p[5]); + word3_muladd(&w2, &w1, &w0, ws[5], p[4]); + word3_muladd(&w2, &w1, &w0, ws[6], p[3]); + word3_muladd(&w2, &w1, &w0, ws[7], p[2]); + word3_muladd(&w2, &w1, &w0, ws[8], p[1]); + word3_add(&w2, &w1, &w0, z[9]); + ws[9] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[9], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[10]); + word3_muladd(&w2, &w1, &w0, ws[1], p[9]); + word3_muladd(&w2, &w1, &w0, ws[2], p[8]); + word3_muladd(&w2, &w1, &w0, ws[3], p[7]); + word3_muladd(&w2, &w1, &w0, ws[4], p[6]); + word3_muladd(&w2, &w1, &w0, ws[5], p[5]); + word3_muladd(&w2, &w1, &w0, ws[6], p[4]); + word3_muladd(&w2, &w1, &w0, ws[7], p[3]); + word3_muladd(&w2, &w1, &w0, ws[8], p[2]); + word3_muladd(&w2, &w1, &w0, ws[9], p[1]); + word3_add(&w2, &w1, &w0, z[10]); + ws[10] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[10], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[11]); + word3_muladd(&w2, &w1, &w0, ws[1], p[10]); + word3_muladd(&w2, &w1, &w0, ws[2], p[9]); + word3_muladd(&w2, &w1, &w0, ws[3], p[8]); + word3_muladd(&w2, &w1, &w0, ws[4], p[7]); + word3_muladd(&w2, &w1, &w0, ws[5], p[6]); + word3_muladd(&w2, &w1, &w0, ws[6], p[5]); + word3_muladd(&w2, &w1, &w0, ws[7], p[4]); + word3_muladd(&w2, &w1, &w0, ws[8], p[3]); + word3_muladd(&w2, &w1, &w0, ws[9], p[2]); + word3_muladd(&w2, &w1, &w0, ws[10], p[1]); + word3_add(&w2, &w1, &w0, z[11]); + ws[11] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[11], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[12]); + word3_muladd(&w2, &w1, &w0, ws[1], p[11]); + word3_muladd(&w2, &w1, &w0, ws[2], p[10]); + word3_muladd(&w2, &w1, &w0, ws[3], p[9]); + word3_muladd(&w2, &w1, &w0, ws[4], p[8]); + word3_muladd(&w2, &w1, &w0, ws[5], p[7]); + word3_muladd(&w2, &w1, &w0, ws[6], p[6]); + word3_muladd(&w2, &w1, &w0, ws[7], p[5]); + word3_muladd(&w2, &w1, &w0, ws[8], p[4]); + word3_muladd(&w2, &w1, &w0, ws[9], p[3]); + word3_muladd(&w2, &w1, &w0, ws[10], p[2]); + word3_muladd(&w2, &w1, &w0, ws[11], p[1]); + word3_add(&w2, &w1, &w0, z[12]); + ws[12] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[12], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[13]); + word3_muladd(&w2, &w1, &w0, ws[1], p[12]); + word3_muladd(&w2, &w1, &w0, ws[2], p[11]); + word3_muladd(&w2, &w1, &w0, ws[3], p[10]); + word3_muladd(&w2, &w1, &w0, ws[4], p[9]); + word3_muladd(&w2, &w1, &w0, ws[5], p[8]); + word3_muladd(&w2, &w1, &w0, ws[6], p[7]); + word3_muladd(&w2, &w1, &w0, ws[7], p[6]); + word3_muladd(&w2, &w1, &w0, ws[8], p[5]); + word3_muladd(&w2, &w1, &w0, ws[9], p[4]); + word3_muladd(&w2, &w1, &w0, ws[10], p[3]); + word3_muladd(&w2, &w1, &w0, ws[11], p[2]); + word3_muladd(&w2, &w1, &w0, ws[12], p[1]); + word3_add(&w2, &w1, &w0, z[13]); + ws[13] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[13], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[14]); + word3_muladd(&w2, &w1, &w0, ws[1], p[13]); + word3_muladd(&w2, &w1, &w0, ws[2], p[12]); + word3_muladd(&w2, &w1, &w0, ws[3], p[11]); + word3_muladd(&w2, &w1, &w0, ws[4], p[10]); + word3_muladd(&w2, &w1, &w0, ws[5], p[9]); + word3_muladd(&w2, &w1, &w0, ws[6], p[8]); + word3_muladd(&w2, &w1, &w0, ws[7], p[7]); + word3_muladd(&w2, &w1, &w0, ws[8], p[6]); + word3_muladd(&w2, &w1, &w0, ws[9], p[5]); + word3_muladd(&w2, &w1, &w0, ws[10], p[4]); + word3_muladd(&w2, &w1, &w0, ws[11], p[3]); + word3_muladd(&w2, &w1, &w0, ws[12], p[2]); + word3_muladd(&w2, &w1, &w0, ws[13], p[1]); + word3_add(&w2, &w1, &w0, z[14]); + ws[14] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[14], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[15]); + word3_muladd(&w2, &w1, &w0, ws[1], p[14]); + word3_muladd(&w2, &w1, &w0, ws[2], p[13]); + word3_muladd(&w2, &w1, &w0, ws[3], p[12]); + word3_muladd(&w2, &w1, &w0, ws[4], p[11]); + word3_muladd(&w2, &w1, &w0, ws[5], p[10]); + word3_muladd(&w2, &w1, &w0, ws[6], p[9]); + word3_muladd(&w2, &w1, &w0, ws[7], p[8]); + word3_muladd(&w2, &w1, &w0, ws[8], p[7]); + word3_muladd(&w2, &w1, &w0, ws[9], p[6]); + word3_muladd(&w2, &w1, &w0, ws[10], p[5]); + word3_muladd(&w2, &w1, &w0, ws[11], p[4]); + word3_muladd(&w2, &w1, &w0, ws[12], p[3]); + word3_muladd(&w2, &w1, &w0, ws[13], p[2]); + word3_muladd(&w2, &w1, &w0, ws[14], p[1]); + word3_add(&w2, &w1, &w0, z[15]); + ws[15] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[15], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[1], p[15]); + word3_muladd(&w2, &w1, &w0, ws[2], p[14]); + word3_muladd(&w2, &w1, &w0, ws[3], p[13]); + word3_muladd(&w2, &w1, &w0, ws[4], p[12]); + word3_muladd(&w2, &w1, &w0, ws[5], p[11]); + word3_muladd(&w2, &w1, &w0, ws[6], p[10]); + word3_muladd(&w2, &w1, &w0, ws[7], p[9]); + word3_muladd(&w2, &w1, &w0, ws[8], p[8]); + word3_muladd(&w2, &w1, &w0, ws[9], p[7]); + word3_muladd(&w2, &w1, &w0, ws[10], p[6]); + word3_muladd(&w2, &w1, &w0, ws[11], p[5]); + word3_muladd(&w2, &w1, &w0, ws[12], p[4]); + word3_muladd(&w2, &w1, &w0, ws[13], p[3]); + word3_muladd(&w2, &w1, &w0, ws[14], p[2]); + word3_muladd(&w2, &w1, &w0, ws[15], p[1]); + word3_add(&w2, &w1, &w0, z[16]); + ws[0] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[2], p[15]); + word3_muladd(&w2, &w1, &w0, ws[3], p[14]); + word3_muladd(&w2, &w1, &w0, ws[4], p[13]); + word3_muladd(&w2, &w1, &w0, ws[5], p[12]); + word3_muladd(&w2, &w1, &w0, ws[6], p[11]); + word3_muladd(&w2, &w1, &w0, ws[7], p[10]); + word3_muladd(&w2, &w1, &w0, ws[8], p[9]); + word3_muladd(&w2, &w1, &w0, ws[9], p[8]); + word3_muladd(&w2, &w1, &w0, ws[10], p[7]); + word3_muladd(&w2, &w1, &w0, ws[11], p[6]); + word3_muladd(&w2, &w1, &w0, ws[12], p[5]); + word3_muladd(&w2, &w1, &w0, ws[13], p[4]); + word3_muladd(&w2, &w1, &w0, ws[14], p[3]); + word3_muladd(&w2, &w1, &w0, ws[15], p[2]); + word3_add(&w2, &w1, &w0, z[17]); + ws[1] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[3], p[15]); + word3_muladd(&w2, &w1, &w0, ws[4], p[14]); + word3_muladd(&w2, &w1, &w0, ws[5], p[13]); + word3_muladd(&w2, &w1, &w0, ws[6], p[12]); + word3_muladd(&w2, &w1, &w0, ws[7], p[11]); + word3_muladd(&w2, &w1, &w0, ws[8], p[10]); + word3_muladd(&w2, &w1, &w0, ws[9], p[9]); + word3_muladd(&w2, &w1, &w0, ws[10], p[8]); + word3_muladd(&w2, &w1, &w0, ws[11], p[7]); + word3_muladd(&w2, &w1, &w0, ws[12], p[6]); + word3_muladd(&w2, &w1, &w0, ws[13], p[5]); + word3_muladd(&w2, &w1, &w0, ws[14], p[4]); + word3_muladd(&w2, &w1, &w0, ws[15], p[3]); + word3_add(&w2, &w1, &w0, z[18]); + ws[2] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[4], p[15]); + word3_muladd(&w2, &w1, &w0, ws[5], p[14]); + word3_muladd(&w2, &w1, &w0, ws[6], p[13]); + word3_muladd(&w2, &w1, &w0, ws[7], p[12]); + word3_muladd(&w2, &w1, &w0, ws[8], p[11]); + word3_muladd(&w2, &w1, &w0, ws[9], p[10]); + word3_muladd(&w2, &w1, &w0, ws[10], p[9]); + word3_muladd(&w2, &w1, &w0, ws[11], p[8]); + word3_muladd(&w2, &w1, &w0, ws[12], p[7]); + word3_muladd(&w2, &w1, &w0, ws[13], p[6]); + word3_muladd(&w2, &w1, &w0, ws[14], p[5]); + word3_muladd(&w2, &w1, &w0, ws[15], p[4]); + word3_add(&w2, &w1, &w0, z[19]); + ws[3] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[5], p[15]); + word3_muladd(&w2, &w1, &w0, ws[6], p[14]); + word3_muladd(&w2, &w1, &w0, ws[7], p[13]); + word3_muladd(&w2, &w1, &w0, ws[8], p[12]); + word3_muladd(&w2, &w1, &w0, ws[9], p[11]); + word3_muladd(&w2, &w1, &w0, ws[10], p[10]); + word3_muladd(&w2, &w1, &w0, ws[11], p[9]); + word3_muladd(&w2, &w1, &w0, ws[12], p[8]); + word3_muladd(&w2, &w1, &w0, ws[13], p[7]); + word3_muladd(&w2, &w1, &w0, ws[14], p[6]); + word3_muladd(&w2, &w1, &w0, ws[15], p[5]); + word3_add(&w2, &w1, &w0, z[20]); + ws[4] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[6], p[15]); + word3_muladd(&w2, &w1, &w0, ws[7], p[14]); + word3_muladd(&w2, &w1, &w0, ws[8], p[13]); + word3_muladd(&w2, &w1, &w0, ws[9], p[12]); + word3_muladd(&w2, &w1, &w0, ws[10], p[11]); + word3_muladd(&w2, &w1, &w0, ws[11], p[10]); + word3_muladd(&w2, &w1, &w0, ws[12], p[9]); + word3_muladd(&w2, &w1, &w0, ws[13], p[8]); + word3_muladd(&w2, &w1, &w0, ws[14], p[7]); + word3_muladd(&w2, &w1, &w0, ws[15], p[6]); + word3_add(&w2, &w1, &w0, z[21]); + ws[5] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[7], p[15]); + word3_muladd(&w2, &w1, &w0, ws[8], p[14]); + word3_muladd(&w2, &w1, &w0, ws[9], p[13]); + word3_muladd(&w2, &w1, &w0, ws[10], p[12]); + word3_muladd(&w2, &w1, &w0, ws[11], p[11]); + word3_muladd(&w2, &w1, &w0, ws[12], p[10]); + word3_muladd(&w2, &w1, &w0, ws[13], p[9]); + word3_muladd(&w2, &w1, &w0, ws[14], p[8]); + word3_muladd(&w2, &w1, &w0, ws[15], p[7]); + word3_add(&w2, &w1, &w0, z[22]); + ws[6] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[8], p[15]); + word3_muladd(&w2, &w1, &w0, ws[9], p[14]); + word3_muladd(&w2, &w1, &w0, ws[10], p[13]); + word3_muladd(&w2, &w1, &w0, ws[11], p[12]); + word3_muladd(&w2, &w1, &w0, ws[12], p[11]); + word3_muladd(&w2, &w1, &w0, ws[13], p[10]); + word3_muladd(&w2, &w1, &w0, ws[14], p[9]); + word3_muladd(&w2, &w1, &w0, ws[15], p[8]); + word3_add(&w2, &w1, &w0, z[23]); + ws[7] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[9], p[15]); + word3_muladd(&w2, &w1, &w0, ws[10], p[14]); + word3_muladd(&w2, &w1, &w0, ws[11], p[13]); + word3_muladd(&w2, &w1, &w0, ws[12], p[12]); + word3_muladd(&w2, &w1, &w0, ws[13], p[11]); + word3_muladd(&w2, &w1, &w0, ws[14], p[10]); + word3_muladd(&w2, &w1, &w0, ws[15], p[9]); + word3_add(&w2, &w1, &w0, z[24]); + ws[8] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[10], p[15]); + word3_muladd(&w2, &w1, &w0, ws[11], p[14]); + word3_muladd(&w2, &w1, &w0, ws[12], p[13]); + word3_muladd(&w2, &w1, &w0, ws[13], p[12]); + word3_muladd(&w2, &w1, &w0, ws[14], p[11]); + word3_muladd(&w2, &w1, &w0, ws[15], p[10]); + word3_add(&w2, &w1, &w0, z[25]); + ws[9] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[11], p[15]); + word3_muladd(&w2, &w1, &w0, ws[12], p[14]); + word3_muladd(&w2, &w1, &w0, ws[13], p[13]); + word3_muladd(&w2, &w1, &w0, ws[14], p[12]); + word3_muladd(&w2, &w1, &w0, ws[15], p[11]); + word3_add(&w2, &w1, &w0, z[26]); + ws[10] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[12], p[15]); + word3_muladd(&w2, &w1, &w0, ws[13], p[14]); + word3_muladd(&w2, &w1, &w0, ws[14], p[13]); + word3_muladd(&w2, &w1, &w0, ws[15], p[12]); + word3_add(&w2, &w1, &w0, z[27]); + ws[11] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[13], p[15]); + word3_muladd(&w2, &w1, &w0, ws[14], p[14]); + word3_muladd(&w2, &w1, &w0, ws[15], p[13]); + word3_add(&w2, &w1, &w0, z[28]); + ws[12] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[14], p[15]); + word3_muladd(&w2, &w1, &w0, ws[15], p[14]); + word3_add(&w2, &w1, &w0, z[29]); + ws[13] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[15], p[15]); + word3_add(&w2, &w1, &w0, z[30]); + ws[14] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_add(&w2, &w1, &w0, z[31]); + ws[15] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_add(&w2, &w1, &w0, z[33]); + ws[16] = w0; + ws[17] = w1; + word borrow = bigint_sub3(ws + 16 + 1, ws, 16 + 1, p, 16); + CT::conditional_copy_mem(borrow, z, ws, ws + 17, 17); + clear_mem(z + 16, 2*(16+1) - 16); + } + +void bigint_monty_redc_24(word z[], const word p[24], word p_dash, word ws[]) + { + word w2 = 0, w1 = 0, w0 = 0; + w0 = z[0]; + ws[0] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[0], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[1]); + word3_add(&w2, &w1, &w0, z[1]); + ws[1] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[1], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[2]); + word3_muladd(&w2, &w1, &w0, ws[1], p[1]); + word3_add(&w2, &w1, &w0, z[2]); + ws[2] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[2], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[3]); + word3_muladd(&w2, &w1, &w0, ws[1], p[2]); + word3_muladd(&w2, &w1, &w0, ws[2], p[1]); + word3_add(&w2, &w1, &w0, z[3]); + ws[3] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[3], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[4]); + word3_muladd(&w2, &w1, &w0, ws[1], p[3]); + word3_muladd(&w2, &w1, &w0, ws[2], p[2]); + word3_muladd(&w2, &w1, &w0, ws[3], p[1]); + word3_add(&w2, &w1, &w0, z[4]); + ws[4] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[4], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[5]); + word3_muladd(&w2, &w1, &w0, ws[1], p[4]); + word3_muladd(&w2, &w1, &w0, ws[2], p[3]); + word3_muladd(&w2, &w1, &w0, ws[3], p[2]); + word3_muladd(&w2, &w1, &w0, ws[4], p[1]); + word3_add(&w2, &w1, &w0, z[5]); + ws[5] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[5], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[6]); + word3_muladd(&w2, &w1, &w0, ws[1], p[5]); + word3_muladd(&w2, &w1, &w0, ws[2], p[4]); + word3_muladd(&w2, &w1, &w0, ws[3], p[3]); + word3_muladd(&w2, &w1, &w0, ws[4], p[2]); + word3_muladd(&w2, &w1, &w0, ws[5], p[1]); + word3_add(&w2, &w1, &w0, z[6]); + ws[6] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[6], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[7]); + word3_muladd(&w2, &w1, &w0, ws[1], p[6]); + word3_muladd(&w2, &w1, &w0, ws[2], p[5]); + word3_muladd(&w2, &w1, &w0, ws[3], p[4]); + word3_muladd(&w2, &w1, &w0, ws[4], p[3]); + word3_muladd(&w2, &w1, &w0, ws[5], p[2]); + word3_muladd(&w2, &w1, &w0, ws[6], p[1]); + word3_add(&w2, &w1, &w0, z[7]); + ws[7] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[7], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[8]); + word3_muladd(&w2, &w1, &w0, ws[1], p[7]); + word3_muladd(&w2, &w1, &w0, ws[2], p[6]); + word3_muladd(&w2, &w1, &w0, ws[3], p[5]); + word3_muladd(&w2, &w1, &w0, ws[4], p[4]); + word3_muladd(&w2, &w1, &w0, ws[5], p[3]); + word3_muladd(&w2, &w1, &w0, ws[6], p[2]); + word3_muladd(&w2, &w1, &w0, ws[7], p[1]); + word3_add(&w2, &w1, &w0, z[8]); + ws[8] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[8], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[9]); + word3_muladd(&w2, &w1, &w0, ws[1], p[8]); + word3_muladd(&w2, &w1, &w0, ws[2], p[7]); + word3_muladd(&w2, &w1, &w0, ws[3], p[6]); + word3_muladd(&w2, &w1, &w0, ws[4], p[5]); + word3_muladd(&w2, &w1, &w0, ws[5], p[4]); + word3_muladd(&w2, &w1, &w0, ws[6], p[3]); + word3_muladd(&w2, &w1, &w0, ws[7], p[2]); + word3_muladd(&w2, &w1, &w0, ws[8], p[1]); + word3_add(&w2, &w1, &w0, z[9]); + ws[9] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[9], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[10]); + word3_muladd(&w2, &w1, &w0, ws[1], p[9]); + word3_muladd(&w2, &w1, &w0, ws[2], p[8]); + word3_muladd(&w2, &w1, &w0, ws[3], p[7]); + word3_muladd(&w2, &w1, &w0, ws[4], p[6]); + word3_muladd(&w2, &w1, &w0, ws[5], p[5]); + word3_muladd(&w2, &w1, &w0, ws[6], p[4]); + word3_muladd(&w2, &w1, &w0, ws[7], p[3]); + word3_muladd(&w2, &w1, &w0, ws[8], p[2]); + word3_muladd(&w2, &w1, &w0, ws[9], p[1]); + word3_add(&w2, &w1, &w0, z[10]); + ws[10] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[10], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[11]); + word3_muladd(&w2, &w1, &w0, ws[1], p[10]); + word3_muladd(&w2, &w1, &w0, ws[2], p[9]); + word3_muladd(&w2, &w1, &w0, ws[3], p[8]); + word3_muladd(&w2, &w1, &w0, ws[4], p[7]); + word3_muladd(&w2, &w1, &w0, ws[5], p[6]); + word3_muladd(&w2, &w1, &w0, ws[6], p[5]); + word3_muladd(&w2, &w1, &w0, ws[7], p[4]); + word3_muladd(&w2, &w1, &w0, ws[8], p[3]); + word3_muladd(&w2, &w1, &w0, ws[9], p[2]); + word3_muladd(&w2, &w1, &w0, ws[10], p[1]); + word3_add(&w2, &w1, &w0, z[11]); + ws[11] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[11], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[12]); + word3_muladd(&w2, &w1, &w0, ws[1], p[11]); + word3_muladd(&w2, &w1, &w0, ws[2], p[10]); + word3_muladd(&w2, &w1, &w0, ws[3], p[9]); + word3_muladd(&w2, &w1, &w0, ws[4], p[8]); + word3_muladd(&w2, &w1, &w0, ws[5], p[7]); + word3_muladd(&w2, &w1, &w0, ws[6], p[6]); + word3_muladd(&w2, &w1, &w0, ws[7], p[5]); + word3_muladd(&w2, &w1, &w0, ws[8], p[4]); + word3_muladd(&w2, &w1, &w0, ws[9], p[3]); + word3_muladd(&w2, &w1, &w0, ws[10], p[2]); + word3_muladd(&w2, &w1, &w0, ws[11], p[1]); + word3_add(&w2, &w1, &w0, z[12]); + ws[12] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[12], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[13]); + word3_muladd(&w2, &w1, &w0, ws[1], p[12]); + word3_muladd(&w2, &w1, &w0, ws[2], p[11]); + word3_muladd(&w2, &w1, &w0, ws[3], p[10]); + word3_muladd(&w2, &w1, &w0, ws[4], p[9]); + word3_muladd(&w2, &w1, &w0, ws[5], p[8]); + word3_muladd(&w2, &w1, &w0, ws[6], p[7]); + word3_muladd(&w2, &w1, &w0, ws[7], p[6]); + word3_muladd(&w2, &w1, &w0, ws[8], p[5]); + word3_muladd(&w2, &w1, &w0, ws[9], p[4]); + word3_muladd(&w2, &w1, &w0, ws[10], p[3]); + word3_muladd(&w2, &w1, &w0, ws[11], p[2]); + word3_muladd(&w2, &w1, &w0, ws[12], p[1]); + word3_add(&w2, &w1, &w0, z[13]); + ws[13] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[13], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[14]); + word3_muladd(&w2, &w1, &w0, ws[1], p[13]); + word3_muladd(&w2, &w1, &w0, ws[2], p[12]); + word3_muladd(&w2, &w1, &w0, ws[3], p[11]); + word3_muladd(&w2, &w1, &w0, ws[4], p[10]); + word3_muladd(&w2, &w1, &w0, ws[5], p[9]); + word3_muladd(&w2, &w1, &w0, ws[6], p[8]); + word3_muladd(&w2, &w1, &w0, ws[7], p[7]); + word3_muladd(&w2, &w1, &w0, ws[8], p[6]); + word3_muladd(&w2, &w1, &w0, ws[9], p[5]); + word3_muladd(&w2, &w1, &w0, ws[10], p[4]); + word3_muladd(&w2, &w1, &w0, ws[11], p[3]); + word3_muladd(&w2, &w1, &w0, ws[12], p[2]); + word3_muladd(&w2, &w1, &w0, ws[13], p[1]); + word3_add(&w2, &w1, &w0, z[14]); + ws[14] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[14], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[15]); + word3_muladd(&w2, &w1, &w0, ws[1], p[14]); + word3_muladd(&w2, &w1, &w0, ws[2], p[13]); + word3_muladd(&w2, &w1, &w0, ws[3], p[12]); + word3_muladd(&w2, &w1, &w0, ws[4], p[11]); + word3_muladd(&w2, &w1, &w0, ws[5], p[10]); + word3_muladd(&w2, &w1, &w0, ws[6], p[9]); + word3_muladd(&w2, &w1, &w0, ws[7], p[8]); + word3_muladd(&w2, &w1, &w0, ws[8], p[7]); + word3_muladd(&w2, &w1, &w0, ws[9], p[6]); + word3_muladd(&w2, &w1, &w0, ws[10], p[5]); + word3_muladd(&w2, &w1, &w0, ws[11], p[4]); + word3_muladd(&w2, &w1, &w0, ws[12], p[3]); + word3_muladd(&w2, &w1, &w0, ws[13], p[2]); + word3_muladd(&w2, &w1, &w0, ws[14], p[1]); + word3_add(&w2, &w1, &w0, z[15]); + ws[15] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[15], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[16]); + word3_muladd(&w2, &w1, &w0, ws[1], p[15]); + word3_muladd(&w2, &w1, &w0, ws[2], p[14]); + word3_muladd(&w2, &w1, &w0, ws[3], p[13]); + word3_muladd(&w2, &w1, &w0, ws[4], p[12]); + word3_muladd(&w2, &w1, &w0, ws[5], p[11]); + word3_muladd(&w2, &w1, &w0, ws[6], p[10]); + word3_muladd(&w2, &w1, &w0, ws[7], p[9]); + word3_muladd(&w2, &w1, &w0, ws[8], p[8]); + word3_muladd(&w2, &w1, &w0, ws[9], p[7]); + word3_muladd(&w2, &w1, &w0, ws[10], p[6]); + word3_muladd(&w2, &w1, &w0, ws[11], p[5]); + word3_muladd(&w2, &w1, &w0, ws[12], p[4]); + word3_muladd(&w2, &w1, &w0, ws[13], p[3]); + word3_muladd(&w2, &w1, &w0, ws[14], p[2]); + word3_muladd(&w2, &w1, &w0, ws[15], p[1]); + word3_add(&w2, &w1, &w0, z[16]); + ws[16] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[16], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[17]); + word3_muladd(&w2, &w1, &w0, ws[1], p[16]); + word3_muladd(&w2, &w1, &w0, ws[2], p[15]); + word3_muladd(&w2, &w1, &w0, ws[3], p[14]); + word3_muladd(&w2, &w1, &w0, ws[4], p[13]); + word3_muladd(&w2, &w1, &w0, ws[5], p[12]); + word3_muladd(&w2, &w1, &w0, ws[6], p[11]); + word3_muladd(&w2, &w1, &w0, ws[7], p[10]); + word3_muladd(&w2, &w1, &w0, ws[8], p[9]); + word3_muladd(&w2, &w1, &w0, ws[9], p[8]); + word3_muladd(&w2, &w1, &w0, ws[10], p[7]); + word3_muladd(&w2, &w1, &w0, ws[11], p[6]); + word3_muladd(&w2, &w1, &w0, ws[12], p[5]); + word3_muladd(&w2, &w1, &w0, ws[13], p[4]); + word3_muladd(&w2, &w1, &w0, ws[14], p[3]); + word3_muladd(&w2, &w1, &w0, ws[15], p[2]); + word3_muladd(&w2, &w1, &w0, ws[16], p[1]); + word3_add(&w2, &w1, &w0, z[17]); + ws[17] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[17], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[18]); + word3_muladd(&w2, &w1, &w0, ws[1], p[17]); + word3_muladd(&w2, &w1, &w0, ws[2], p[16]); + word3_muladd(&w2, &w1, &w0, ws[3], p[15]); + word3_muladd(&w2, &w1, &w0, ws[4], p[14]); + word3_muladd(&w2, &w1, &w0, ws[5], p[13]); + word3_muladd(&w2, &w1, &w0, ws[6], p[12]); + word3_muladd(&w2, &w1, &w0, ws[7], p[11]); + word3_muladd(&w2, &w1, &w0, ws[8], p[10]); + word3_muladd(&w2, &w1, &w0, ws[9], p[9]); + word3_muladd(&w2, &w1, &w0, ws[10], p[8]); + word3_muladd(&w2, &w1, &w0, ws[11], p[7]); + word3_muladd(&w2, &w1, &w0, ws[12], p[6]); + word3_muladd(&w2, &w1, &w0, ws[13], p[5]); + word3_muladd(&w2, &w1, &w0, ws[14], p[4]); + word3_muladd(&w2, &w1, &w0, ws[15], p[3]); + word3_muladd(&w2, &w1, &w0, ws[16], p[2]); + word3_muladd(&w2, &w1, &w0, ws[17], p[1]); + word3_add(&w2, &w1, &w0, z[18]); + ws[18] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[18], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[19]); + word3_muladd(&w2, &w1, &w0, ws[1], p[18]); + word3_muladd(&w2, &w1, &w0, ws[2], p[17]); + word3_muladd(&w2, &w1, &w0, ws[3], p[16]); + word3_muladd(&w2, &w1, &w0, ws[4], p[15]); + word3_muladd(&w2, &w1, &w0, ws[5], p[14]); + word3_muladd(&w2, &w1, &w0, ws[6], p[13]); + word3_muladd(&w2, &w1, &w0, ws[7], p[12]); + word3_muladd(&w2, &w1, &w0, ws[8], p[11]); + word3_muladd(&w2, &w1, &w0, ws[9], p[10]); + word3_muladd(&w2, &w1, &w0, ws[10], p[9]); + word3_muladd(&w2, &w1, &w0, ws[11], p[8]); + word3_muladd(&w2, &w1, &w0, ws[12], p[7]); + word3_muladd(&w2, &w1, &w0, ws[13], p[6]); + word3_muladd(&w2, &w1, &w0, ws[14], p[5]); + word3_muladd(&w2, &w1, &w0, ws[15], p[4]); + word3_muladd(&w2, &w1, &w0, ws[16], p[3]); + word3_muladd(&w2, &w1, &w0, ws[17], p[2]); + word3_muladd(&w2, &w1, &w0, ws[18], p[1]); + word3_add(&w2, &w1, &w0, z[19]); + ws[19] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[19], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[20]); + word3_muladd(&w2, &w1, &w0, ws[1], p[19]); + word3_muladd(&w2, &w1, &w0, ws[2], p[18]); + word3_muladd(&w2, &w1, &w0, ws[3], p[17]); + word3_muladd(&w2, &w1, &w0, ws[4], p[16]); + word3_muladd(&w2, &w1, &w0, ws[5], p[15]); + word3_muladd(&w2, &w1, &w0, ws[6], p[14]); + word3_muladd(&w2, &w1, &w0, ws[7], p[13]); + word3_muladd(&w2, &w1, &w0, ws[8], p[12]); + word3_muladd(&w2, &w1, &w0, ws[9], p[11]); + word3_muladd(&w2, &w1, &w0, ws[10], p[10]); + word3_muladd(&w2, &w1, &w0, ws[11], p[9]); + word3_muladd(&w2, &w1, &w0, ws[12], p[8]); + word3_muladd(&w2, &w1, &w0, ws[13], p[7]); + word3_muladd(&w2, &w1, &w0, ws[14], p[6]); + word3_muladd(&w2, &w1, &w0, ws[15], p[5]); + word3_muladd(&w2, &w1, &w0, ws[16], p[4]); + word3_muladd(&w2, &w1, &w0, ws[17], p[3]); + word3_muladd(&w2, &w1, &w0, ws[18], p[2]); + word3_muladd(&w2, &w1, &w0, ws[19], p[1]); + word3_add(&w2, &w1, &w0, z[20]); + ws[20] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[20], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[21]); + word3_muladd(&w2, &w1, &w0, ws[1], p[20]); + word3_muladd(&w2, &w1, &w0, ws[2], p[19]); + word3_muladd(&w2, &w1, &w0, ws[3], p[18]); + word3_muladd(&w2, &w1, &w0, ws[4], p[17]); + word3_muladd(&w2, &w1, &w0, ws[5], p[16]); + word3_muladd(&w2, &w1, &w0, ws[6], p[15]); + word3_muladd(&w2, &w1, &w0, ws[7], p[14]); + word3_muladd(&w2, &w1, &w0, ws[8], p[13]); + word3_muladd(&w2, &w1, &w0, ws[9], p[12]); + word3_muladd(&w2, &w1, &w0, ws[10], p[11]); + word3_muladd(&w2, &w1, &w0, ws[11], p[10]); + word3_muladd(&w2, &w1, &w0, ws[12], p[9]); + word3_muladd(&w2, &w1, &w0, ws[13], p[8]); + word3_muladd(&w2, &w1, &w0, ws[14], p[7]); + word3_muladd(&w2, &w1, &w0, ws[15], p[6]); + word3_muladd(&w2, &w1, &w0, ws[16], p[5]); + word3_muladd(&w2, &w1, &w0, ws[17], p[4]); + word3_muladd(&w2, &w1, &w0, ws[18], p[3]); + word3_muladd(&w2, &w1, &w0, ws[19], p[2]); + word3_muladd(&w2, &w1, &w0, ws[20], p[1]); + word3_add(&w2, &w1, &w0, z[21]); + ws[21] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[21], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[22]); + word3_muladd(&w2, &w1, &w0, ws[1], p[21]); + word3_muladd(&w2, &w1, &w0, ws[2], p[20]); + word3_muladd(&w2, &w1, &w0, ws[3], p[19]); + word3_muladd(&w2, &w1, &w0, ws[4], p[18]); + word3_muladd(&w2, &w1, &w0, ws[5], p[17]); + word3_muladd(&w2, &w1, &w0, ws[6], p[16]); + word3_muladd(&w2, &w1, &w0, ws[7], p[15]); + word3_muladd(&w2, &w1, &w0, ws[8], p[14]); + word3_muladd(&w2, &w1, &w0, ws[9], p[13]); + word3_muladd(&w2, &w1, &w0, ws[10], p[12]); + word3_muladd(&w2, &w1, &w0, ws[11], p[11]); + word3_muladd(&w2, &w1, &w0, ws[12], p[10]); + word3_muladd(&w2, &w1, &w0, ws[13], p[9]); + word3_muladd(&w2, &w1, &w0, ws[14], p[8]); + word3_muladd(&w2, &w1, &w0, ws[15], p[7]); + word3_muladd(&w2, &w1, &w0, ws[16], p[6]); + word3_muladd(&w2, &w1, &w0, ws[17], p[5]); + word3_muladd(&w2, &w1, &w0, ws[18], p[4]); + word3_muladd(&w2, &w1, &w0, ws[19], p[3]); + word3_muladd(&w2, &w1, &w0, ws[20], p[2]); + word3_muladd(&w2, &w1, &w0, ws[21], p[1]); + word3_add(&w2, &w1, &w0, z[22]); + ws[22] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[22], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[23]); + word3_muladd(&w2, &w1, &w0, ws[1], p[22]); + word3_muladd(&w2, &w1, &w0, ws[2], p[21]); + word3_muladd(&w2, &w1, &w0, ws[3], p[20]); + word3_muladd(&w2, &w1, &w0, ws[4], p[19]); + word3_muladd(&w2, &w1, &w0, ws[5], p[18]); + word3_muladd(&w2, &w1, &w0, ws[6], p[17]); + word3_muladd(&w2, &w1, &w0, ws[7], p[16]); + word3_muladd(&w2, &w1, &w0, ws[8], p[15]); + word3_muladd(&w2, &w1, &w0, ws[9], p[14]); + word3_muladd(&w2, &w1, &w0, ws[10], p[13]); + word3_muladd(&w2, &w1, &w0, ws[11], p[12]); + word3_muladd(&w2, &w1, &w0, ws[12], p[11]); + word3_muladd(&w2, &w1, &w0, ws[13], p[10]); + word3_muladd(&w2, &w1, &w0, ws[14], p[9]); + word3_muladd(&w2, &w1, &w0, ws[15], p[8]); + word3_muladd(&w2, &w1, &w0, ws[16], p[7]); + word3_muladd(&w2, &w1, &w0, ws[17], p[6]); + word3_muladd(&w2, &w1, &w0, ws[18], p[5]); + word3_muladd(&w2, &w1, &w0, ws[19], p[4]); + word3_muladd(&w2, &w1, &w0, ws[20], p[3]); + word3_muladd(&w2, &w1, &w0, ws[21], p[2]); + word3_muladd(&w2, &w1, &w0, ws[22], p[1]); + word3_add(&w2, &w1, &w0, z[23]); + ws[23] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[23], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[1], p[23]); + word3_muladd(&w2, &w1, &w0, ws[2], p[22]); + word3_muladd(&w2, &w1, &w0, ws[3], p[21]); + word3_muladd(&w2, &w1, &w0, ws[4], p[20]); + word3_muladd(&w2, &w1, &w0, ws[5], p[19]); + word3_muladd(&w2, &w1, &w0, ws[6], p[18]); + word3_muladd(&w2, &w1, &w0, ws[7], p[17]); + word3_muladd(&w2, &w1, &w0, ws[8], p[16]); + word3_muladd(&w2, &w1, &w0, ws[9], p[15]); + word3_muladd(&w2, &w1, &w0, ws[10], p[14]); + word3_muladd(&w2, &w1, &w0, ws[11], p[13]); + word3_muladd(&w2, &w1, &w0, ws[12], p[12]); + word3_muladd(&w2, &w1, &w0, ws[13], p[11]); + word3_muladd(&w2, &w1, &w0, ws[14], p[10]); + word3_muladd(&w2, &w1, &w0, ws[15], p[9]); + word3_muladd(&w2, &w1, &w0, ws[16], p[8]); + word3_muladd(&w2, &w1, &w0, ws[17], p[7]); + word3_muladd(&w2, &w1, &w0, ws[18], p[6]); + word3_muladd(&w2, &w1, &w0, ws[19], p[5]); + word3_muladd(&w2, &w1, &w0, ws[20], p[4]); + word3_muladd(&w2, &w1, &w0, ws[21], p[3]); + word3_muladd(&w2, &w1, &w0, ws[22], p[2]); + word3_muladd(&w2, &w1, &w0, ws[23], p[1]); + word3_add(&w2, &w1, &w0, z[24]); + ws[0] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[2], p[23]); + word3_muladd(&w2, &w1, &w0, ws[3], p[22]); + word3_muladd(&w2, &w1, &w0, ws[4], p[21]); + word3_muladd(&w2, &w1, &w0, ws[5], p[20]); + word3_muladd(&w2, &w1, &w0, ws[6], p[19]); + word3_muladd(&w2, &w1, &w0, ws[7], p[18]); + word3_muladd(&w2, &w1, &w0, ws[8], p[17]); + word3_muladd(&w2, &w1, &w0, ws[9], p[16]); + word3_muladd(&w2, &w1, &w0, ws[10], p[15]); + word3_muladd(&w2, &w1, &w0, ws[11], p[14]); + word3_muladd(&w2, &w1, &w0, ws[12], p[13]); + word3_muladd(&w2, &w1, &w0, ws[13], p[12]); + word3_muladd(&w2, &w1, &w0, ws[14], p[11]); + word3_muladd(&w2, &w1, &w0, ws[15], p[10]); + word3_muladd(&w2, &w1, &w0, ws[16], p[9]); + word3_muladd(&w2, &w1, &w0, ws[17], p[8]); + word3_muladd(&w2, &w1, &w0, ws[18], p[7]); + word3_muladd(&w2, &w1, &w0, ws[19], p[6]); + word3_muladd(&w2, &w1, &w0, ws[20], p[5]); + word3_muladd(&w2, &w1, &w0, ws[21], p[4]); + word3_muladd(&w2, &w1, &w0, ws[22], p[3]); + word3_muladd(&w2, &w1, &w0, ws[23], p[2]); + word3_add(&w2, &w1, &w0, z[25]); + ws[1] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[3], p[23]); + word3_muladd(&w2, &w1, &w0, ws[4], p[22]); + word3_muladd(&w2, &w1, &w0, ws[5], p[21]); + word3_muladd(&w2, &w1, &w0, ws[6], p[20]); + word3_muladd(&w2, &w1, &w0, ws[7], p[19]); + word3_muladd(&w2, &w1, &w0, ws[8], p[18]); + word3_muladd(&w2, &w1, &w0, ws[9], p[17]); + word3_muladd(&w2, &w1, &w0, ws[10], p[16]); + word3_muladd(&w2, &w1, &w0, ws[11], p[15]); + word3_muladd(&w2, &w1, &w0, ws[12], p[14]); + word3_muladd(&w2, &w1, &w0, ws[13], p[13]); + word3_muladd(&w2, &w1, &w0, ws[14], p[12]); + word3_muladd(&w2, &w1, &w0, ws[15], p[11]); + word3_muladd(&w2, &w1, &w0, ws[16], p[10]); + word3_muladd(&w2, &w1, &w0, ws[17], p[9]); + word3_muladd(&w2, &w1, &w0, ws[18], p[8]); + word3_muladd(&w2, &w1, &w0, ws[19], p[7]); + word3_muladd(&w2, &w1, &w0, ws[20], p[6]); + word3_muladd(&w2, &w1, &w0, ws[21], p[5]); + word3_muladd(&w2, &w1, &w0, ws[22], p[4]); + word3_muladd(&w2, &w1, &w0, ws[23], p[3]); + word3_add(&w2, &w1, &w0, z[26]); + ws[2] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[4], p[23]); + word3_muladd(&w2, &w1, &w0, ws[5], p[22]); + word3_muladd(&w2, &w1, &w0, ws[6], p[21]); + word3_muladd(&w2, &w1, &w0, ws[7], p[20]); + word3_muladd(&w2, &w1, &w0, ws[8], p[19]); + word3_muladd(&w2, &w1, &w0, ws[9], p[18]); + word3_muladd(&w2, &w1, &w0, ws[10], p[17]); + word3_muladd(&w2, &w1, &w0, ws[11], p[16]); + word3_muladd(&w2, &w1, &w0, ws[12], p[15]); + word3_muladd(&w2, &w1, &w0, ws[13], p[14]); + word3_muladd(&w2, &w1, &w0, ws[14], p[13]); + word3_muladd(&w2, &w1, &w0, ws[15], p[12]); + word3_muladd(&w2, &w1, &w0, ws[16], p[11]); + word3_muladd(&w2, &w1, &w0, ws[17], p[10]); + word3_muladd(&w2, &w1, &w0, ws[18], p[9]); + word3_muladd(&w2, &w1, &w0, ws[19], p[8]); + word3_muladd(&w2, &w1, &w0, ws[20], p[7]); + word3_muladd(&w2, &w1, &w0, ws[21], p[6]); + word3_muladd(&w2, &w1, &w0, ws[22], p[5]); + word3_muladd(&w2, &w1, &w0, ws[23], p[4]); + word3_add(&w2, &w1, &w0, z[27]); + ws[3] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[5], p[23]); + word3_muladd(&w2, &w1, &w0, ws[6], p[22]); + word3_muladd(&w2, &w1, &w0, ws[7], p[21]); + word3_muladd(&w2, &w1, &w0, ws[8], p[20]); + word3_muladd(&w2, &w1, &w0, ws[9], p[19]); + word3_muladd(&w2, &w1, &w0, ws[10], p[18]); + word3_muladd(&w2, &w1, &w0, ws[11], p[17]); + word3_muladd(&w2, &w1, &w0, ws[12], p[16]); + word3_muladd(&w2, &w1, &w0, ws[13], p[15]); + word3_muladd(&w2, &w1, &w0, ws[14], p[14]); + word3_muladd(&w2, &w1, &w0, ws[15], p[13]); + word3_muladd(&w2, &w1, &w0, ws[16], p[12]); + word3_muladd(&w2, &w1, &w0, ws[17], p[11]); + word3_muladd(&w2, &w1, &w0, ws[18], p[10]); + word3_muladd(&w2, &w1, &w0, ws[19], p[9]); + word3_muladd(&w2, &w1, &w0, ws[20], p[8]); + word3_muladd(&w2, &w1, &w0, ws[21], p[7]); + word3_muladd(&w2, &w1, &w0, ws[22], p[6]); + word3_muladd(&w2, &w1, &w0, ws[23], p[5]); + word3_add(&w2, &w1, &w0, z[28]); + ws[4] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[6], p[23]); + word3_muladd(&w2, &w1, &w0, ws[7], p[22]); + word3_muladd(&w2, &w1, &w0, ws[8], p[21]); + word3_muladd(&w2, &w1, &w0, ws[9], p[20]); + word3_muladd(&w2, &w1, &w0, ws[10], p[19]); + word3_muladd(&w2, &w1, &w0, ws[11], p[18]); + word3_muladd(&w2, &w1, &w0, ws[12], p[17]); + word3_muladd(&w2, &w1, &w0, ws[13], p[16]); + word3_muladd(&w2, &w1, &w0, ws[14], p[15]); + word3_muladd(&w2, &w1, &w0, ws[15], p[14]); + word3_muladd(&w2, &w1, &w0, ws[16], p[13]); + word3_muladd(&w2, &w1, &w0, ws[17], p[12]); + word3_muladd(&w2, &w1, &w0, ws[18], p[11]); + word3_muladd(&w2, &w1, &w0, ws[19], p[10]); + word3_muladd(&w2, &w1, &w0, ws[20], p[9]); + word3_muladd(&w2, &w1, &w0, ws[21], p[8]); + word3_muladd(&w2, &w1, &w0, ws[22], p[7]); + word3_muladd(&w2, &w1, &w0, ws[23], p[6]); + word3_add(&w2, &w1, &w0, z[29]); + ws[5] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[7], p[23]); + word3_muladd(&w2, &w1, &w0, ws[8], p[22]); + word3_muladd(&w2, &w1, &w0, ws[9], p[21]); + word3_muladd(&w2, &w1, &w0, ws[10], p[20]); + word3_muladd(&w2, &w1, &w0, ws[11], p[19]); + word3_muladd(&w2, &w1, &w0, ws[12], p[18]); + word3_muladd(&w2, &w1, &w0, ws[13], p[17]); + word3_muladd(&w2, &w1, &w0, ws[14], p[16]); + word3_muladd(&w2, &w1, &w0, ws[15], p[15]); + word3_muladd(&w2, &w1, &w0, ws[16], p[14]); + word3_muladd(&w2, &w1, &w0, ws[17], p[13]); + word3_muladd(&w2, &w1, &w0, ws[18], p[12]); + word3_muladd(&w2, &w1, &w0, ws[19], p[11]); + word3_muladd(&w2, &w1, &w0, ws[20], p[10]); + word3_muladd(&w2, &w1, &w0, ws[21], p[9]); + word3_muladd(&w2, &w1, &w0, ws[22], p[8]); + word3_muladd(&w2, &w1, &w0, ws[23], p[7]); + word3_add(&w2, &w1, &w0, z[30]); + ws[6] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[8], p[23]); + word3_muladd(&w2, &w1, &w0, ws[9], p[22]); + word3_muladd(&w2, &w1, &w0, ws[10], p[21]); + word3_muladd(&w2, &w1, &w0, ws[11], p[20]); + word3_muladd(&w2, &w1, &w0, ws[12], p[19]); + word3_muladd(&w2, &w1, &w0, ws[13], p[18]); + word3_muladd(&w2, &w1, &w0, ws[14], p[17]); + word3_muladd(&w2, &w1, &w0, ws[15], p[16]); + word3_muladd(&w2, &w1, &w0, ws[16], p[15]); + word3_muladd(&w2, &w1, &w0, ws[17], p[14]); + word3_muladd(&w2, &w1, &w0, ws[18], p[13]); + word3_muladd(&w2, &w1, &w0, ws[19], p[12]); + word3_muladd(&w2, &w1, &w0, ws[20], p[11]); + word3_muladd(&w2, &w1, &w0, ws[21], p[10]); + word3_muladd(&w2, &w1, &w0, ws[22], p[9]); + word3_muladd(&w2, &w1, &w0, ws[23], p[8]); + word3_add(&w2, &w1, &w0, z[31]); + ws[7] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[9], p[23]); + word3_muladd(&w2, &w1, &w0, ws[10], p[22]); + word3_muladd(&w2, &w1, &w0, ws[11], p[21]); + word3_muladd(&w2, &w1, &w0, ws[12], p[20]); + word3_muladd(&w2, &w1, &w0, ws[13], p[19]); + word3_muladd(&w2, &w1, &w0, ws[14], p[18]); + word3_muladd(&w2, &w1, &w0, ws[15], p[17]); + word3_muladd(&w2, &w1, &w0, ws[16], p[16]); + word3_muladd(&w2, &w1, &w0, ws[17], p[15]); + word3_muladd(&w2, &w1, &w0, ws[18], p[14]); + word3_muladd(&w2, &w1, &w0, ws[19], p[13]); + word3_muladd(&w2, &w1, &w0, ws[20], p[12]); + word3_muladd(&w2, &w1, &w0, ws[21], p[11]); + word3_muladd(&w2, &w1, &w0, ws[22], p[10]); + word3_muladd(&w2, &w1, &w0, ws[23], p[9]); + word3_add(&w2, &w1, &w0, z[32]); + ws[8] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[10], p[23]); + word3_muladd(&w2, &w1, &w0, ws[11], p[22]); + word3_muladd(&w2, &w1, &w0, ws[12], p[21]); + word3_muladd(&w2, &w1, &w0, ws[13], p[20]); + word3_muladd(&w2, &w1, &w0, ws[14], p[19]); + word3_muladd(&w2, &w1, &w0, ws[15], p[18]); + word3_muladd(&w2, &w1, &w0, ws[16], p[17]); + word3_muladd(&w2, &w1, &w0, ws[17], p[16]); + word3_muladd(&w2, &w1, &w0, ws[18], p[15]); + word3_muladd(&w2, &w1, &w0, ws[19], p[14]); + word3_muladd(&w2, &w1, &w0, ws[20], p[13]); + word3_muladd(&w2, &w1, &w0, ws[21], p[12]); + word3_muladd(&w2, &w1, &w0, ws[22], p[11]); + word3_muladd(&w2, &w1, &w0, ws[23], p[10]); + word3_add(&w2, &w1, &w0, z[33]); + ws[9] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[11], p[23]); + word3_muladd(&w2, &w1, &w0, ws[12], p[22]); + word3_muladd(&w2, &w1, &w0, ws[13], p[21]); + word3_muladd(&w2, &w1, &w0, ws[14], p[20]); + word3_muladd(&w2, &w1, &w0, ws[15], p[19]); + word3_muladd(&w2, &w1, &w0, ws[16], p[18]); + word3_muladd(&w2, &w1, &w0, ws[17], p[17]); + word3_muladd(&w2, &w1, &w0, ws[18], p[16]); + word3_muladd(&w2, &w1, &w0, ws[19], p[15]); + word3_muladd(&w2, &w1, &w0, ws[20], p[14]); + word3_muladd(&w2, &w1, &w0, ws[21], p[13]); + word3_muladd(&w2, &w1, &w0, ws[22], p[12]); + word3_muladd(&w2, &w1, &w0, ws[23], p[11]); + word3_add(&w2, &w1, &w0, z[34]); + ws[10] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[12], p[23]); + word3_muladd(&w2, &w1, &w0, ws[13], p[22]); + word3_muladd(&w2, &w1, &w0, ws[14], p[21]); + word3_muladd(&w2, &w1, &w0, ws[15], p[20]); + word3_muladd(&w2, &w1, &w0, ws[16], p[19]); + word3_muladd(&w2, &w1, &w0, ws[17], p[18]); + word3_muladd(&w2, &w1, &w0, ws[18], p[17]); + word3_muladd(&w2, &w1, &w0, ws[19], p[16]); + word3_muladd(&w2, &w1, &w0, ws[20], p[15]); + word3_muladd(&w2, &w1, &w0, ws[21], p[14]); + word3_muladd(&w2, &w1, &w0, ws[22], p[13]); + word3_muladd(&w2, &w1, &w0, ws[23], p[12]); + word3_add(&w2, &w1, &w0, z[35]); + ws[11] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[13], p[23]); + word3_muladd(&w2, &w1, &w0, ws[14], p[22]); + word3_muladd(&w2, &w1, &w0, ws[15], p[21]); + word3_muladd(&w2, &w1, &w0, ws[16], p[20]); + word3_muladd(&w2, &w1, &w0, ws[17], p[19]); + word3_muladd(&w2, &w1, &w0, ws[18], p[18]); + word3_muladd(&w2, &w1, &w0, ws[19], p[17]); + word3_muladd(&w2, &w1, &w0, ws[20], p[16]); + word3_muladd(&w2, &w1, &w0, ws[21], p[15]); + word3_muladd(&w2, &w1, &w0, ws[22], p[14]); + word3_muladd(&w2, &w1, &w0, ws[23], p[13]); + word3_add(&w2, &w1, &w0, z[36]); + ws[12] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[14], p[23]); + word3_muladd(&w2, &w1, &w0, ws[15], p[22]); + word3_muladd(&w2, &w1, &w0, ws[16], p[21]); + word3_muladd(&w2, &w1, &w0, ws[17], p[20]); + word3_muladd(&w2, &w1, &w0, ws[18], p[19]); + word3_muladd(&w2, &w1, &w0, ws[19], p[18]); + word3_muladd(&w2, &w1, &w0, ws[20], p[17]); + word3_muladd(&w2, &w1, &w0, ws[21], p[16]); + word3_muladd(&w2, &w1, &w0, ws[22], p[15]); + word3_muladd(&w2, &w1, &w0, ws[23], p[14]); + word3_add(&w2, &w1, &w0, z[37]); + ws[13] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[15], p[23]); + word3_muladd(&w2, &w1, &w0, ws[16], p[22]); + word3_muladd(&w2, &w1, &w0, ws[17], p[21]); + word3_muladd(&w2, &w1, &w0, ws[18], p[20]); + word3_muladd(&w2, &w1, &w0, ws[19], p[19]); + word3_muladd(&w2, &w1, &w0, ws[20], p[18]); + word3_muladd(&w2, &w1, &w0, ws[21], p[17]); + word3_muladd(&w2, &w1, &w0, ws[22], p[16]); + word3_muladd(&w2, &w1, &w0, ws[23], p[15]); + word3_add(&w2, &w1, &w0, z[38]); + ws[14] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[16], p[23]); + word3_muladd(&w2, &w1, &w0, ws[17], p[22]); + word3_muladd(&w2, &w1, &w0, ws[18], p[21]); + word3_muladd(&w2, &w1, &w0, ws[19], p[20]); + word3_muladd(&w2, &w1, &w0, ws[20], p[19]); + word3_muladd(&w2, &w1, &w0, ws[21], p[18]); + word3_muladd(&w2, &w1, &w0, ws[22], p[17]); + word3_muladd(&w2, &w1, &w0, ws[23], p[16]); + word3_add(&w2, &w1, &w0, z[39]); + ws[15] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[17], p[23]); + word3_muladd(&w2, &w1, &w0, ws[18], p[22]); + word3_muladd(&w2, &w1, &w0, ws[19], p[21]); + word3_muladd(&w2, &w1, &w0, ws[20], p[20]); + word3_muladd(&w2, &w1, &w0, ws[21], p[19]); + word3_muladd(&w2, &w1, &w0, ws[22], p[18]); + word3_muladd(&w2, &w1, &w0, ws[23], p[17]); + word3_add(&w2, &w1, &w0, z[40]); + ws[16] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[18], p[23]); + word3_muladd(&w2, &w1, &w0, ws[19], p[22]); + word3_muladd(&w2, &w1, &w0, ws[20], p[21]); + word3_muladd(&w2, &w1, &w0, ws[21], p[20]); + word3_muladd(&w2, &w1, &w0, ws[22], p[19]); + word3_muladd(&w2, &w1, &w0, ws[23], p[18]); + word3_add(&w2, &w1, &w0, z[41]); + ws[17] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[19], p[23]); + word3_muladd(&w2, &w1, &w0, ws[20], p[22]); + word3_muladd(&w2, &w1, &w0, ws[21], p[21]); + word3_muladd(&w2, &w1, &w0, ws[22], p[20]); + word3_muladd(&w2, &w1, &w0, ws[23], p[19]); + word3_add(&w2, &w1, &w0, z[42]); + ws[18] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[20], p[23]); + word3_muladd(&w2, &w1, &w0, ws[21], p[22]); + word3_muladd(&w2, &w1, &w0, ws[22], p[21]); + word3_muladd(&w2, &w1, &w0, ws[23], p[20]); + word3_add(&w2, &w1, &w0, z[43]); + ws[19] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[21], p[23]); + word3_muladd(&w2, &w1, &w0, ws[22], p[22]); + word3_muladd(&w2, &w1, &w0, ws[23], p[21]); + word3_add(&w2, &w1, &w0, z[44]); + ws[20] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[22], p[23]); + word3_muladd(&w2, &w1, &w0, ws[23], p[22]); + word3_add(&w2, &w1, &w0, z[45]); + ws[21] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[23], p[23]); + word3_add(&w2, &w1, &w0, z[46]); + ws[22] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_add(&w2, &w1, &w0, z[47]); + ws[23] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_add(&w2, &w1, &w0, z[49]); + ws[24] = w0; + ws[25] = w1; + word borrow = bigint_sub3(ws + 24 + 1, ws, 24 + 1, p, 24); + CT::conditional_copy_mem(borrow, z, ws, ws + 25, 25); + clear_mem(z + 24, 2*(24+1) - 24); + } + +void bigint_monty_redc_32(word z[], const word p[32], word p_dash, word ws[]) + { + word w2 = 0, w1 = 0, w0 = 0; + w0 = z[0]; + ws[0] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[0], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[1]); + word3_add(&w2, &w1, &w0, z[1]); + ws[1] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[1], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[2]); + word3_muladd(&w2, &w1, &w0, ws[1], p[1]); + word3_add(&w2, &w1, &w0, z[2]); + ws[2] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[2], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[3]); + word3_muladd(&w2, &w1, &w0, ws[1], p[2]); + word3_muladd(&w2, &w1, &w0, ws[2], p[1]); + word3_add(&w2, &w1, &w0, z[3]); + ws[3] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[3], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[4]); + word3_muladd(&w2, &w1, &w0, ws[1], p[3]); + word3_muladd(&w2, &w1, &w0, ws[2], p[2]); + word3_muladd(&w2, &w1, &w0, ws[3], p[1]); + word3_add(&w2, &w1, &w0, z[4]); + ws[4] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[4], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[5]); + word3_muladd(&w2, &w1, &w0, ws[1], p[4]); + word3_muladd(&w2, &w1, &w0, ws[2], p[3]); + word3_muladd(&w2, &w1, &w0, ws[3], p[2]); + word3_muladd(&w2, &w1, &w0, ws[4], p[1]); + word3_add(&w2, &w1, &w0, z[5]); + ws[5] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[5], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[6]); + word3_muladd(&w2, &w1, &w0, ws[1], p[5]); + word3_muladd(&w2, &w1, &w0, ws[2], p[4]); + word3_muladd(&w2, &w1, &w0, ws[3], p[3]); + word3_muladd(&w2, &w1, &w0, ws[4], p[2]); + word3_muladd(&w2, &w1, &w0, ws[5], p[1]); + word3_add(&w2, &w1, &w0, z[6]); + ws[6] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[6], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[7]); + word3_muladd(&w2, &w1, &w0, ws[1], p[6]); + word3_muladd(&w2, &w1, &w0, ws[2], p[5]); + word3_muladd(&w2, &w1, &w0, ws[3], p[4]); + word3_muladd(&w2, &w1, &w0, ws[4], p[3]); + word3_muladd(&w2, &w1, &w0, ws[5], p[2]); + word3_muladd(&w2, &w1, &w0, ws[6], p[1]); + word3_add(&w2, &w1, &w0, z[7]); + ws[7] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[7], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[8]); + word3_muladd(&w2, &w1, &w0, ws[1], p[7]); + word3_muladd(&w2, &w1, &w0, ws[2], p[6]); + word3_muladd(&w2, &w1, &w0, ws[3], p[5]); + word3_muladd(&w2, &w1, &w0, ws[4], p[4]); + word3_muladd(&w2, &w1, &w0, ws[5], p[3]); + word3_muladd(&w2, &w1, &w0, ws[6], p[2]); + word3_muladd(&w2, &w1, &w0, ws[7], p[1]); + word3_add(&w2, &w1, &w0, z[8]); + ws[8] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[8], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[9]); + word3_muladd(&w2, &w1, &w0, ws[1], p[8]); + word3_muladd(&w2, &w1, &w0, ws[2], p[7]); + word3_muladd(&w2, &w1, &w0, ws[3], p[6]); + word3_muladd(&w2, &w1, &w0, ws[4], p[5]); + word3_muladd(&w2, &w1, &w0, ws[5], p[4]); + word3_muladd(&w2, &w1, &w0, ws[6], p[3]); + word3_muladd(&w2, &w1, &w0, ws[7], p[2]); + word3_muladd(&w2, &w1, &w0, ws[8], p[1]); + word3_add(&w2, &w1, &w0, z[9]); + ws[9] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[9], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[10]); + word3_muladd(&w2, &w1, &w0, ws[1], p[9]); + word3_muladd(&w2, &w1, &w0, ws[2], p[8]); + word3_muladd(&w2, &w1, &w0, ws[3], p[7]); + word3_muladd(&w2, &w1, &w0, ws[4], p[6]); + word3_muladd(&w2, &w1, &w0, ws[5], p[5]); + word3_muladd(&w2, &w1, &w0, ws[6], p[4]); + word3_muladd(&w2, &w1, &w0, ws[7], p[3]); + word3_muladd(&w2, &w1, &w0, ws[8], p[2]); + word3_muladd(&w2, &w1, &w0, ws[9], p[1]); + word3_add(&w2, &w1, &w0, z[10]); + ws[10] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[10], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[11]); + word3_muladd(&w2, &w1, &w0, ws[1], p[10]); + word3_muladd(&w2, &w1, &w0, ws[2], p[9]); + word3_muladd(&w2, &w1, &w0, ws[3], p[8]); + word3_muladd(&w2, &w1, &w0, ws[4], p[7]); + word3_muladd(&w2, &w1, &w0, ws[5], p[6]); + word3_muladd(&w2, &w1, &w0, ws[6], p[5]); + word3_muladd(&w2, &w1, &w0, ws[7], p[4]); + word3_muladd(&w2, &w1, &w0, ws[8], p[3]); + word3_muladd(&w2, &w1, &w0, ws[9], p[2]); + word3_muladd(&w2, &w1, &w0, ws[10], p[1]); + word3_add(&w2, &w1, &w0, z[11]); + ws[11] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[11], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[12]); + word3_muladd(&w2, &w1, &w0, ws[1], p[11]); + word3_muladd(&w2, &w1, &w0, ws[2], p[10]); + word3_muladd(&w2, &w1, &w0, ws[3], p[9]); + word3_muladd(&w2, &w1, &w0, ws[4], p[8]); + word3_muladd(&w2, &w1, &w0, ws[5], p[7]); + word3_muladd(&w2, &w1, &w0, ws[6], p[6]); + word3_muladd(&w2, &w1, &w0, ws[7], p[5]); + word3_muladd(&w2, &w1, &w0, ws[8], p[4]); + word3_muladd(&w2, &w1, &w0, ws[9], p[3]); + word3_muladd(&w2, &w1, &w0, ws[10], p[2]); + word3_muladd(&w2, &w1, &w0, ws[11], p[1]); + word3_add(&w2, &w1, &w0, z[12]); + ws[12] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[12], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[13]); + word3_muladd(&w2, &w1, &w0, ws[1], p[12]); + word3_muladd(&w2, &w1, &w0, ws[2], p[11]); + word3_muladd(&w2, &w1, &w0, ws[3], p[10]); + word3_muladd(&w2, &w1, &w0, ws[4], p[9]); + word3_muladd(&w2, &w1, &w0, ws[5], p[8]); + word3_muladd(&w2, &w1, &w0, ws[6], p[7]); + word3_muladd(&w2, &w1, &w0, ws[7], p[6]); + word3_muladd(&w2, &w1, &w0, ws[8], p[5]); + word3_muladd(&w2, &w1, &w0, ws[9], p[4]); + word3_muladd(&w2, &w1, &w0, ws[10], p[3]); + word3_muladd(&w2, &w1, &w0, ws[11], p[2]); + word3_muladd(&w2, &w1, &w0, ws[12], p[1]); + word3_add(&w2, &w1, &w0, z[13]); + ws[13] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[13], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[14]); + word3_muladd(&w2, &w1, &w0, ws[1], p[13]); + word3_muladd(&w2, &w1, &w0, ws[2], p[12]); + word3_muladd(&w2, &w1, &w0, ws[3], p[11]); + word3_muladd(&w2, &w1, &w0, ws[4], p[10]); + word3_muladd(&w2, &w1, &w0, ws[5], p[9]); + word3_muladd(&w2, &w1, &w0, ws[6], p[8]); + word3_muladd(&w2, &w1, &w0, ws[7], p[7]); + word3_muladd(&w2, &w1, &w0, ws[8], p[6]); + word3_muladd(&w2, &w1, &w0, ws[9], p[5]); + word3_muladd(&w2, &w1, &w0, ws[10], p[4]); + word3_muladd(&w2, &w1, &w0, ws[11], p[3]); + word3_muladd(&w2, &w1, &w0, ws[12], p[2]); + word3_muladd(&w2, &w1, &w0, ws[13], p[1]); + word3_add(&w2, &w1, &w0, z[14]); + ws[14] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[14], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[15]); + word3_muladd(&w2, &w1, &w0, ws[1], p[14]); + word3_muladd(&w2, &w1, &w0, ws[2], p[13]); + word3_muladd(&w2, &w1, &w0, ws[3], p[12]); + word3_muladd(&w2, &w1, &w0, ws[4], p[11]); + word3_muladd(&w2, &w1, &w0, ws[5], p[10]); + word3_muladd(&w2, &w1, &w0, ws[6], p[9]); + word3_muladd(&w2, &w1, &w0, ws[7], p[8]); + word3_muladd(&w2, &w1, &w0, ws[8], p[7]); + word3_muladd(&w2, &w1, &w0, ws[9], p[6]); + word3_muladd(&w2, &w1, &w0, ws[10], p[5]); + word3_muladd(&w2, &w1, &w0, ws[11], p[4]); + word3_muladd(&w2, &w1, &w0, ws[12], p[3]); + word3_muladd(&w2, &w1, &w0, ws[13], p[2]); + word3_muladd(&w2, &w1, &w0, ws[14], p[1]); + word3_add(&w2, &w1, &w0, z[15]); + ws[15] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[15], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[16]); + word3_muladd(&w2, &w1, &w0, ws[1], p[15]); + word3_muladd(&w2, &w1, &w0, ws[2], p[14]); + word3_muladd(&w2, &w1, &w0, ws[3], p[13]); + word3_muladd(&w2, &w1, &w0, ws[4], p[12]); + word3_muladd(&w2, &w1, &w0, ws[5], p[11]); + word3_muladd(&w2, &w1, &w0, ws[6], p[10]); + word3_muladd(&w2, &w1, &w0, ws[7], p[9]); + word3_muladd(&w2, &w1, &w0, ws[8], p[8]); + word3_muladd(&w2, &w1, &w0, ws[9], p[7]); + word3_muladd(&w2, &w1, &w0, ws[10], p[6]); + word3_muladd(&w2, &w1, &w0, ws[11], p[5]); + word3_muladd(&w2, &w1, &w0, ws[12], p[4]); + word3_muladd(&w2, &w1, &w0, ws[13], p[3]); + word3_muladd(&w2, &w1, &w0, ws[14], p[2]); + word3_muladd(&w2, &w1, &w0, ws[15], p[1]); + word3_add(&w2, &w1, &w0, z[16]); + ws[16] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[16], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[17]); + word3_muladd(&w2, &w1, &w0, ws[1], p[16]); + word3_muladd(&w2, &w1, &w0, ws[2], p[15]); + word3_muladd(&w2, &w1, &w0, ws[3], p[14]); + word3_muladd(&w2, &w1, &w0, ws[4], p[13]); + word3_muladd(&w2, &w1, &w0, ws[5], p[12]); + word3_muladd(&w2, &w1, &w0, ws[6], p[11]); + word3_muladd(&w2, &w1, &w0, ws[7], p[10]); + word3_muladd(&w2, &w1, &w0, ws[8], p[9]); + word3_muladd(&w2, &w1, &w0, ws[9], p[8]); + word3_muladd(&w2, &w1, &w0, ws[10], p[7]); + word3_muladd(&w2, &w1, &w0, ws[11], p[6]); + word3_muladd(&w2, &w1, &w0, ws[12], p[5]); + word3_muladd(&w2, &w1, &w0, ws[13], p[4]); + word3_muladd(&w2, &w1, &w0, ws[14], p[3]); + word3_muladd(&w2, &w1, &w0, ws[15], p[2]); + word3_muladd(&w2, &w1, &w0, ws[16], p[1]); + word3_add(&w2, &w1, &w0, z[17]); + ws[17] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[17], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[18]); + word3_muladd(&w2, &w1, &w0, ws[1], p[17]); + word3_muladd(&w2, &w1, &w0, ws[2], p[16]); + word3_muladd(&w2, &w1, &w0, ws[3], p[15]); + word3_muladd(&w2, &w1, &w0, ws[4], p[14]); + word3_muladd(&w2, &w1, &w0, ws[5], p[13]); + word3_muladd(&w2, &w1, &w0, ws[6], p[12]); + word3_muladd(&w2, &w1, &w0, ws[7], p[11]); + word3_muladd(&w2, &w1, &w0, ws[8], p[10]); + word3_muladd(&w2, &w1, &w0, ws[9], p[9]); + word3_muladd(&w2, &w1, &w0, ws[10], p[8]); + word3_muladd(&w2, &w1, &w0, ws[11], p[7]); + word3_muladd(&w2, &w1, &w0, ws[12], p[6]); + word3_muladd(&w2, &w1, &w0, ws[13], p[5]); + word3_muladd(&w2, &w1, &w0, ws[14], p[4]); + word3_muladd(&w2, &w1, &w0, ws[15], p[3]); + word3_muladd(&w2, &w1, &w0, ws[16], p[2]); + word3_muladd(&w2, &w1, &w0, ws[17], p[1]); + word3_add(&w2, &w1, &w0, z[18]); + ws[18] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[18], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[19]); + word3_muladd(&w2, &w1, &w0, ws[1], p[18]); + word3_muladd(&w2, &w1, &w0, ws[2], p[17]); + word3_muladd(&w2, &w1, &w0, ws[3], p[16]); + word3_muladd(&w2, &w1, &w0, ws[4], p[15]); + word3_muladd(&w2, &w1, &w0, ws[5], p[14]); + word3_muladd(&w2, &w1, &w0, ws[6], p[13]); + word3_muladd(&w2, &w1, &w0, ws[7], p[12]); + word3_muladd(&w2, &w1, &w0, ws[8], p[11]); + word3_muladd(&w2, &w1, &w0, ws[9], p[10]); + word3_muladd(&w2, &w1, &w0, ws[10], p[9]); + word3_muladd(&w2, &w1, &w0, ws[11], p[8]); + word3_muladd(&w2, &w1, &w0, ws[12], p[7]); + word3_muladd(&w2, &w1, &w0, ws[13], p[6]); + word3_muladd(&w2, &w1, &w0, ws[14], p[5]); + word3_muladd(&w2, &w1, &w0, ws[15], p[4]); + word3_muladd(&w2, &w1, &w0, ws[16], p[3]); + word3_muladd(&w2, &w1, &w0, ws[17], p[2]); + word3_muladd(&w2, &w1, &w0, ws[18], p[1]); + word3_add(&w2, &w1, &w0, z[19]); + ws[19] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[19], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[20]); + word3_muladd(&w2, &w1, &w0, ws[1], p[19]); + word3_muladd(&w2, &w1, &w0, ws[2], p[18]); + word3_muladd(&w2, &w1, &w0, ws[3], p[17]); + word3_muladd(&w2, &w1, &w0, ws[4], p[16]); + word3_muladd(&w2, &w1, &w0, ws[5], p[15]); + word3_muladd(&w2, &w1, &w0, ws[6], p[14]); + word3_muladd(&w2, &w1, &w0, ws[7], p[13]); + word3_muladd(&w2, &w1, &w0, ws[8], p[12]); + word3_muladd(&w2, &w1, &w0, ws[9], p[11]); + word3_muladd(&w2, &w1, &w0, ws[10], p[10]); + word3_muladd(&w2, &w1, &w0, ws[11], p[9]); + word3_muladd(&w2, &w1, &w0, ws[12], p[8]); + word3_muladd(&w2, &w1, &w0, ws[13], p[7]); + word3_muladd(&w2, &w1, &w0, ws[14], p[6]); + word3_muladd(&w2, &w1, &w0, ws[15], p[5]); + word3_muladd(&w2, &w1, &w0, ws[16], p[4]); + word3_muladd(&w2, &w1, &w0, ws[17], p[3]); + word3_muladd(&w2, &w1, &w0, ws[18], p[2]); + word3_muladd(&w2, &w1, &w0, ws[19], p[1]); + word3_add(&w2, &w1, &w0, z[20]); + ws[20] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[20], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[21]); + word3_muladd(&w2, &w1, &w0, ws[1], p[20]); + word3_muladd(&w2, &w1, &w0, ws[2], p[19]); + word3_muladd(&w2, &w1, &w0, ws[3], p[18]); + word3_muladd(&w2, &w1, &w0, ws[4], p[17]); + word3_muladd(&w2, &w1, &w0, ws[5], p[16]); + word3_muladd(&w2, &w1, &w0, ws[6], p[15]); + word3_muladd(&w2, &w1, &w0, ws[7], p[14]); + word3_muladd(&w2, &w1, &w0, ws[8], p[13]); + word3_muladd(&w2, &w1, &w0, ws[9], p[12]); + word3_muladd(&w2, &w1, &w0, ws[10], p[11]); + word3_muladd(&w2, &w1, &w0, ws[11], p[10]); + word3_muladd(&w2, &w1, &w0, ws[12], p[9]); + word3_muladd(&w2, &w1, &w0, ws[13], p[8]); + word3_muladd(&w2, &w1, &w0, ws[14], p[7]); + word3_muladd(&w2, &w1, &w0, ws[15], p[6]); + word3_muladd(&w2, &w1, &w0, ws[16], p[5]); + word3_muladd(&w2, &w1, &w0, ws[17], p[4]); + word3_muladd(&w2, &w1, &w0, ws[18], p[3]); + word3_muladd(&w2, &w1, &w0, ws[19], p[2]); + word3_muladd(&w2, &w1, &w0, ws[20], p[1]); + word3_add(&w2, &w1, &w0, z[21]); + ws[21] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[21], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[22]); + word3_muladd(&w2, &w1, &w0, ws[1], p[21]); + word3_muladd(&w2, &w1, &w0, ws[2], p[20]); + word3_muladd(&w2, &w1, &w0, ws[3], p[19]); + word3_muladd(&w2, &w1, &w0, ws[4], p[18]); + word3_muladd(&w2, &w1, &w0, ws[5], p[17]); + word3_muladd(&w2, &w1, &w0, ws[6], p[16]); + word3_muladd(&w2, &w1, &w0, ws[7], p[15]); + word3_muladd(&w2, &w1, &w0, ws[8], p[14]); + word3_muladd(&w2, &w1, &w0, ws[9], p[13]); + word3_muladd(&w2, &w1, &w0, ws[10], p[12]); + word3_muladd(&w2, &w1, &w0, ws[11], p[11]); + word3_muladd(&w2, &w1, &w0, ws[12], p[10]); + word3_muladd(&w2, &w1, &w0, ws[13], p[9]); + word3_muladd(&w2, &w1, &w0, ws[14], p[8]); + word3_muladd(&w2, &w1, &w0, ws[15], p[7]); + word3_muladd(&w2, &w1, &w0, ws[16], p[6]); + word3_muladd(&w2, &w1, &w0, ws[17], p[5]); + word3_muladd(&w2, &w1, &w0, ws[18], p[4]); + word3_muladd(&w2, &w1, &w0, ws[19], p[3]); + word3_muladd(&w2, &w1, &w0, ws[20], p[2]); + word3_muladd(&w2, &w1, &w0, ws[21], p[1]); + word3_add(&w2, &w1, &w0, z[22]); + ws[22] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[22], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[23]); + word3_muladd(&w2, &w1, &w0, ws[1], p[22]); + word3_muladd(&w2, &w1, &w0, ws[2], p[21]); + word3_muladd(&w2, &w1, &w0, ws[3], p[20]); + word3_muladd(&w2, &w1, &w0, ws[4], p[19]); + word3_muladd(&w2, &w1, &w0, ws[5], p[18]); + word3_muladd(&w2, &w1, &w0, ws[6], p[17]); + word3_muladd(&w2, &w1, &w0, ws[7], p[16]); + word3_muladd(&w2, &w1, &w0, ws[8], p[15]); + word3_muladd(&w2, &w1, &w0, ws[9], p[14]); + word3_muladd(&w2, &w1, &w0, ws[10], p[13]); + word3_muladd(&w2, &w1, &w0, ws[11], p[12]); + word3_muladd(&w2, &w1, &w0, ws[12], p[11]); + word3_muladd(&w2, &w1, &w0, ws[13], p[10]); + word3_muladd(&w2, &w1, &w0, ws[14], p[9]); + word3_muladd(&w2, &w1, &w0, ws[15], p[8]); + word3_muladd(&w2, &w1, &w0, ws[16], p[7]); + word3_muladd(&w2, &w1, &w0, ws[17], p[6]); + word3_muladd(&w2, &w1, &w0, ws[18], p[5]); + word3_muladd(&w2, &w1, &w0, ws[19], p[4]); + word3_muladd(&w2, &w1, &w0, ws[20], p[3]); + word3_muladd(&w2, &w1, &w0, ws[21], p[2]); + word3_muladd(&w2, &w1, &w0, ws[22], p[1]); + word3_add(&w2, &w1, &w0, z[23]); + ws[23] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[23], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[24]); + word3_muladd(&w2, &w1, &w0, ws[1], p[23]); + word3_muladd(&w2, &w1, &w0, ws[2], p[22]); + word3_muladd(&w2, &w1, &w0, ws[3], p[21]); + word3_muladd(&w2, &w1, &w0, ws[4], p[20]); + word3_muladd(&w2, &w1, &w0, ws[5], p[19]); + word3_muladd(&w2, &w1, &w0, ws[6], p[18]); + word3_muladd(&w2, &w1, &w0, ws[7], p[17]); + word3_muladd(&w2, &w1, &w0, ws[8], p[16]); + word3_muladd(&w2, &w1, &w0, ws[9], p[15]); + word3_muladd(&w2, &w1, &w0, ws[10], p[14]); + word3_muladd(&w2, &w1, &w0, ws[11], p[13]); + word3_muladd(&w2, &w1, &w0, ws[12], p[12]); + word3_muladd(&w2, &w1, &w0, ws[13], p[11]); + word3_muladd(&w2, &w1, &w0, ws[14], p[10]); + word3_muladd(&w2, &w1, &w0, ws[15], p[9]); + word3_muladd(&w2, &w1, &w0, ws[16], p[8]); + word3_muladd(&w2, &w1, &w0, ws[17], p[7]); + word3_muladd(&w2, &w1, &w0, ws[18], p[6]); + word3_muladd(&w2, &w1, &w0, ws[19], p[5]); + word3_muladd(&w2, &w1, &w0, ws[20], p[4]); + word3_muladd(&w2, &w1, &w0, ws[21], p[3]); + word3_muladd(&w2, &w1, &w0, ws[22], p[2]); + word3_muladd(&w2, &w1, &w0, ws[23], p[1]); + word3_add(&w2, &w1, &w0, z[24]); + ws[24] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[24], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[25]); + word3_muladd(&w2, &w1, &w0, ws[1], p[24]); + word3_muladd(&w2, &w1, &w0, ws[2], p[23]); + word3_muladd(&w2, &w1, &w0, ws[3], p[22]); + word3_muladd(&w2, &w1, &w0, ws[4], p[21]); + word3_muladd(&w2, &w1, &w0, ws[5], p[20]); + word3_muladd(&w2, &w1, &w0, ws[6], p[19]); + word3_muladd(&w2, &w1, &w0, ws[7], p[18]); + word3_muladd(&w2, &w1, &w0, ws[8], p[17]); + word3_muladd(&w2, &w1, &w0, ws[9], p[16]); + word3_muladd(&w2, &w1, &w0, ws[10], p[15]); + word3_muladd(&w2, &w1, &w0, ws[11], p[14]); + word3_muladd(&w2, &w1, &w0, ws[12], p[13]); + word3_muladd(&w2, &w1, &w0, ws[13], p[12]); + word3_muladd(&w2, &w1, &w0, ws[14], p[11]); + word3_muladd(&w2, &w1, &w0, ws[15], p[10]); + word3_muladd(&w2, &w1, &w0, ws[16], p[9]); + word3_muladd(&w2, &w1, &w0, ws[17], p[8]); + word3_muladd(&w2, &w1, &w0, ws[18], p[7]); + word3_muladd(&w2, &w1, &w0, ws[19], p[6]); + word3_muladd(&w2, &w1, &w0, ws[20], p[5]); + word3_muladd(&w2, &w1, &w0, ws[21], p[4]); + word3_muladd(&w2, &w1, &w0, ws[22], p[3]); + word3_muladd(&w2, &w1, &w0, ws[23], p[2]); + word3_muladd(&w2, &w1, &w0, ws[24], p[1]); + word3_add(&w2, &w1, &w0, z[25]); + ws[25] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[25], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[26]); + word3_muladd(&w2, &w1, &w0, ws[1], p[25]); + word3_muladd(&w2, &w1, &w0, ws[2], p[24]); + word3_muladd(&w2, &w1, &w0, ws[3], p[23]); + word3_muladd(&w2, &w1, &w0, ws[4], p[22]); + word3_muladd(&w2, &w1, &w0, ws[5], p[21]); + word3_muladd(&w2, &w1, &w0, ws[6], p[20]); + word3_muladd(&w2, &w1, &w0, ws[7], p[19]); + word3_muladd(&w2, &w1, &w0, ws[8], p[18]); + word3_muladd(&w2, &w1, &w0, ws[9], p[17]); + word3_muladd(&w2, &w1, &w0, ws[10], p[16]); + word3_muladd(&w2, &w1, &w0, ws[11], p[15]); + word3_muladd(&w2, &w1, &w0, ws[12], p[14]); + word3_muladd(&w2, &w1, &w0, ws[13], p[13]); + word3_muladd(&w2, &w1, &w0, ws[14], p[12]); + word3_muladd(&w2, &w1, &w0, ws[15], p[11]); + word3_muladd(&w2, &w1, &w0, ws[16], p[10]); + word3_muladd(&w2, &w1, &w0, ws[17], p[9]); + word3_muladd(&w2, &w1, &w0, ws[18], p[8]); + word3_muladd(&w2, &w1, &w0, ws[19], p[7]); + word3_muladd(&w2, &w1, &w0, ws[20], p[6]); + word3_muladd(&w2, &w1, &w0, ws[21], p[5]); + word3_muladd(&w2, &w1, &w0, ws[22], p[4]); + word3_muladd(&w2, &w1, &w0, ws[23], p[3]); + word3_muladd(&w2, &w1, &w0, ws[24], p[2]); + word3_muladd(&w2, &w1, &w0, ws[25], p[1]); + word3_add(&w2, &w1, &w0, z[26]); + ws[26] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[26], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[27]); + word3_muladd(&w2, &w1, &w0, ws[1], p[26]); + word3_muladd(&w2, &w1, &w0, ws[2], p[25]); + word3_muladd(&w2, &w1, &w0, ws[3], p[24]); + word3_muladd(&w2, &w1, &w0, ws[4], p[23]); + word3_muladd(&w2, &w1, &w0, ws[5], p[22]); + word3_muladd(&w2, &w1, &w0, ws[6], p[21]); + word3_muladd(&w2, &w1, &w0, ws[7], p[20]); + word3_muladd(&w2, &w1, &w0, ws[8], p[19]); + word3_muladd(&w2, &w1, &w0, ws[9], p[18]); + word3_muladd(&w2, &w1, &w0, ws[10], p[17]); + word3_muladd(&w2, &w1, &w0, ws[11], p[16]); + word3_muladd(&w2, &w1, &w0, ws[12], p[15]); + word3_muladd(&w2, &w1, &w0, ws[13], p[14]); + word3_muladd(&w2, &w1, &w0, ws[14], p[13]); + word3_muladd(&w2, &w1, &w0, ws[15], p[12]); + word3_muladd(&w2, &w1, &w0, ws[16], p[11]); + word3_muladd(&w2, &w1, &w0, ws[17], p[10]); + word3_muladd(&w2, &w1, &w0, ws[18], p[9]); + word3_muladd(&w2, &w1, &w0, ws[19], p[8]); + word3_muladd(&w2, &w1, &w0, ws[20], p[7]); + word3_muladd(&w2, &w1, &w0, ws[21], p[6]); + word3_muladd(&w2, &w1, &w0, ws[22], p[5]); + word3_muladd(&w2, &w1, &w0, ws[23], p[4]); + word3_muladd(&w2, &w1, &w0, ws[24], p[3]); + word3_muladd(&w2, &w1, &w0, ws[25], p[2]); + word3_muladd(&w2, &w1, &w0, ws[26], p[1]); + word3_add(&w2, &w1, &w0, z[27]); + ws[27] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[27], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[28]); + word3_muladd(&w2, &w1, &w0, ws[1], p[27]); + word3_muladd(&w2, &w1, &w0, ws[2], p[26]); + word3_muladd(&w2, &w1, &w0, ws[3], p[25]); + word3_muladd(&w2, &w1, &w0, ws[4], p[24]); + word3_muladd(&w2, &w1, &w0, ws[5], p[23]); + word3_muladd(&w2, &w1, &w0, ws[6], p[22]); + word3_muladd(&w2, &w1, &w0, ws[7], p[21]); + word3_muladd(&w2, &w1, &w0, ws[8], p[20]); + word3_muladd(&w2, &w1, &w0, ws[9], p[19]); + word3_muladd(&w2, &w1, &w0, ws[10], p[18]); + word3_muladd(&w2, &w1, &w0, ws[11], p[17]); + word3_muladd(&w2, &w1, &w0, ws[12], p[16]); + word3_muladd(&w2, &w1, &w0, ws[13], p[15]); + word3_muladd(&w2, &w1, &w0, ws[14], p[14]); + word3_muladd(&w2, &w1, &w0, ws[15], p[13]); + word3_muladd(&w2, &w1, &w0, ws[16], p[12]); + word3_muladd(&w2, &w1, &w0, ws[17], p[11]); + word3_muladd(&w2, &w1, &w0, ws[18], p[10]); + word3_muladd(&w2, &w1, &w0, ws[19], p[9]); + word3_muladd(&w2, &w1, &w0, ws[20], p[8]); + word3_muladd(&w2, &w1, &w0, ws[21], p[7]); + word3_muladd(&w2, &w1, &w0, ws[22], p[6]); + word3_muladd(&w2, &w1, &w0, ws[23], p[5]); + word3_muladd(&w2, &w1, &w0, ws[24], p[4]); + word3_muladd(&w2, &w1, &w0, ws[25], p[3]); + word3_muladd(&w2, &w1, &w0, ws[26], p[2]); + word3_muladd(&w2, &w1, &w0, ws[27], p[1]); + word3_add(&w2, &w1, &w0, z[28]); + ws[28] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[28], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[29]); + word3_muladd(&w2, &w1, &w0, ws[1], p[28]); + word3_muladd(&w2, &w1, &w0, ws[2], p[27]); + word3_muladd(&w2, &w1, &w0, ws[3], p[26]); + word3_muladd(&w2, &w1, &w0, ws[4], p[25]); + word3_muladd(&w2, &w1, &w0, ws[5], p[24]); + word3_muladd(&w2, &w1, &w0, ws[6], p[23]); + word3_muladd(&w2, &w1, &w0, ws[7], p[22]); + word3_muladd(&w2, &w1, &w0, ws[8], p[21]); + word3_muladd(&w2, &w1, &w0, ws[9], p[20]); + word3_muladd(&w2, &w1, &w0, ws[10], p[19]); + word3_muladd(&w2, &w1, &w0, ws[11], p[18]); + word3_muladd(&w2, &w1, &w0, ws[12], p[17]); + word3_muladd(&w2, &w1, &w0, ws[13], p[16]); + word3_muladd(&w2, &w1, &w0, ws[14], p[15]); + word3_muladd(&w2, &w1, &w0, ws[15], p[14]); + word3_muladd(&w2, &w1, &w0, ws[16], p[13]); + word3_muladd(&w2, &w1, &w0, ws[17], p[12]); + word3_muladd(&w2, &w1, &w0, ws[18], p[11]); + word3_muladd(&w2, &w1, &w0, ws[19], p[10]); + word3_muladd(&w2, &w1, &w0, ws[20], p[9]); + word3_muladd(&w2, &w1, &w0, ws[21], p[8]); + word3_muladd(&w2, &w1, &w0, ws[22], p[7]); + word3_muladd(&w2, &w1, &w0, ws[23], p[6]); + word3_muladd(&w2, &w1, &w0, ws[24], p[5]); + word3_muladd(&w2, &w1, &w0, ws[25], p[4]); + word3_muladd(&w2, &w1, &w0, ws[26], p[3]); + word3_muladd(&w2, &w1, &w0, ws[27], p[2]); + word3_muladd(&w2, &w1, &w0, ws[28], p[1]); + word3_add(&w2, &w1, &w0, z[29]); + ws[29] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[29], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[30]); + word3_muladd(&w2, &w1, &w0, ws[1], p[29]); + word3_muladd(&w2, &w1, &w0, ws[2], p[28]); + word3_muladd(&w2, &w1, &w0, ws[3], p[27]); + word3_muladd(&w2, &w1, &w0, ws[4], p[26]); + word3_muladd(&w2, &w1, &w0, ws[5], p[25]); + word3_muladd(&w2, &w1, &w0, ws[6], p[24]); + word3_muladd(&w2, &w1, &w0, ws[7], p[23]); + word3_muladd(&w2, &w1, &w0, ws[8], p[22]); + word3_muladd(&w2, &w1, &w0, ws[9], p[21]); + word3_muladd(&w2, &w1, &w0, ws[10], p[20]); + word3_muladd(&w2, &w1, &w0, ws[11], p[19]); + word3_muladd(&w2, &w1, &w0, ws[12], p[18]); + word3_muladd(&w2, &w1, &w0, ws[13], p[17]); + word3_muladd(&w2, &w1, &w0, ws[14], p[16]); + word3_muladd(&w2, &w1, &w0, ws[15], p[15]); + word3_muladd(&w2, &w1, &w0, ws[16], p[14]); + word3_muladd(&w2, &w1, &w0, ws[17], p[13]); + word3_muladd(&w2, &w1, &w0, ws[18], p[12]); + word3_muladd(&w2, &w1, &w0, ws[19], p[11]); + word3_muladd(&w2, &w1, &w0, ws[20], p[10]); + word3_muladd(&w2, &w1, &w0, ws[21], p[9]); + word3_muladd(&w2, &w1, &w0, ws[22], p[8]); + word3_muladd(&w2, &w1, &w0, ws[23], p[7]); + word3_muladd(&w2, &w1, &w0, ws[24], p[6]); + word3_muladd(&w2, &w1, &w0, ws[25], p[5]); + word3_muladd(&w2, &w1, &w0, ws[26], p[4]); + word3_muladd(&w2, &w1, &w0, ws[27], p[3]); + word3_muladd(&w2, &w1, &w0, ws[28], p[2]); + word3_muladd(&w2, &w1, &w0, ws[29], p[1]); + word3_add(&w2, &w1, &w0, z[30]); + ws[30] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[30], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[0], p[31]); + word3_muladd(&w2, &w1, &w0, ws[1], p[30]); + word3_muladd(&w2, &w1, &w0, ws[2], p[29]); + word3_muladd(&w2, &w1, &w0, ws[3], p[28]); + word3_muladd(&w2, &w1, &w0, ws[4], p[27]); + word3_muladd(&w2, &w1, &w0, ws[5], p[26]); + word3_muladd(&w2, &w1, &w0, ws[6], p[25]); + word3_muladd(&w2, &w1, &w0, ws[7], p[24]); + word3_muladd(&w2, &w1, &w0, ws[8], p[23]); + word3_muladd(&w2, &w1, &w0, ws[9], p[22]); + word3_muladd(&w2, &w1, &w0, ws[10], p[21]); + word3_muladd(&w2, &w1, &w0, ws[11], p[20]); + word3_muladd(&w2, &w1, &w0, ws[12], p[19]); + word3_muladd(&w2, &w1, &w0, ws[13], p[18]); + word3_muladd(&w2, &w1, &w0, ws[14], p[17]); + word3_muladd(&w2, &w1, &w0, ws[15], p[16]); + word3_muladd(&w2, &w1, &w0, ws[16], p[15]); + word3_muladd(&w2, &w1, &w0, ws[17], p[14]); + word3_muladd(&w2, &w1, &w0, ws[18], p[13]); + word3_muladd(&w2, &w1, &w0, ws[19], p[12]); + word3_muladd(&w2, &w1, &w0, ws[20], p[11]); + word3_muladd(&w2, &w1, &w0, ws[21], p[10]); + word3_muladd(&w2, &w1, &w0, ws[22], p[9]); + word3_muladd(&w2, &w1, &w0, ws[23], p[8]); + word3_muladd(&w2, &w1, &w0, ws[24], p[7]); + word3_muladd(&w2, &w1, &w0, ws[25], p[6]); + word3_muladd(&w2, &w1, &w0, ws[26], p[5]); + word3_muladd(&w2, &w1, &w0, ws[27], p[4]); + word3_muladd(&w2, &w1, &w0, ws[28], p[3]); + word3_muladd(&w2, &w1, &w0, ws[29], p[2]); + word3_muladd(&w2, &w1, &w0, ws[30], p[1]); + word3_add(&w2, &w1, &w0, z[31]); + ws[31] = w0 * p_dash; + word3_muladd(&w2, &w1, &w0, ws[31], p[0]); + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[1], p[31]); + word3_muladd(&w2, &w1, &w0, ws[2], p[30]); + word3_muladd(&w2, &w1, &w0, ws[3], p[29]); + word3_muladd(&w2, &w1, &w0, ws[4], p[28]); + word3_muladd(&w2, &w1, &w0, ws[5], p[27]); + word3_muladd(&w2, &w1, &w0, ws[6], p[26]); + word3_muladd(&w2, &w1, &w0, ws[7], p[25]); + word3_muladd(&w2, &w1, &w0, ws[8], p[24]); + word3_muladd(&w2, &w1, &w0, ws[9], p[23]); + word3_muladd(&w2, &w1, &w0, ws[10], p[22]); + word3_muladd(&w2, &w1, &w0, ws[11], p[21]); + word3_muladd(&w2, &w1, &w0, ws[12], p[20]); + word3_muladd(&w2, &w1, &w0, ws[13], p[19]); + word3_muladd(&w2, &w1, &w0, ws[14], p[18]); + word3_muladd(&w2, &w1, &w0, ws[15], p[17]); + word3_muladd(&w2, &w1, &w0, ws[16], p[16]); + word3_muladd(&w2, &w1, &w0, ws[17], p[15]); + word3_muladd(&w2, &w1, &w0, ws[18], p[14]); + word3_muladd(&w2, &w1, &w0, ws[19], p[13]); + word3_muladd(&w2, &w1, &w0, ws[20], p[12]); + word3_muladd(&w2, &w1, &w0, ws[21], p[11]); + word3_muladd(&w2, &w1, &w0, ws[22], p[10]); + word3_muladd(&w2, &w1, &w0, ws[23], p[9]); + word3_muladd(&w2, &w1, &w0, ws[24], p[8]); + word3_muladd(&w2, &w1, &w0, ws[25], p[7]); + word3_muladd(&w2, &w1, &w0, ws[26], p[6]); + word3_muladd(&w2, &w1, &w0, ws[27], p[5]); + word3_muladd(&w2, &w1, &w0, ws[28], p[4]); + word3_muladd(&w2, &w1, &w0, ws[29], p[3]); + word3_muladd(&w2, &w1, &w0, ws[30], p[2]); + word3_muladd(&w2, &w1, &w0, ws[31], p[1]); + word3_add(&w2, &w1, &w0, z[32]); + ws[0] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[2], p[31]); + word3_muladd(&w2, &w1, &w0, ws[3], p[30]); + word3_muladd(&w2, &w1, &w0, ws[4], p[29]); + word3_muladd(&w2, &w1, &w0, ws[5], p[28]); + word3_muladd(&w2, &w1, &w0, ws[6], p[27]); + word3_muladd(&w2, &w1, &w0, ws[7], p[26]); + word3_muladd(&w2, &w1, &w0, ws[8], p[25]); + word3_muladd(&w2, &w1, &w0, ws[9], p[24]); + word3_muladd(&w2, &w1, &w0, ws[10], p[23]); + word3_muladd(&w2, &w1, &w0, ws[11], p[22]); + word3_muladd(&w2, &w1, &w0, ws[12], p[21]); + word3_muladd(&w2, &w1, &w0, ws[13], p[20]); + word3_muladd(&w2, &w1, &w0, ws[14], p[19]); + word3_muladd(&w2, &w1, &w0, ws[15], p[18]); + word3_muladd(&w2, &w1, &w0, ws[16], p[17]); + word3_muladd(&w2, &w1, &w0, ws[17], p[16]); + word3_muladd(&w2, &w1, &w0, ws[18], p[15]); + word3_muladd(&w2, &w1, &w0, ws[19], p[14]); + word3_muladd(&w2, &w1, &w0, ws[20], p[13]); + word3_muladd(&w2, &w1, &w0, ws[21], p[12]); + word3_muladd(&w2, &w1, &w0, ws[22], p[11]); + word3_muladd(&w2, &w1, &w0, ws[23], p[10]); + word3_muladd(&w2, &w1, &w0, ws[24], p[9]); + word3_muladd(&w2, &w1, &w0, ws[25], p[8]); + word3_muladd(&w2, &w1, &w0, ws[26], p[7]); + word3_muladd(&w2, &w1, &w0, ws[27], p[6]); + word3_muladd(&w2, &w1, &w0, ws[28], p[5]); + word3_muladd(&w2, &w1, &w0, ws[29], p[4]); + word3_muladd(&w2, &w1, &w0, ws[30], p[3]); + word3_muladd(&w2, &w1, &w0, ws[31], p[2]); + word3_add(&w2, &w1, &w0, z[33]); + ws[1] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[3], p[31]); + word3_muladd(&w2, &w1, &w0, ws[4], p[30]); + word3_muladd(&w2, &w1, &w0, ws[5], p[29]); + word3_muladd(&w2, &w1, &w0, ws[6], p[28]); + word3_muladd(&w2, &w1, &w0, ws[7], p[27]); + word3_muladd(&w2, &w1, &w0, ws[8], p[26]); + word3_muladd(&w2, &w1, &w0, ws[9], p[25]); + word3_muladd(&w2, &w1, &w0, ws[10], p[24]); + word3_muladd(&w2, &w1, &w0, ws[11], p[23]); + word3_muladd(&w2, &w1, &w0, ws[12], p[22]); + word3_muladd(&w2, &w1, &w0, ws[13], p[21]); + word3_muladd(&w2, &w1, &w0, ws[14], p[20]); + word3_muladd(&w2, &w1, &w0, ws[15], p[19]); + word3_muladd(&w2, &w1, &w0, ws[16], p[18]); + word3_muladd(&w2, &w1, &w0, ws[17], p[17]); + word3_muladd(&w2, &w1, &w0, ws[18], p[16]); + word3_muladd(&w2, &w1, &w0, ws[19], p[15]); + word3_muladd(&w2, &w1, &w0, ws[20], p[14]); + word3_muladd(&w2, &w1, &w0, ws[21], p[13]); + word3_muladd(&w2, &w1, &w0, ws[22], p[12]); + word3_muladd(&w2, &w1, &w0, ws[23], p[11]); + word3_muladd(&w2, &w1, &w0, ws[24], p[10]); + word3_muladd(&w2, &w1, &w0, ws[25], p[9]); + word3_muladd(&w2, &w1, &w0, ws[26], p[8]); + word3_muladd(&w2, &w1, &w0, ws[27], p[7]); + word3_muladd(&w2, &w1, &w0, ws[28], p[6]); + word3_muladd(&w2, &w1, &w0, ws[29], p[5]); + word3_muladd(&w2, &w1, &w0, ws[30], p[4]); + word3_muladd(&w2, &w1, &w0, ws[31], p[3]); + word3_add(&w2, &w1, &w0, z[34]); + ws[2] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[4], p[31]); + word3_muladd(&w2, &w1, &w0, ws[5], p[30]); + word3_muladd(&w2, &w1, &w0, ws[6], p[29]); + word3_muladd(&w2, &w1, &w0, ws[7], p[28]); + word3_muladd(&w2, &w1, &w0, ws[8], p[27]); + word3_muladd(&w2, &w1, &w0, ws[9], p[26]); + word3_muladd(&w2, &w1, &w0, ws[10], p[25]); + word3_muladd(&w2, &w1, &w0, ws[11], p[24]); + word3_muladd(&w2, &w1, &w0, ws[12], p[23]); + word3_muladd(&w2, &w1, &w0, ws[13], p[22]); + word3_muladd(&w2, &w1, &w0, ws[14], p[21]); + word3_muladd(&w2, &w1, &w0, ws[15], p[20]); + word3_muladd(&w2, &w1, &w0, ws[16], p[19]); + word3_muladd(&w2, &w1, &w0, ws[17], p[18]); + word3_muladd(&w2, &w1, &w0, ws[18], p[17]); + word3_muladd(&w2, &w1, &w0, ws[19], p[16]); + word3_muladd(&w2, &w1, &w0, ws[20], p[15]); + word3_muladd(&w2, &w1, &w0, ws[21], p[14]); + word3_muladd(&w2, &w1, &w0, ws[22], p[13]); + word3_muladd(&w2, &w1, &w0, ws[23], p[12]); + word3_muladd(&w2, &w1, &w0, ws[24], p[11]); + word3_muladd(&w2, &w1, &w0, ws[25], p[10]); + word3_muladd(&w2, &w1, &w0, ws[26], p[9]); + word3_muladd(&w2, &w1, &w0, ws[27], p[8]); + word3_muladd(&w2, &w1, &w0, ws[28], p[7]); + word3_muladd(&w2, &w1, &w0, ws[29], p[6]); + word3_muladd(&w2, &w1, &w0, ws[30], p[5]); + word3_muladd(&w2, &w1, &w0, ws[31], p[4]); + word3_add(&w2, &w1, &w0, z[35]); + ws[3] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[5], p[31]); + word3_muladd(&w2, &w1, &w0, ws[6], p[30]); + word3_muladd(&w2, &w1, &w0, ws[7], p[29]); + word3_muladd(&w2, &w1, &w0, ws[8], p[28]); + word3_muladd(&w2, &w1, &w0, ws[9], p[27]); + word3_muladd(&w2, &w1, &w0, ws[10], p[26]); + word3_muladd(&w2, &w1, &w0, ws[11], p[25]); + word3_muladd(&w2, &w1, &w0, ws[12], p[24]); + word3_muladd(&w2, &w1, &w0, ws[13], p[23]); + word3_muladd(&w2, &w1, &w0, ws[14], p[22]); + word3_muladd(&w2, &w1, &w0, ws[15], p[21]); + word3_muladd(&w2, &w1, &w0, ws[16], p[20]); + word3_muladd(&w2, &w1, &w0, ws[17], p[19]); + word3_muladd(&w2, &w1, &w0, ws[18], p[18]); + word3_muladd(&w2, &w1, &w0, ws[19], p[17]); + word3_muladd(&w2, &w1, &w0, ws[20], p[16]); + word3_muladd(&w2, &w1, &w0, ws[21], p[15]); + word3_muladd(&w2, &w1, &w0, ws[22], p[14]); + word3_muladd(&w2, &w1, &w0, ws[23], p[13]); + word3_muladd(&w2, &w1, &w0, ws[24], p[12]); + word3_muladd(&w2, &w1, &w0, ws[25], p[11]); + word3_muladd(&w2, &w1, &w0, ws[26], p[10]); + word3_muladd(&w2, &w1, &w0, ws[27], p[9]); + word3_muladd(&w2, &w1, &w0, ws[28], p[8]); + word3_muladd(&w2, &w1, &w0, ws[29], p[7]); + word3_muladd(&w2, &w1, &w0, ws[30], p[6]); + word3_muladd(&w2, &w1, &w0, ws[31], p[5]); + word3_add(&w2, &w1, &w0, z[36]); + ws[4] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[6], p[31]); + word3_muladd(&w2, &w1, &w0, ws[7], p[30]); + word3_muladd(&w2, &w1, &w0, ws[8], p[29]); + word3_muladd(&w2, &w1, &w0, ws[9], p[28]); + word3_muladd(&w2, &w1, &w0, ws[10], p[27]); + word3_muladd(&w2, &w1, &w0, ws[11], p[26]); + word3_muladd(&w2, &w1, &w0, ws[12], p[25]); + word3_muladd(&w2, &w1, &w0, ws[13], p[24]); + word3_muladd(&w2, &w1, &w0, ws[14], p[23]); + word3_muladd(&w2, &w1, &w0, ws[15], p[22]); + word3_muladd(&w2, &w1, &w0, ws[16], p[21]); + word3_muladd(&w2, &w1, &w0, ws[17], p[20]); + word3_muladd(&w2, &w1, &w0, ws[18], p[19]); + word3_muladd(&w2, &w1, &w0, ws[19], p[18]); + word3_muladd(&w2, &w1, &w0, ws[20], p[17]); + word3_muladd(&w2, &w1, &w0, ws[21], p[16]); + word3_muladd(&w2, &w1, &w0, ws[22], p[15]); + word3_muladd(&w2, &w1, &w0, ws[23], p[14]); + word3_muladd(&w2, &w1, &w0, ws[24], p[13]); + word3_muladd(&w2, &w1, &w0, ws[25], p[12]); + word3_muladd(&w2, &w1, &w0, ws[26], p[11]); + word3_muladd(&w2, &w1, &w0, ws[27], p[10]); + word3_muladd(&w2, &w1, &w0, ws[28], p[9]); + word3_muladd(&w2, &w1, &w0, ws[29], p[8]); + word3_muladd(&w2, &w1, &w0, ws[30], p[7]); + word3_muladd(&w2, &w1, &w0, ws[31], p[6]); + word3_add(&w2, &w1, &w0, z[37]); + ws[5] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[7], p[31]); + word3_muladd(&w2, &w1, &w0, ws[8], p[30]); + word3_muladd(&w2, &w1, &w0, ws[9], p[29]); + word3_muladd(&w2, &w1, &w0, ws[10], p[28]); + word3_muladd(&w2, &w1, &w0, ws[11], p[27]); + word3_muladd(&w2, &w1, &w0, ws[12], p[26]); + word3_muladd(&w2, &w1, &w0, ws[13], p[25]); + word3_muladd(&w2, &w1, &w0, ws[14], p[24]); + word3_muladd(&w2, &w1, &w0, ws[15], p[23]); + word3_muladd(&w2, &w1, &w0, ws[16], p[22]); + word3_muladd(&w2, &w1, &w0, ws[17], p[21]); + word3_muladd(&w2, &w1, &w0, ws[18], p[20]); + word3_muladd(&w2, &w1, &w0, ws[19], p[19]); + word3_muladd(&w2, &w1, &w0, ws[20], p[18]); + word3_muladd(&w2, &w1, &w0, ws[21], p[17]); + word3_muladd(&w2, &w1, &w0, ws[22], p[16]); + word3_muladd(&w2, &w1, &w0, ws[23], p[15]); + word3_muladd(&w2, &w1, &w0, ws[24], p[14]); + word3_muladd(&w2, &w1, &w0, ws[25], p[13]); + word3_muladd(&w2, &w1, &w0, ws[26], p[12]); + word3_muladd(&w2, &w1, &w0, ws[27], p[11]); + word3_muladd(&w2, &w1, &w0, ws[28], p[10]); + word3_muladd(&w2, &w1, &w0, ws[29], p[9]); + word3_muladd(&w2, &w1, &w0, ws[30], p[8]); + word3_muladd(&w2, &w1, &w0, ws[31], p[7]); + word3_add(&w2, &w1, &w0, z[38]); + ws[6] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[8], p[31]); + word3_muladd(&w2, &w1, &w0, ws[9], p[30]); + word3_muladd(&w2, &w1, &w0, ws[10], p[29]); + word3_muladd(&w2, &w1, &w0, ws[11], p[28]); + word3_muladd(&w2, &w1, &w0, ws[12], p[27]); + word3_muladd(&w2, &w1, &w0, ws[13], p[26]); + word3_muladd(&w2, &w1, &w0, ws[14], p[25]); + word3_muladd(&w2, &w1, &w0, ws[15], p[24]); + word3_muladd(&w2, &w1, &w0, ws[16], p[23]); + word3_muladd(&w2, &w1, &w0, ws[17], p[22]); + word3_muladd(&w2, &w1, &w0, ws[18], p[21]); + word3_muladd(&w2, &w1, &w0, ws[19], p[20]); + word3_muladd(&w2, &w1, &w0, ws[20], p[19]); + word3_muladd(&w2, &w1, &w0, ws[21], p[18]); + word3_muladd(&w2, &w1, &w0, ws[22], p[17]); + word3_muladd(&w2, &w1, &w0, ws[23], p[16]); + word3_muladd(&w2, &w1, &w0, ws[24], p[15]); + word3_muladd(&w2, &w1, &w0, ws[25], p[14]); + word3_muladd(&w2, &w1, &w0, ws[26], p[13]); + word3_muladd(&w2, &w1, &w0, ws[27], p[12]); + word3_muladd(&w2, &w1, &w0, ws[28], p[11]); + word3_muladd(&w2, &w1, &w0, ws[29], p[10]); + word3_muladd(&w2, &w1, &w0, ws[30], p[9]); + word3_muladd(&w2, &w1, &w0, ws[31], p[8]); + word3_add(&w2, &w1, &w0, z[39]); + ws[7] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[9], p[31]); + word3_muladd(&w2, &w1, &w0, ws[10], p[30]); + word3_muladd(&w2, &w1, &w0, ws[11], p[29]); + word3_muladd(&w2, &w1, &w0, ws[12], p[28]); + word3_muladd(&w2, &w1, &w0, ws[13], p[27]); + word3_muladd(&w2, &w1, &w0, ws[14], p[26]); + word3_muladd(&w2, &w1, &w0, ws[15], p[25]); + word3_muladd(&w2, &w1, &w0, ws[16], p[24]); + word3_muladd(&w2, &w1, &w0, ws[17], p[23]); + word3_muladd(&w2, &w1, &w0, ws[18], p[22]); + word3_muladd(&w2, &w1, &w0, ws[19], p[21]); + word3_muladd(&w2, &w1, &w0, ws[20], p[20]); + word3_muladd(&w2, &w1, &w0, ws[21], p[19]); + word3_muladd(&w2, &w1, &w0, ws[22], p[18]); + word3_muladd(&w2, &w1, &w0, ws[23], p[17]); + word3_muladd(&w2, &w1, &w0, ws[24], p[16]); + word3_muladd(&w2, &w1, &w0, ws[25], p[15]); + word3_muladd(&w2, &w1, &w0, ws[26], p[14]); + word3_muladd(&w2, &w1, &w0, ws[27], p[13]); + word3_muladd(&w2, &w1, &w0, ws[28], p[12]); + word3_muladd(&w2, &w1, &w0, ws[29], p[11]); + word3_muladd(&w2, &w1, &w0, ws[30], p[10]); + word3_muladd(&w2, &w1, &w0, ws[31], p[9]); + word3_add(&w2, &w1, &w0, z[40]); + ws[8] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[10], p[31]); + word3_muladd(&w2, &w1, &w0, ws[11], p[30]); + word3_muladd(&w2, &w1, &w0, ws[12], p[29]); + word3_muladd(&w2, &w1, &w0, ws[13], p[28]); + word3_muladd(&w2, &w1, &w0, ws[14], p[27]); + word3_muladd(&w2, &w1, &w0, ws[15], p[26]); + word3_muladd(&w2, &w1, &w0, ws[16], p[25]); + word3_muladd(&w2, &w1, &w0, ws[17], p[24]); + word3_muladd(&w2, &w1, &w0, ws[18], p[23]); + word3_muladd(&w2, &w1, &w0, ws[19], p[22]); + word3_muladd(&w2, &w1, &w0, ws[20], p[21]); + word3_muladd(&w2, &w1, &w0, ws[21], p[20]); + word3_muladd(&w2, &w1, &w0, ws[22], p[19]); + word3_muladd(&w2, &w1, &w0, ws[23], p[18]); + word3_muladd(&w2, &w1, &w0, ws[24], p[17]); + word3_muladd(&w2, &w1, &w0, ws[25], p[16]); + word3_muladd(&w2, &w1, &w0, ws[26], p[15]); + word3_muladd(&w2, &w1, &w0, ws[27], p[14]); + word3_muladd(&w2, &w1, &w0, ws[28], p[13]); + word3_muladd(&w2, &w1, &w0, ws[29], p[12]); + word3_muladd(&w2, &w1, &w0, ws[30], p[11]); + word3_muladd(&w2, &w1, &w0, ws[31], p[10]); + word3_add(&w2, &w1, &w0, z[41]); + ws[9] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[11], p[31]); + word3_muladd(&w2, &w1, &w0, ws[12], p[30]); + word3_muladd(&w2, &w1, &w0, ws[13], p[29]); + word3_muladd(&w2, &w1, &w0, ws[14], p[28]); + word3_muladd(&w2, &w1, &w0, ws[15], p[27]); + word3_muladd(&w2, &w1, &w0, ws[16], p[26]); + word3_muladd(&w2, &w1, &w0, ws[17], p[25]); + word3_muladd(&w2, &w1, &w0, ws[18], p[24]); + word3_muladd(&w2, &w1, &w0, ws[19], p[23]); + word3_muladd(&w2, &w1, &w0, ws[20], p[22]); + word3_muladd(&w2, &w1, &w0, ws[21], p[21]); + word3_muladd(&w2, &w1, &w0, ws[22], p[20]); + word3_muladd(&w2, &w1, &w0, ws[23], p[19]); + word3_muladd(&w2, &w1, &w0, ws[24], p[18]); + word3_muladd(&w2, &w1, &w0, ws[25], p[17]); + word3_muladd(&w2, &w1, &w0, ws[26], p[16]); + word3_muladd(&w2, &w1, &w0, ws[27], p[15]); + word3_muladd(&w2, &w1, &w0, ws[28], p[14]); + word3_muladd(&w2, &w1, &w0, ws[29], p[13]); + word3_muladd(&w2, &w1, &w0, ws[30], p[12]); + word3_muladd(&w2, &w1, &w0, ws[31], p[11]); + word3_add(&w2, &w1, &w0, z[42]); + ws[10] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[12], p[31]); + word3_muladd(&w2, &w1, &w0, ws[13], p[30]); + word3_muladd(&w2, &w1, &w0, ws[14], p[29]); + word3_muladd(&w2, &w1, &w0, ws[15], p[28]); + word3_muladd(&w2, &w1, &w0, ws[16], p[27]); + word3_muladd(&w2, &w1, &w0, ws[17], p[26]); + word3_muladd(&w2, &w1, &w0, ws[18], p[25]); + word3_muladd(&w2, &w1, &w0, ws[19], p[24]); + word3_muladd(&w2, &w1, &w0, ws[20], p[23]); + word3_muladd(&w2, &w1, &w0, ws[21], p[22]); + word3_muladd(&w2, &w1, &w0, ws[22], p[21]); + word3_muladd(&w2, &w1, &w0, ws[23], p[20]); + word3_muladd(&w2, &w1, &w0, ws[24], p[19]); + word3_muladd(&w2, &w1, &w0, ws[25], p[18]); + word3_muladd(&w2, &w1, &w0, ws[26], p[17]); + word3_muladd(&w2, &w1, &w0, ws[27], p[16]); + word3_muladd(&w2, &w1, &w0, ws[28], p[15]); + word3_muladd(&w2, &w1, &w0, ws[29], p[14]); + word3_muladd(&w2, &w1, &w0, ws[30], p[13]); + word3_muladd(&w2, &w1, &w0, ws[31], p[12]); + word3_add(&w2, &w1, &w0, z[43]); + ws[11] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[13], p[31]); + word3_muladd(&w2, &w1, &w0, ws[14], p[30]); + word3_muladd(&w2, &w1, &w0, ws[15], p[29]); + word3_muladd(&w2, &w1, &w0, ws[16], p[28]); + word3_muladd(&w2, &w1, &w0, ws[17], p[27]); + word3_muladd(&w2, &w1, &w0, ws[18], p[26]); + word3_muladd(&w2, &w1, &w0, ws[19], p[25]); + word3_muladd(&w2, &w1, &w0, ws[20], p[24]); + word3_muladd(&w2, &w1, &w0, ws[21], p[23]); + word3_muladd(&w2, &w1, &w0, ws[22], p[22]); + word3_muladd(&w2, &w1, &w0, ws[23], p[21]); + word3_muladd(&w2, &w1, &w0, ws[24], p[20]); + word3_muladd(&w2, &w1, &w0, ws[25], p[19]); + word3_muladd(&w2, &w1, &w0, ws[26], p[18]); + word3_muladd(&w2, &w1, &w0, ws[27], p[17]); + word3_muladd(&w2, &w1, &w0, ws[28], p[16]); + word3_muladd(&w2, &w1, &w0, ws[29], p[15]); + word3_muladd(&w2, &w1, &w0, ws[30], p[14]); + word3_muladd(&w2, &w1, &w0, ws[31], p[13]); + word3_add(&w2, &w1, &w0, z[44]); + ws[12] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[14], p[31]); + word3_muladd(&w2, &w1, &w0, ws[15], p[30]); + word3_muladd(&w2, &w1, &w0, ws[16], p[29]); + word3_muladd(&w2, &w1, &w0, ws[17], p[28]); + word3_muladd(&w2, &w1, &w0, ws[18], p[27]); + word3_muladd(&w2, &w1, &w0, ws[19], p[26]); + word3_muladd(&w2, &w1, &w0, ws[20], p[25]); + word3_muladd(&w2, &w1, &w0, ws[21], p[24]); + word3_muladd(&w2, &w1, &w0, ws[22], p[23]); + word3_muladd(&w2, &w1, &w0, ws[23], p[22]); + word3_muladd(&w2, &w1, &w0, ws[24], p[21]); + word3_muladd(&w2, &w1, &w0, ws[25], p[20]); + word3_muladd(&w2, &w1, &w0, ws[26], p[19]); + word3_muladd(&w2, &w1, &w0, ws[27], p[18]); + word3_muladd(&w2, &w1, &w0, ws[28], p[17]); + word3_muladd(&w2, &w1, &w0, ws[29], p[16]); + word3_muladd(&w2, &w1, &w0, ws[30], p[15]); + word3_muladd(&w2, &w1, &w0, ws[31], p[14]); + word3_add(&w2, &w1, &w0, z[45]); + ws[13] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[15], p[31]); + word3_muladd(&w2, &w1, &w0, ws[16], p[30]); + word3_muladd(&w2, &w1, &w0, ws[17], p[29]); + word3_muladd(&w2, &w1, &w0, ws[18], p[28]); + word3_muladd(&w2, &w1, &w0, ws[19], p[27]); + word3_muladd(&w2, &w1, &w0, ws[20], p[26]); + word3_muladd(&w2, &w1, &w0, ws[21], p[25]); + word3_muladd(&w2, &w1, &w0, ws[22], p[24]); + word3_muladd(&w2, &w1, &w0, ws[23], p[23]); + word3_muladd(&w2, &w1, &w0, ws[24], p[22]); + word3_muladd(&w2, &w1, &w0, ws[25], p[21]); + word3_muladd(&w2, &w1, &w0, ws[26], p[20]); + word3_muladd(&w2, &w1, &w0, ws[27], p[19]); + word3_muladd(&w2, &w1, &w0, ws[28], p[18]); + word3_muladd(&w2, &w1, &w0, ws[29], p[17]); + word3_muladd(&w2, &w1, &w0, ws[30], p[16]); + word3_muladd(&w2, &w1, &w0, ws[31], p[15]); + word3_add(&w2, &w1, &w0, z[46]); + ws[14] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[16], p[31]); + word3_muladd(&w2, &w1, &w0, ws[17], p[30]); + word3_muladd(&w2, &w1, &w0, ws[18], p[29]); + word3_muladd(&w2, &w1, &w0, ws[19], p[28]); + word3_muladd(&w2, &w1, &w0, ws[20], p[27]); + word3_muladd(&w2, &w1, &w0, ws[21], p[26]); + word3_muladd(&w2, &w1, &w0, ws[22], p[25]); + word3_muladd(&w2, &w1, &w0, ws[23], p[24]); + word3_muladd(&w2, &w1, &w0, ws[24], p[23]); + word3_muladd(&w2, &w1, &w0, ws[25], p[22]); + word3_muladd(&w2, &w1, &w0, ws[26], p[21]); + word3_muladd(&w2, &w1, &w0, ws[27], p[20]); + word3_muladd(&w2, &w1, &w0, ws[28], p[19]); + word3_muladd(&w2, &w1, &w0, ws[29], p[18]); + word3_muladd(&w2, &w1, &w0, ws[30], p[17]); + word3_muladd(&w2, &w1, &w0, ws[31], p[16]); + word3_add(&w2, &w1, &w0, z[47]); + ws[15] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[17], p[31]); + word3_muladd(&w2, &w1, &w0, ws[18], p[30]); + word3_muladd(&w2, &w1, &w0, ws[19], p[29]); + word3_muladd(&w2, &w1, &w0, ws[20], p[28]); + word3_muladd(&w2, &w1, &w0, ws[21], p[27]); + word3_muladd(&w2, &w1, &w0, ws[22], p[26]); + word3_muladd(&w2, &w1, &w0, ws[23], p[25]); + word3_muladd(&w2, &w1, &w0, ws[24], p[24]); + word3_muladd(&w2, &w1, &w0, ws[25], p[23]); + word3_muladd(&w2, &w1, &w0, ws[26], p[22]); + word3_muladd(&w2, &w1, &w0, ws[27], p[21]); + word3_muladd(&w2, &w1, &w0, ws[28], p[20]); + word3_muladd(&w2, &w1, &w0, ws[29], p[19]); + word3_muladd(&w2, &w1, &w0, ws[30], p[18]); + word3_muladd(&w2, &w1, &w0, ws[31], p[17]); + word3_add(&w2, &w1, &w0, z[48]); + ws[16] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[18], p[31]); + word3_muladd(&w2, &w1, &w0, ws[19], p[30]); + word3_muladd(&w2, &w1, &w0, ws[20], p[29]); + word3_muladd(&w2, &w1, &w0, ws[21], p[28]); + word3_muladd(&w2, &w1, &w0, ws[22], p[27]); + word3_muladd(&w2, &w1, &w0, ws[23], p[26]); + word3_muladd(&w2, &w1, &w0, ws[24], p[25]); + word3_muladd(&w2, &w1, &w0, ws[25], p[24]); + word3_muladd(&w2, &w1, &w0, ws[26], p[23]); + word3_muladd(&w2, &w1, &w0, ws[27], p[22]); + word3_muladd(&w2, &w1, &w0, ws[28], p[21]); + word3_muladd(&w2, &w1, &w0, ws[29], p[20]); + word3_muladd(&w2, &w1, &w0, ws[30], p[19]); + word3_muladd(&w2, &w1, &w0, ws[31], p[18]); + word3_add(&w2, &w1, &w0, z[49]); + ws[17] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[19], p[31]); + word3_muladd(&w2, &w1, &w0, ws[20], p[30]); + word3_muladd(&w2, &w1, &w0, ws[21], p[29]); + word3_muladd(&w2, &w1, &w0, ws[22], p[28]); + word3_muladd(&w2, &w1, &w0, ws[23], p[27]); + word3_muladd(&w2, &w1, &w0, ws[24], p[26]); + word3_muladd(&w2, &w1, &w0, ws[25], p[25]); + word3_muladd(&w2, &w1, &w0, ws[26], p[24]); + word3_muladd(&w2, &w1, &w0, ws[27], p[23]); + word3_muladd(&w2, &w1, &w0, ws[28], p[22]); + word3_muladd(&w2, &w1, &w0, ws[29], p[21]); + word3_muladd(&w2, &w1, &w0, ws[30], p[20]); + word3_muladd(&w2, &w1, &w0, ws[31], p[19]); + word3_add(&w2, &w1, &w0, z[50]); + ws[18] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[20], p[31]); + word3_muladd(&w2, &w1, &w0, ws[21], p[30]); + word3_muladd(&w2, &w1, &w0, ws[22], p[29]); + word3_muladd(&w2, &w1, &w0, ws[23], p[28]); + word3_muladd(&w2, &w1, &w0, ws[24], p[27]); + word3_muladd(&w2, &w1, &w0, ws[25], p[26]); + word3_muladd(&w2, &w1, &w0, ws[26], p[25]); + word3_muladd(&w2, &w1, &w0, ws[27], p[24]); + word3_muladd(&w2, &w1, &w0, ws[28], p[23]); + word3_muladd(&w2, &w1, &w0, ws[29], p[22]); + word3_muladd(&w2, &w1, &w0, ws[30], p[21]); + word3_muladd(&w2, &w1, &w0, ws[31], p[20]); + word3_add(&w2, &w1, &w0, z[51]); + ws[19] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[21], p[31]); + word3_muladd(&w2, &w1, &w0, ws[22], p[30]); + word3_muladd(&w2, &w1, &w0, ws[23], p[29]); + word3_muladd(&w2, &w1, &w0, ws[24], p[28]); + word3_muladd(&w2, &w1, &w0, ws[25], p[27]); + word3_muladd(&w2, &w1, &w0, ws[26], p[26]); + word3_muladd(&w2, &w1, &w0, ws[27], p[25]); + word3_muladd(&w2, &w1, &w0, ws[28], p[24]); + word3_muladd(&w2, &w1, &w0, ws[29], p[23]); + word3_muladd(&w2, &w1, &w0, ws[30], p[22]); + word3_muladd(&w2, &w1, &w0, ws[31], p[21]); + word3_add(&w2, &w1, &w0, z[52]); + ws[20] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[22], p[31]); + word3_muladd(&w2, &w1, &w0, ws[23], p[30]); + word3_muladd(&w2, &w1, &w0, ws[24], p[29]); + word3_muladd(&w2, &w1, &w0, ws[25], p[28]); + word3_muladd(&w2, &w1, &w0, ws[26], p[27]); + word3_muladd(&w2, &w1, &w0, ws[27], p[26]); + word3_muladd(&w2, &w1, &w0, ws[28], p[25]); + word3_muladd(&w2, &w1, &w0, ws[29], p[24]); + word3_muladd(&w2, &w1, &w0, ws[30], p[23]); + word3_muladd(&w2, &w1, &w0, ws[31], p[22]); + word3_add(&w2, &w1, &w0, z[53]); + ws[21] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[23], p[31]); + word3_muladd(&w2, &w1, &w0, ws[24], p[30]); + word3_muladd(&w2, &w1, &w0, ws[25], p[29]); + word3_muladd(&w2, &w1, &w0, ws[26], p[28]); + word3_muladd(&w2, &w1, &w0, ws[27], p[27]); + word3_muladd(&w2, &w1, &w0, ws[28], p[26]); + word3_muladd(&w2, &w1, &w0, ws[29], p[25]); + word3_muladd(&w2, &w1, &w0, ws[30], p[24]); + word3_muladd(&w2, &w1, &w0, ws[31], p[23]); + word3_add(&w2, &w1, &w0, z[54]); + ws[22] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[24], p[31]); + word3_muladd(&w2, &w1, &w0, ws[25], p[30]); + word3_muladd(&w2, &w1, &w0, ws[26], p[29]); + word3_muladd(&w2, &w1, &w0, ws[27], p[28]); + word3_muladd(&w2, &w1, &w0, ws[28], p[27]); + word3_muladd(&w2, &w1, &w0, ws[29], p[26]); + word3_muladd(&w2, &w1, &w0, ws[30], p[25]); + word3_muladd(&w2, &w1, &w0, ws[31], p[24]); + word3_add(&w2, &w1, &w0, z[55]); + ws[23] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[25], p[31]); + word3_muladd(&w2, &w1, &w0, ws[26], p[30]); + word3_muladd(&w2, &w1, &w0, ws[27], p[29]); + word3_muladd(&w2, &w1, &w0, ws[28], p[28]); + word3_muladd(&w2, &w1, &w0, ws[29], p[27]); + word3_muladd(&w2, &w1, &w0, ws[30], p[26]); + word3_muladd(&w2, &w1, &w0, ws[31], p[25]); + word3_add(&w2, &w1, &w0, z[56]); + ws[24] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[26], p[31]); + word3_muladd(&w2, &w1, &w0, ws[27], p[30]); + word3_muladd(&w2, &w1, &w0, ws[28], p[29]); + word3_muladd(&w2, &w1, &w0, ws[29], p[28]); + word3_muladd(&w2, &w1, &w0, ws[30], p[27]); + word3_muladd(&w2, &w1, &w0, ws[31], p[26]); + word3_add(&w2, &w1, &w0, z[57]); + ws[25] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[27], p[31]); + word3_muladd(&w2, &w1, &w0, ws[28], p[30]); + word3_muladd(&w2, &w1, &w0, ws[29], p[29]); + word3_muladd(&w2, &w1, &w0, ws[30], p[28]); + word3_muladd(&w2, &w1, &w0, ws[31], p[27]); + word3_add(&w2, &w1, &w0, z[58]); + ws[26] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[28], p[31]); + word3_muladd(&w2, &w1, &w0, ws[29], p[30]); + word3_muladd(&w2, &w1, &w0, ws[30], p[29]); + word3_muladd(&w2, &w1, &w0, ws[31], p[28]); + word3_add(&w2, &w1, &w0, z[59]); + ws[27] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[29], p[31]); + word3_muladd(&w2, &w1, &w0, ws[30], p[30]); + word3_muladd(&w2, &w1, &w0, ws[31], p[29]); + word3_add(&w2, &w1, &w0, z[60]); + ws[28] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[30], p[31]); + word3_muladd(&w2, &w1, &w0, ws[31], p[30]); + word3_add(&w2, &w1, &w0, z[61]); + ws[29] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, ws[31], p[31]); + word3_add(&w2, &w1, &w0, z[62]); + ws[30] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_add(&w2, &w1, &w0, z[63]); + ws[31] = w0; + w0 = w1; w1 = w2; w2 = 0; + word3_add(&w2, &w1, &w0, z[65]); + ws[32] = w0; + ws[33] = w1; + word borrow = bigint_sub3(ws + 32 + 1, ws, 32 + 1, p, 32); + CT::conditional_copy_mem(borrow, z, ws, ws + 33, 33); + clear_mem(z + 32, 2*(32+1) - 32); + } + +} 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 new file mode 100644 index 0000000000..c9936a338b --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/math/numbertheory/curve_nistp.h @@ -0,0 +1,46 @@ +/* +* Arithmetic operations specialized for NIST ECC primes +* (C) 2014,2015 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_NIST_PRIMES_H_ +#define BOTAN_NIST_PRIMES_H_ + +#include + +namespace Botan { + +/** +* NIST Prime reduction functions. +* +* Reduces the value in place +* +* ws is a workspace function which is used as a temporary, +* and will be resized as needed. +*/ +BOTAN_PUBLIC_API(2,0) const BigInt& prime_p521(); +BOTAN_PUBLIC_API(2,0) void redc_p521(BigInt& x, secure_vector& 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(); +BOTAN_PUBLIC_API(2,0) void redc_p384(BigInt& x, secure_vector& ws); + +BOTAN_PUBLIC_API(2,0) const BigInt& prime_p256(); +BOTAN_PUBLIC_API(2,0) void redc_p256(BigInt& x, secure_vector& ws); + +BOTAN_PUBLIC_API(2,0) const BigInt& prime_p224(); +BOTAN_PUBLIC_API(2,0) void redc_p224(BigInt& x, secure_vector& ws); + +BOTAN_PUBLIC_API(2,0) const BigInt& prime_p192(); +BOTAN_PUBLIC_API(2,0) void redc_p192(BigInt& x, secure_vector& ws); + +#endif + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/math/numbertheory/def_powm.h b/src/libs/3rdparty/botan/src/lib/math/numbertheory/def_powm.h new file mode 100644 index 0000000000..6b1f33835f --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/math/numbertheory/def_powm.h @@ -0,0 +1,68 @@ +/* +* Modular Exponentiation +* (C) 1999-2007 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_DEFAULT_MODEXP_H_ +#define BOTAN_DEFAULT_MODEXP_H_ + +#include +#include +#include + +namespace Botan { + +/** +* Fixed Window Exponentiator +*/ +class Fixed_Window_Exponentiator final : public Modular_Exponentiator + { + public: + void set_exponent(const BigInt&) override; + void set_base(const BigInt&) override; + BigInt execute() const override; + + Modular_Exponentiator* copy() const override + { return new Fixed_Window_Exponentiator(*this); } + + Fixed_Window_Exponentiator(const BigInt&, Power_Mod::Usage_Hints); + private: + Modular_Reducer m_reducer; + BigInt m_exp; + size_t m_window_bits; + std::vector m_g; + Power_Mod::Usage_Hints m_hints; + }; + +class Montgomery_Params; +class Montgomery_Exponentation_State; + +/** +* Montgomery Exponentiator +*/ +class Montgomery_Exponentiator final : public Modular_Exponentiator + { + public: + void set_exponent(const BigInt&) override; + void set_base(const BigInt&) override; + BigInt execute() const override; + + Modular_Exponentiator* copy() const override + { return new Montgomery_Exponentiator(*this); } + + Montgomery_Exponentiator(const BigInt&, Power_Mod::Usage_Hints); + private: + BigInt m_p; + Modular_Reducer m_mod_p; + std::shared_ptr m_monty_params; + std::shared_ptr m_monty; + + BigInt m_e; + Power_Mod::Usage_Hints m_hints; + }; + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/math/numbertheory/dsa_gen.cpp b/src/libs/3rdparty/botan/src/lib/math/numbertheory/dsa_gen.cpp new file mode 100644 index 0000000000..a5efbc2662 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/math/numbertheory/dsa_gen.cpp @@ -0,0 +1,136 @@ +/* +* DSA Parameter Generation +* (C) 1999-2007 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include + +namespace Botan { + +namespace { + +/* +* Check if this size is allowed by FIPS 186-3 +*/ +bool fips186_3_valid_size(size_t pbits, size_t qbits) + { + if(qbits == 160) + return (pbits == 1024); + + if(qbits == 224) + return (pbits == 2048); + + if(qbits == 256) + return (pbits == 2048 || pbits == 3072); + + return false; + } + +} + +/* +* Attempt DSA prime generation with given seed +*/ +bool generate_dsa_primes(RandomNumberGenerator& rng, + BigInt& p, BigInt& q, + size_t pbits, size_t qbits, + const std::vector& seed_c, + size_t offset) + { + if(!fips186_3_valid_size(pbits, qbits)) + throw Invalid_Argument( + "FIPS 186-3 does not allow DSA domain parameters of " + + std::to_string(pbits) + "/" + std::to_string(qbits) + " bits long"); + + if(seed_c.size() * 8 < qbits) + throw Invalid_Argument( + "Generating a DSA parameter set with a " + std::to_string(qbits) + + " bit long q requires a seed at least as many bits long"); + + const std::string hash_name = "SHA-" + std::to_string(qbits); + std::unique_ptr hash(HashFunction::create_or_throw(hash_name)); + + const size_t HASH_SIZE = hash->output_length(); + + class Seed final + { + public: + explicit Seed(const std::vector& s) : m_seed(s) {} + + const std::vector& value() const { return m_seed; } + + Seed& operator++() + { + for(size_t j = m_seed.size(); j > 0; --j) + if(++m_seed[j-1]) + break; + return (*this); + } + private: + std::vector m_seed; + }; + + Seed seed(seed_c); + + q.binary_decode(hash->process(seed.value())); + q.set_bit(qbits-1); + q.set_bit(0); + + if(!is_prime(q, rng, 128, true)) + return false; + + const size_t n = (pbits-1) / (HASH_SIZE * 8), + b = (pbits-1) % (HASH_SIZE * 8); + + BigInt X; + std::vector V(HASH_SIZE * (n+1)); + + Modular_Reducer mod_2q(2*q); + + for(size_t j = 0; j != 4*pbits; ++j) + { + for(size_t k = 0; k <= n; ++k) + { + ++seed; + hash->update(seed.value()); + hash->final(&V[HASH_SIZE * (n-k)]); + } + + if(j >= offset) + { + X.binary_decode(&V[HASH_SIZE - 1 - b/8], + V.size() - (HASH_SIZE - 1 - b/8)); + X.set_bit(pbits-1); + + p = X - (mod_2q.reduce(X) - 1); + + if(p.bits() == pbits && is_prime(p, rng, 128, true)) + return true; + } + } + return false; + } + +/* +* Generate DSA Primes +*/ +std::vector generate_dsa_primes(RandomNumberGenerator& rng, + BigInt& p, BigInt& q, + size_t pbits, size_t qbits) + { + while(true) + { + std::vector seed(qbits / 8); + rng.randomize(seed.data(), seed.size()); + + if(generate_dsa_primes(rng, p, q, pbits, qbits, seed)) + return seed; + } + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/math/numbertheory/info.txt b/src/libs/3rdparty/botan/src/lib/math/numbertheory/info.txt new file mode 100644 index 0000000000..8da52f9f43 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/math/numbertheory/info.txt @@ -0,0 +1,24 @@ + +NUMBERTHEORY -> 20131128 + + +load_on auto + + +curve_nistp.h +numthry.h +pow_mod.h +reducer.h +monty.h + + + +def_powm.h +monty_exp.h + + + +bigint +hash +rng + diff --git a/src/libs/3rdparty/botan/src/lib/math/numbertheory/jacobi.cpp b/src/libs/3rdparty/botan/src/lib/math/numbertheory/jacobi.cpp new file mode 100644 index 0000000000..d3e8d75572 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/math/numbertheory/jacobi.cpp @@ -0,0 +1,53 @@ +/* +* Jacobi Function +* (C) 1999-2007 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include + +namespace Botan { + +/* +* Calculate the Jacobi symbol +*/ +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; + int32_t J = 1; + + while(y > 1) + { + x %= y; + if(x > y / 2) + { + x = y - x; + if(y % 4 == 3) + J = -J; + } + if(x.is_zero()) + return 0; + + size_t shifts = low_zero_bits(x); + x >>= shifts; + if(shifts % 2) + { + word y_mod_8 = y % 8; + if(y_mod_8 == 3 || y_mod_8 == 5) + J = -J; + } + + if(x % 4 == 3 && y % 4 == 3) + J = -J; + std::swap(x, y); + } + return J; + } + +} 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 new file mode 100644 index 0000000000..1979fa5502 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/math/numbertheory/make_prm.cpp @@ -0,0 +1,285 @@ +/* +* Prime Generation +* (C) 1999-2007,2018 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include + +namespace Botan { + +namespace { + +class Prime_Sieve + { + public: + Prime_Sieve(const BigInt& init_value) : m_sieve(PRIME_TABLE_SIZE) + { + for(size_t i = 0; i != m_sieve.size(); ++i) + m_sieve[i] = static_cast(init_value % PRIMES[i]); + } + + void step(word increment) + { + for(size_t i = 0; i != m_sieve.size(); ++i) + { + m_sieve[i] = (m_sieve[i] + increment) % PRIMES[i]; + } + } + + bool passes(bool check_2p1 = false) const + { + for(size_t i = 0; i != m_sieve.size(); ++i) + { + /* + In this case, p is a multiple of PRIMES[i] + */ + if(m_sieve[i] == 0) + return false; + + if(check_2p1) + { + /* + In this case, 2*p+1 will be a multiple of PRIMES[i] + + So if potentially generating a safe prime, we want to + avoid this value because 2*p+1 will certainly not be prime. + + See "Safe Prime Generation with a Combined Sieve" M. Wiener + https://eprint.iacr.org/2003/186.pdf + */ + if(m_sieve[i] == (PRIMES[i] - 1) / 2) + return false; + } + } + + return true; + } + + private: + std::vector m_sieve; + }; + +} + + +/* +* Generate a random prime +*/ +BigInt random_prime(RandomNumberGenerator& rng, + size_t bits, const BigInt& coprime, + size_t equiv, size_t modulo, + size_t prob) + { + if(coprime.is_negative()) + { + throw Invalid_Argument("random_prime: coprime must be >= 0"); + } + if(modulo == 0) + { + throw Invalid_Argument("random_prime: Invalid modulo value"); + } + + equiv %= modulo; + + if(equiv == 0) + throw Invalid_Argument("random_prime Invalid value for equiv/modulo"); + + // Handle small values: + if(bits <= 1) + { + throw Invalid_Argument("random_prime: Can't make a prime of " + + std::to_string(bits) + " bits"); + } + else if(bits == 2) + { + return ((rng.next_byte() % 2) ? 2 : 3); + } + else if(bits == 3) + { + return ((rng.next_byte() % 2) ? 5 : 7); + } + else if(bits == 4) + { + return ((rng.next_byte() % 2) ? 11 : 13); + } + else if(bits <= 16) + { + for(;;) + { + size_t idx = make_uint16(rng.next_byte(), rng.next_byte()) % PRIME_TABLE_SIZE; + uint16_t small_prime = PRIMES[idx]; + + if(high_bit(small_prime) == bits) + return small_prime; + } + } + + const size_t MAX_ATTEMPTS = 32*1024; + + while(true) + { + BigInt p(rng, bits); + + // Force lowest and two top bits on + p.set_bit(bits - 1); + p.set_bit(bits - 2); + p.set_bit(0); + + // Force p to be equal to equiv mod modulo + p += (modulo - (p % modulo)) + equiv; + + Prime_Sieve sieve(p); + + size_t counter = 0; + while(true) + { + ++counter; + + if(counter > MAX_ATTEMPTS) + { + break; // don't try forever, choose a new starting point + } + + p += modulo; + + sieve.step(modulo); + + if(sieve.passes(true) == false) + continue; + + if(coprime > 1) + { + /* + * Check if gcd(p - 1, coprime) != 1 by computing the inverse. The + * gcd algorithm is not constant time, but modular inverse is (for + * odd modulus anyway). This avoids a side channel attack against RSA + * key generation, though RSA keygen should be using generate_rsa_prime. + */ + if(inverse_mod(p - 1, coprime).is_zero()) + continue; + } + + if(p.bits() > bits) + break; + + if(is_prime(p, rng, prob, true)) + return p; + } + } + } + +BigInt generate_rsa_prime(RandomNumberGenerator& keygen_rng, + RandomNumberGenerator& prime_test_rng, + size_t bits, + const BigInt& coprime, + size_t prob) + { + if(bits < 512) + throw Invalid_Argument("generate_rsa_prime bits too small"); + + /* + * The restriction on coprime <= 64 bits is arbitrary but generally speaking + * very large RSA public exponents are a bad idea both for performance and due + * to attacks on small d. + */ + if(coprime <= 1 || coprime.is_even() || coprime.bits() > 64) + throw Invalid_Argument("generate_rsa_prime coprime must be small odd positive integer"); + + const size_t MAX_ATTEMPTS = 32*1024; + + while(true) + { + BigInt p(keygen_rng, bits); + + // Force lowest and two top bits on + p.set_bit(bits - 1); + p.set_bit(bits - 2); + p.set_bit(0); + + Prime_Sieve sieve(p); + + const word step = 2; + + size_t counter = 0; + while(true) + { + ++counter; + + if(counter > MAX_ATTEMPTS) + { + break; // don't try forever, choose a new starting point + } + + p += step; + + sieve.step(step); + + if(sieve.passes() == false) + continue; + + /* + * Check if p - 1 and coprime are relatively prime by computing the inverse. + * + * We avoid gcd here because that algorithm is not constant time. + * Modular inverse is (for odd modulus anyway). + * + * We earlier verified that coprime argument is odd. Thus the factors of 2 + * in (p - 1) cannot possibly be factors in coprime, so remove them from p - 1. + * Using an odd modulus allows the const time algorithm to be used. + * + * This assumes coprime < p - 1 which is always true for RSA. + */ + BigInt p1 = p - 1; + p1 >>= low_zero_bits(p1); + if(inverse_mod(coprime, p1).is_zero()) + { + BOTAN_DEBUG_ASSERT(gcd(p1, coprime) > 1); + continue; + } + + BOTAN_DEBUG_ASSERT(gcd(p1, coprime) == 1); + + if(p.bits() > bits) + break; + + if(is_prime(p, prime_test_rng, prob, true)) + return p; + } + } + } + +/* +* Generate a random safe prime +*/ +BigInt random_safe_prime(RandomNumberGenerator& rng, size_t bits) + { + if(bits <= 64) + throw Invalid_Argument("random_safe_prime: Can't make a prime of " + + std::to_string(bits) + " bits"); + + BigInt q, p; + for(;;) + { + /* + Generate q == 2 (mod 3) + + Otherwise [q == 1 (mod 3) case], 2*q+1 == 3 (mod 3) and not prime. + */ + q = random_prime(rng, bits - 1, 0, 2, 3, 8); + p = (q << 1) + 1; + + if(is_prime(p, rng, 128, true)) + { + // We did only a weak check before, go back and verify q before returning + if(is_prime(q, rng, 128, true)) + return p; + } + } + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/math/numbertheory/monty.cpp b/src/libs/3rdparty/botan/src/lib/math/numbertheory/monty.cpp new file mode 100644 index 0000000000..b91560fd58 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/math/numbertheory/monty.cpp @@ -0,0 +1,449 @@ +/* +* (C) 2018 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include + +namespace Botan { + +Montgomery_Params::Montgomery_Params(const BigInt& p, + const Modular_Reducer& mod_p) + { + if(p.is_negative() || p.is_even()) + throw Invalid_Argument("Montgomery_Params invalid modulus"); + + m_p = p; + m_p_words = m_p.sig_words(); + m_p_dash = monty_inverse(m_p.word_at(0)); + + const BigInt r = BigInt::power_of_2(m_p_words * BOTAN_MP_WORD_BITS); + + m_r1 = mod_p.reduce(r); + m_r2 = mod_p.square(m_r1); + m_r3 = mod_p.multiply(m_r1, m_r2); + } + +Montgomery_Params::Montgomery_Params(const BigInt& p) + { + + if(p.is_negative() || p.is_even()) + throw Invalid_Argument("Montgomery_Params invalid modulus"); + + m_p = p; + m_p_words = m_p.sig_words(); + m_p_dash = monty_inverse(m_p.word_at(0)); + + const BigInt r = BigInt::power_of_2(m_p_words * BOTAN_MP_WORD_BITS); + + Modular_Reducer mod_p(p); + + m_r1 = mod_p.reduce(r); + m_r2 = mod_p.square(m_r1); + m_r3 = mod_p.multiply(m_r1, m_r2); + } + +BigInt Montgomery_Params::inv_mod_p(const BigInt& x) const + { + return ct_inverse_mod_odd_modulus(x, p()); + } + +BigInt Montgomery_Params::redc(const BigInt& x, secure_vector& ws) const + { + const size_t output_size = 2*m_p_words + 2; + + if(ws.size() < output_size) + ws.resize(output_size); + + BigInt z = x; + z.grow_to(output_size); + + bigint_monty_redc(z.mutable_data(), + m_p.data(), m_p_words, m_p_dash, + ws.data(), ws.size()); + + return z; + } + +BigInt Montgomery_Params::mul(const BigInt& x, const BigInt& y, + secure_vector& ws) const + { + const size_t output_size = 2*m_p_words + 2; + + if(ws.size() < output_size) + ws.resize(output_size); + + BOTAN_DEBUG_ASSERT(x.sig_words() <= m_p_words); + BOTAN_DEBUG_ASSERT(y.sig_words() <= m_p_words); + + BigInt z(BigInt::Positive, output_size); + bigint_mul(z.mutable_data(), z.size(), + x.data(), x.size(), std::min(m_p_words, x.size()), + y.data(), y.size(), std::min(m_p_words, y.size()), + ws.data(), ws.size()); + + bigint_monty_redc(z.mutable_data(), + m_p.data(), m_p_words, m_p_dash, + ws.data(), ws.size()); + + return z; + } + +BigInt Montgomery_Params::mul(const BigInt& x, + const secure_vector& y, + secure_vector& ws) const + { + const size_t output_size = 2*m_p_words + 2; + if(ws.size() < output_size) + ws.resize(output_size); + BigInt z(BigInt::Positive, output_size); + + BOTAN_DEBUG_ASSERT(x.sig_words() <= m_p_words); + + bigint_mul(z.mutable_data(), z.size(), + x.data(), x.size(), std::min(m_p_words, x.size()), + y.data(), y.size(), std::min(m_p_words, y.size()), + ws.data(), ws.size()); + + bigint_monty_redc(z.mutable_data(), + m_p.data(), m_p_words, m_p_dash, + ws.data(), ws.size()); + + return z; + } + +void Montgomery_Params::mul_by(BigInt& x, + const secure_vector& y, + secure_vector& ws) const + { + const size_t output_size = 2*m_p_words + 2; + + if(ws.size() < 2*output_size) + ws.resize(2*output_size); + + word* z_data = &ws[0]; + word* ws_data = &ws[output_size]; + + BOTAN_DEBUG_ASSERT(x.sig_words() <= m_p_words); + + bigint_mul(z_data, output_size, + x.data(), x.size(), std::min(m_p_words, x.size()), + y.data(), y.size(), std::min(m_p_words, y.size()), + ws_data, output_size); + + bigint_monty_redc(z_data, + m_p.data(), m_p_words, m_p_dash, + ws_data, output_size); + + if(x.size() < output_size) + x.grow_to(output_size); + copy_mem(x.mutable_data(), z_data, output_size); + } + +void Montgomery_Params::mul_by(BigInt& x, + const BigInt& y, + secure_vector& ws) const + { + const size_t output_size = 2*m_p_words + 2; + + if(ws.size() < 2*output_size) + ws.resize(2*output_size); + + word* z_data = &ws[0]; + word* ws_data = &ws[output_size]; + + BOTAN_DEBUG_ASSERT(x.sig_words() <= m_p_words); + + bigint_mul(z_data, output_size, + x.data(), x.size(), std::min(m_p_words, x.size()), + y.data(), y.size(), std::min(m_p_words, y.size()), + ws_data, output_size); + + bigint_monty_redc(z_data, + m_p.data(), m_p_words, m_p_dash, + ws_data, output_size); + + if(x.size() < output_size) + x.grow_to(output_size); + copy_mem(x.mutable_data(), z_data, output_size); + } + +BigInt Montgomery_Params::sqr(const BigInt& x, secure_vector& ws) const + { + const size_t output_size = 2*m_p_words + 2; + + if(ws.size() < output_size) + ws.resize(output_size); + + BigInt z(BigInt::Positive, output_size); + + BOTAN_DEBUG_ASSERT(x.sig_words() <= m_p_words); + + bigint_sqr(z.mutable_data(), z.size(), + x.data(), x.size(), std::min(m_p_words, x.size()), + ws.data(), ws.size()); + + bigint_monty_redc(z.mutable_data(), + m_p.data(), m_p_words, m_p_dash, + ws.data(), ws.size()); + + return z; + } + +void Montgomery_Params::square_this(BigInt& x, + secure_vector& ws) const + { + const size_t output_size = 2*m_p_words + 2; + + if(ws.size() < 2*output_size) + ws.resize(2*output_size); + + word* z_data = &ws[0]; + word* ws_data = &ws[output_size]; + + BOTAN_DEBUG_ASSERT(x.sig_words() <= m_p_words); + + bigint_sqr(z_data, output_size, + x.data(), x.size(), std::min(m_p_words, x.size()), + ws_data, output_size); + + bigint_monty_redc(z_data, + m_p.data(), m_p_words, m_p_dash, + ws_data, output_size); + + if(x.size() < output_size) + x.grow_to(output_size); + copy_mem(x.mutable_data(), z_data, output_size); + } + +Montgomery_Int::Montgomery_Int(const std::shared_ptr params, + const BigInt& v, + bool redc_needed) : + m_params(params) + { + if(redc_needed == false) + { + m_v = v; + } + else + { + secure_vector ws; + m_v = m_params->mul(v % m_params->p(), m_params->R2(), ws); + } + } + +Montgomery_Int::Montgomery_Int(std::shared_ptr params, + const uint8_t bits[], size_t len, + bool redc_needed) : + m_params(params), + m_v(bits, len) + { + if(redc_needed) + { + secure_vector ws; + m_v = m_params->mul(m_v % m_params->p(), m_params->R2(), ws); + } + } + +Montgomery_Int::Montgomery_Int(std::shared_ptr params, + const word words[], size_t len, + bool redc_needed) : + m_params(params), + m_v(words, len) + { + if(redc_needed) + { + secure_vector ws; + m_v = m_params->mul(m_v % m_params->p(), m_params->R2(), ws); + } + } + +void Montgomery_Int::fix_size() + { + const size_t p_words = m_params->p_words(); + + if(m_v.sig_words() > p_words) + throw Internal_Error("Montgomery_Int::fix_size v too large"); + + secure_vector& w = m_v.get_word_vector(); + + if(w.size() != p_words) + { + w.resize(p_words); + w.shrink_to_fit(); + } + } + +bool Montgomery_Int::operator==(const Montgomery_Int& other) const + { + return m_v == other.m_v && m_params->p() == other.m_params->p(); + } + +std::vector Montgomery_Int::serialize() const + { + std::vector v(size()); + BigInt::encode_1363(v.data(), v.size(), value()); + return v; + } + +size_t Montgomery_Int::size() const + { + return m_params->p().bytes(); + } + +bool Montgomery_Int::is_one() const + { + return m_v == m_params->R1(); + } + +bool Montgomery_Int::is_zero() const + { + return m_v.is_zero(); + } + +BigInt Montgomery_Int::value() const + { + secure_vector ws; + return m_params->redc(m_v, ws); + } + +Montgomery_Int Montgomery_Int::operator+(const Montgomery_Int& other) const + { + BigInt z = m_v + other.m_v; + secure_vector ws; + z.reduce_below(m_params->p(), ws); + return Montgomery_Int(m_params, z, false); + } + +Montgomery_Int Montgomery_Int::operator-(const Montgomery_Int& other) const + { + BigInt z = m_v - other.m_v; + if(z.is_negative()) + z += m_params->p(); + return Montgomery_Int(m_params, z, false); + } + +Montgomery_Int& Montgomery_Int::operator+=(const Montgomery_Int& other) + { + secure_vector ws; + return this->add(other, ws); + } + +Montgomery_Int& Montgomery_Int::add(const Montgomery_Int& other, secure_vector& ws) + { + m_v.mod_add(other.m_v, m_params->p(), ws); + return (*this); + } + +Montgomery_Int& Montgomery_Int::operator-=(const Montgomery_Int& other) + { + secure_vector ws; + return this->sub(other, ws); + } + +Montgomery_Int& Montgomery_Int::sub(const Montgomery_Int& other, secure_vector& ws) + { + m_v.mod_sub(other.m_v, m_params->p(), ws); + return (*this); + } + +Montgomery_Int Montgomery_Int::operator*(const Montgomery_Int& other) const + { + secure_vector ws; + return Montgomery_Int(m_params, m_params->mul(m_v, other.m_v, ws), false); + } + +Montgomery_Int Montgomery_Int::mul(const Montgomery_Int& other, + secure_vector& ws) const + { + return Montgomery_Int(m_params, m_params->mul(m_v, other.m_v, ws), false); + } + +Montgomery_Int& Montgomery_Int::mul_by(const Montgomery_Int& other, + secure_vector& ws) + { + m_params->mul_by(m_v, other.m_v, ws); + return (*this); + } + +Montgomery_Int& Montgomery_Int::mul_by(const secure_vector& other, + secure_vector& ws) + { + m_params->mul_by(m_v, other, ws); + return (*this); + } + +Montgomery_Int& Montgomery_Int::operator*=(const Montgomery_Int& other) + { + secure_vector ws; + return mul_by(other, ws); + } + +Montgomery_Int& Montgomery_Int::operator*=(const secure_vector& other) + { + secure_vector ws; + return mul_by(other, ws); + } + +Montgomery_Int& Montgomery_Int::square_this_n_times(secure_vector& ws, size_t n) + { + for(size_t i = 0; i != n; ++i) + m_params->square_this(m_v, ws); + return (*this); + } + +Montgomery_Int& Montgomery_Int::square_this(secure_vector& ws) + { + m_params->square_this(m_v, ws); + return (*this); + } + +Montgomery_Int Montgomery_Int::square(secure_vector& ws) const + { + return Montgomery_Int(m_params, m_params->sqr(m_v, ws), false); + } + +Montgomery_Int Montgomery_Int::multiplicative_inverse() const + { + secure_vector ws; + const BigInt iv = m_params->mul(m_params->inv_mod_p(m_v), m_params->R3(), ws); + return Montgomery_Int(m_params, iv, false); + } + +Montgomery_Int Montgomery_Int::additive_inverse() const + { + return Montgomery_Int(m_params, m_params->p()) - (*this); + } + +Montgomery_Int& Montgomery_Int::mul_by_2(secure_vector& ws) + { + m_v <<= 1; + m_v.reduce_below(m_params->p(), ws); + return (*this); + } + +Montgomery_Int& Montgomery_Int::mul_by_3(secure_vector& ws) + { + m_v *= 3; + m_v.reduce_below(m_params->p(), ws); + return (*this); + } + +Montgomery_Int& Montgomery_Int::mul_by_4(secure_vector& ws) + { + m_v <<= 2; + m_v.reduce_below(m_params->p(), ws); + return (*this); + } + +Montgomery_Int& Montgomery_Int::mul_by_8(secure_vector& ws) + { + m_v <<= 3; + m_v.reduce_below(m_params->p(), ws); + return (*this); + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/math/numbertheory/monty.h b/src/libs/3rdparty/botan/src/lib/math/numbertheory/monty.h new file mode 100644 index 0000000000..e5ab2f9ada --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/math/numbertheory/monty.h @@ -0,0 +1,190 @@ +/* +* (C) 2018 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_MONTY_INT_H_ +#define BOTAN_MONTY_INT_H_ + +#include + +namespace Botan { + +class Modular_Reducer; + +class Montgomery_Params; + +/** +* The Montgomery representation of an integer +*/ +class BOTAN_UNSTABLE_API Montgomery_Int final + { + public: + /** + * Create a zero-initialized Montgomery_Int + */ + Montgomery_Int(std::shared_ptr params) : m_params(params) {} + + /** + * Create a Montgomery_Int + */ + Montgomery_Int(std::shared_ptr params, + const BigInt& v, + bool redc_needed = true); + + /** + * Create a Montgomery_Int + */ + Montgomery_Int(std::shared_ptr params, + const uint8_t bits[], size_t len, + bool redc_needed = true); + + /** + * Create a Montgomery_Int + */ + Montgomery_Int(std::shared_ptr params, + const word words[], size_t len, + bool redc_needed = true); + + bool operator==(const Montgomery_Int& other) const; + bool operator!=(const Montgomery_Int& other) const { return (m_v != other.m_v); } + + std::vector serialize() const; + + size_t size() const; + bool is_one() const; + bool is_zero() const; + + void fix_size(); + + /** + * Return the value to normal mod-p space + */ + BigInt value() const; + + /** + * Return the Montgomery representation + */ + const BigInt& repr() const { return m_v; } + + Montgomery_Int operator+(const Montgomery_Int& other) const; + + Montgomery_Int operator-(const Montgomery_Int& other) const; + + Montgomery_Int& operator+=(const Montgomery_Int& other); + + Montgomery_Int& operator-=(const Montgomery_Int& other); + + Montgomery_Int operator*(const Montgomery_Int& other) const; + + Montgomery_Int& operator*=(const Montgomery_Int& other); + + Montgomery_Int& operator*=(const secure_vector& other); + + Montgomery_Int& add(const Montgomery_Int& other, + secure_vector& ws); + + Montgomery_Int& sub(const Montgomery_Int& other, + secure_vector& ws); + + Montgomery_Int mul(const Montgomery_Int& other, + secure_vector& ws) const; + + Montgomery_Int& mul_by(const Montgomery_Int& other, + secure_vector& ws); + + Montgomery_Int& mul_by(const secure_vector& other, + secure_vector& ws); + + Montgomery_Int square(secure_vector& ws) const; + + Montgomery_Int& square_this(secure_vector& ws); + + Montgomery_Int& square_this_n_times(secure_vector& ws, size_t n); + + Montgomery_Int multiplicative_inverse() const; + + Montgomery_Int additive_inverse() const; + + Montgomery_Int& mul_by_2(secure_vector& ws); + + Montgomery_Int& mul_by_3(secure_vector& ws); + + Montgomery_Int& mul_by_4(secure_vector& ws); + + Montgomery_Int& mul_by_8(secure_vector& ws); + + void const_time_poison() const { m_v.const_time_poison(); } + void const_time_unpoison() const { return m_v.const_time_unpoison(); } + + private: + std::shared_ptr m_params; + BigInt m_v; + }; + +/** +* Parameters for Montgomery Reduction +*/ +class BOTAN_UNSTABLE_API Montgomery_Params final + { + public: + /** + * Initialize a set of Montgomery reduction parameters. These values + * can be shared by all values in a specific Montgomery domain. + */ + Montgomery_Params(const BigInt& p, const Modular_Reducer& mod_p); + + /** + * Initialize a set of Montgomery reduction parameters. These values + * can be shared by all values in a specific Montgomery domain. + */ + Montgomery_Params(const BigInt& p); + + const BigInt& p() const { return m_p; } + const BigInt& R1() const { return m_r1; } + const BigInt& R2() const { return m_r2; } + const BigInt& R3() const { return m_r3; } + + word p_dash() const { return m_p_dash; } + + size_t p_words() const { return m_p_words; } + + BigInt redc(const BigInt& x, + secure_vector& ws) const; + + BigInt mul(const BigInt& x, + const BigInt& y, + secure_vector& ws) const; + + BigInt mul(const BigInt& x, + const secure_vector& y, + secure_vector& ws) const; + + void mul_by(BigInt& x, + const secure_vector& y, + secure_vector& ws) const; + + void mul_by(BigInt& x, const BigInt& y, + secure_vector& ws) const; + + BigInt sqr(const BigInt& x, + secure_vector& ws) const; + + void square_this(BigInt& x, + secure_vector& ws) const; + + BigInt inv_mod_p(const BigInt& x) const; + + private: + BigInt m_p; + BigInt m_r1; + BigInt m_r2; + BigInt m_r3; + word m_p_dash; + size_t m_p_words; + }; + +} + +#endif 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 new file mode 100644 index 0000000000..5674920915 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/math/numbertheory/monty_exp.cpp @@ -0,0 +1,248 @@ +/* +* Montgomery Exponentiation +* (C) 1999-2010,2012,2018 Jack Lloyd +* 2016 Matthias Gierlings +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include +#include +#include + +namespace Botan { + +class Montgomery_Exponentation_State + { + public: + Montgomery_Exponentation_State(std::shared_ptr params, + const BigInt& g, + size_t window_bits, + bool const_time); + + BigInt exponentiation(const BigInt& k, size_t max_k_bits) const; + + BigInt exponentiation_vartime(const BigInt& k) const; + private: + std::shared_ptr m_params; + std::vector m_g; + size_t m_window_bits; + bool m_const_time; + }; + +Montgomery_Exponentation_State::Montgomery_Exponentation_State(std::shared_ptr params, + const BigInt& g, + size_t window_bits, + bool const_time) : + m_params(params), + m_window_bits(window_bits == 0 ? 4 : window_bits), + m_const_time(const_time) + { + 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); + + m_g.reserve(window_size); + + m_g.push_back(Montgomery_Int(m_params, m_params->R1(), false)); + + m_g.push_back(Montgomery_Int(m_params, g)); + + const Montgomery_Int& monty_g = m_g[1]; + + for(size_t i = 2; i != window_size; ++i) + { + m_g.push_back(monty_g * m_g[i - 1]); + } + + // Resize each element to exactly p words + for(size_t i = 0; i != window_size; ++i) + { + m_g[i].fix_size(); + if(const_time) + m_g[i].const_time_poison(); + } + } + +namespace { + +void const_time_lookup(secure_vector& output, + const std::vector& g, + size_t nibble) + { + const size_t words = output.size(); + + clear_mem(output.data(), output.size()); + + for(size_t i = 0; i != g.size(); ++i) + { + const secure_vector& vec = g[i].repr().get_word_vector(); + + BOTAN_ASSERT(vec.size() >= words, + "Word size as expected in const_time_lookup"); + + const word mask = CT::is_equal(i, nibble); + + for(size_t w = 0; w != words; ++w) + output[w] |= (mask & vec[w]); + } + } + +} + +BigInt Montgomery_Exponentation_State::exponentiation(const BigInt& scalar, size_t max_k_bits) const + { + BOTAN_DEBUG_ASSERT(scalar.bits() <= max_k_bits); + // TODO add a const-time implementation of above assert and use it in release builds + + const size_t exp_nibbles = (max_k_bits + m_window_bits - 1) / m_window_bits; + + if(exp_nibbles == 0) + return 1; + + secure_vector e_bits(m_params->p_words()); + secure_vector ws; + + const_time_lookup(e_bits, m_g, scalar.get_substring(m_window_bits*(exp_nibbles-1), m_window_bits)); + Montgomery_Int x(m_params, e_bits.data(), e_bits.size(), false); + + for(size_t i = exp_nibbles - 1; i > 0; --i) + { + x.square_this_n_times(ws, m_window_bits); + const_time_lookup(e_bits, m_g, scalar.get_substring(m_window_bits*(i-1), m_window_bits)); + x.mul_by(e_bits, ws); + } + + x.const_time_unpoison(); + return x.value(); + } + +BigInt Montgomery_Exponentation_State::exponentiation_vartime(const BigInt& scalar) const + { + BOTAN_ASSERT_NOMSG(m_const_time == false); + + const size_t exp_nibbles = (scalar.bits() + m_window_bits - 1) / m_window_bits; + + secure_vector ws; + + if(exp_nibbles == 0) + return 1; + + Montgomery_Int x = m_g[scalar.get_substring(m_window_bits*(exp_nibbles-1), m_window_bits)]; + + for(size_t i = exp_nibbles - 1; i > 0; --i) + { + x.square_this_n_times(ws, m_window_bits); + + const uint32_t nibble = scalar.get_substring(m_window_bits*(i-1), m_window_bits); + if(nibble > 0) + x.mul_by(m_g[nibble], ws); + } + + x.const_time_unpoison(); + return x.value(); + } + +std::shared_ptr +monty_precompute(std::shared_ptr params, + const BigInt& g, + size_t window_bits, + bool const_time) + { + return std::make_shared(params, g, window_bits, const_time); + } + +BigInt monty_execute(const Montgomery_Exponentation_State& precomputed_state, + const BigInt& k, size_t max_k_bits) + { + return precomputed_state.exponentiation(k, max_k_bits); + } + +BigInt monty_execute_vartime(const Montgomery_Exponentation_State& precomputed_state, + const BigInt& k) + { + return precomputed_state.exponentiation_vartime(k); + } + +BigInt monty_multi_exp(std::shared_ptr params_p, + const BigInt& x_bn, + const BigInt& z1, + const BigInt& y_bn, + const BigInt& z2) + { + if(z1.is_negative() || z2.is_negative()) + throw Invalid_Argument("multi_exponentiate exponents must be positive"); + + const size_t z_bits = round_up(std::max(z1.bits(), z2.bits()), 2); + + secure_vector ws; + + const Montgomery_Int one(params_p, params_p->R1(), false); + //const Montgomery_Int one(params_p, 1); + + const Montgomery_Int x1(params_p, x_bn); + const Montgomery_Int x2 = x1.square(ws); + const Montgomery_Int x3 = x2.mul(x1, ws); + + const Montgomery_Int y1(params_p, y_bn); + const Montgomery_Int y2 = y1.square(ws); + const Montgomery_Int y3 = y2.mul(y1, ws); + + const Montgomery_Int y1x1 = y1.mul(x1, ws); + const Montgomery_Int y1x2 = y1.mul(x2, ws); + const Montgomery_Int y1x3 = y1.mul(x3, ws); + + const Montgomery_Int y2x1 = y2.mul(x1, ws); + const Montgomery_Int y2x2 = y2.mul(x2, ws); + const Montgomery_Int y2x3 = y2.mul(x3, ws); + + const Montgomery_Int y3x1 = y3.mul(x1, ws); + const Montgomery_Int y3x2 = y3.mul(x2, ws); + const Montgomery_Int y3x3 = y3.mul(x3, ws); + + const Montgomery_Int* M[16] = { + &one, + &x1, // 0001 + &x2, // 0010 + &x3, // 0011 + &y1, // 0100 + &y1x1, + &y1x2, + &y1x3, + &y2, // 1000 + &y2x1, + &y2x2, + &y2x3, + &y3, // 1100 + &y3x1, + &y3x2, + &y3x3 + }; + + Montgomery_Int H = one; + + for(size_t i = 0; i != z_bits; i += 2) + { + if(i > 0) + { + H.square_this(ws); + 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 uint8_t z12 = (4*z2_b) + z1_b; + + H.mul_by(*M[z12], ws); + } + + return H.value(); + } + +} + diff --git a/src/libs/3rdparty/botan/src/lib/math/numbertheory/monty_exp.h b/src/libs/3rdparty/botan/src/lib/math/numbertheory/monty_exp.h new file mode 100644 index 0000000000..632d7f7d6e --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/math/numbertheory/monty_exp.h @@ -0,0 +1,54 @@ +/* +* (C) 2018 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_MONTY_EXP_H_ +#define BOTAN_MONTY_EXP_H_ + +#include + +namespace Botan { + +class BigInt; +class Modular_Reducer; + +class Montgomery_Params; + +class Montgomery_Exponentation_State; + +/* +* Precompute for calculating values g^x mod p +*/ +std::shared_ptr +monty_precompute(std::shared_ptr params_p, + const BigInt& g, + size_t window_bits, + bool const_time = true); + +/* +* Return g^k mod p +*/ +BigInt monty_execute(const Montgomery_Exponentation_State& precomputed_state, + const BigInt& k, size_t max_k_bits); + +/* +* Return g^k mod p taking variable time depending on k +* @warning only use this if k is public +*/ +BigInt monty_execute_vartime(const Montgomery_Exponentation_State& precomputed_state, + const BigInt& k); + +/** +* Return (x^z1 * y^z2) % p +*/ +BigInt monty_multi_exp(std::shared_ptr params_p, + const BigInt& x, + const BigInt& z1, + const BigInt& y, + const BigInt& z2); + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/math/numbertheory/mp_numth.cpp b/src/libs/3rdparty/botan/src/lib/math/numbertheory/mp_numth.cpp new file mode 100644 index 0000000000..eef6419965 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/math/numbertheory/mp_numth.cpp @@ -0,0 +1,84 @@ +/* +* Fused and Important MP Algorithms +* (C) 1999-2007 Jack Lloyd +* 2016 Matthias Gierlings +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include + +namespace Botan { + +/* +* Square a BigInt +*/ +BigInt square(const BigInt& x) + { + BigInt z = x; + secure_vector ws; + z.square(ws); + return z; + } + +/* +* Multiply-Add Operation +*/ +BigInt mul_add(const BigInt& a, const BigInt& b, const BigInt& c) + { + if(c.is_negative()) + throw Invalid_Argument("mul_add: Third argument must be > 0"); + + BigInt::Sign sign = BigInt::Positive; + if(a.sign() != b.sign()) + sign = BigInt::Negative; + + const size_t a_sw = a.sig_words(); + const size_t b_sw = b.sig_words(); + const size_t c_sw = c.sig_words(); + + BigInt r(sign, std::max(a_sw + b_sw, c_sw) + 1); + secure_vector workspace(r.size()); + + bigint_mul(r.mutable_data(), r.size(), + a.data(), a.size(), a_sw, + b.data(), b.size(), b_sw, + workspace.data(), workspace.size()); + + const size_t r_size = std::max(r.sig_words(), c_sw); + bigint_add2(r.mutable_data(), r_size, c.data(), c_sw); + return r; + } + +/* +* Subtract-Multiply Operation +*/ +BigInt sub_mul(const BigInt& a, const BigInt& b, const BigInt& c) + { + if(a.is_negative() || b.is_negative()) + throw Invalid_Argument("sub_mul: First two arguments must be >= 0"); + + BigInt r = a; + r -= b; + r *= c; + return r; + } + +/* +* Multiply-Subtract Operation +*/ +BigInt mul_sub(const BigInt& a, const BigInt& b, const BigInt& c) + { + if(c.is_negative() || c.is_zero()) + throw Invalid_Argument("mul_sub: Third argument must be > 0"); + + BigInt r = a; + r *= b; + r -= c; + return r; + } + +} 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 new file mode 100644 index 0000000000..b74a2f9c6b --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/math/numbertheory/nistp_redc.cpp @@ -0,0 +1,623 @@ +/* +* NIST prime reductions +* (C) 2014,2015,2018 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include + +namespace Botan { + +const BigInt& prime_p521() + { + static const BigInt p521("0x1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"); + + return p521; + } + +void redc_p521(BigInt& x, secure_vector& ws) + { + const size_t p_full_words = 521 / BOTAN_MP_WORD_BITS; + const size_t p_top_bits = 521 % BOTAN_MP_WORD_BITS; + const size_t p_words = p_full_words + 1; + + const size_t x_sw = x.sig_words(); + + if(x_sw < p_words) + return; // already smaller + + if(ws.size() < p_words + 1) + ws.resize(p_words + 1); + + clear_mem(ws.data(), ws.size()); + bigint_shr2(ws.data(), x.data(), x_sw, p_full_words, p_top_bits); + + x.mask_bits(521); + + // Word-level carry will be zero + word carry = bigint_add3_nc(x.mutable_data(), x.data(), p_words, ws.data(), p_words); + 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); + +#if (BOTAN_MP_WORD_BITS == 64) + static const word p521_words[9] = { + 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, + 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, + 0x1FF }; +#endif + + /* + * If bit 522 is set then we overflowed and must reduce. Otherwise, if the + * top bit is set, it is possible we have x == 2**521 - 1 so check for that. + */ + if(bit_522_set) + { +#if (BOTAN_MP_WORD_BITS == 64) + bigint_sub2(x.mutable_data(), x.size(), p521_words, 9); +#else + x -= prime_p521(); +#endif + } + else if(x.word_at(p_full_words) >> (p_top_bits - 1)) + { + /* + * Otherwise we must reduce if p is exactly 2^512-1 + */ + + word possibly_521 = MP_WORD_MAX; + for(size_t i = 0; i != p_full_words; ++i) + possibly_521 &= x.word_at(i); + + if(possibly_521 == MP_WORD_MAX) + x.reduce_below(prime_p521(), ws); + } + } + +#if defined(BOTAN_HAS_NIST_PRIME_REDUCERS_W32) + +namespace { + +/** +* Treating this MPI as a sequence of 32-bit words in big-endian +* order, return word i (or 0 if out of range) +*/ +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(x.word_at(i/2) >> ((i % 2)*32)); +#else + #error "Not implemented" +#endif + } + +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(R1) << 32) | R0); +#else + #error "Not implemented" +#endif + } + +} + +const BigInt& prime_p192() + { + static const BigInt p192("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF"); + return p192; + } + +void redc_p192(BigInt& x, secure_vector& ws) + { + BOTAN_UNUSED(ws); + + static const size_t p192_limbs = 192 / BOTAN_MP_WORD_BITS; + + const uint64_t X00 = get_uint32_t(x, 0); + const uint64_t X01 = get_uint32_t(x, 1); + const uint64_t X02 = get_uint32_t(x, 2); + const uint64_t X03 = get_uint32_t(x, 3); + const uint64_t X04 = get_uint32_t(x, 4); + const uint64_t X05 = get_uint32_t(x, 5); + const uint64_t X06 = get_uint32_t(x, 6); + const uint64_t X07 = get_uint32_t(x, 7); + const uint64_t X08 = get_uint32_t(x, 8); + const uint64_t X09 = get_uint32_t(x, 9); + const uint64_t X10 = get_uint32_t(x, 10); + const uint64_t X11 = get_uint32_t(x, 11); + + const uint64_t S0 = X00 + X06 + X10; + const uint64_t S1 = X01 + X07 + X11; + const uint64_t S2 = X02 + X06 + X08 + X10; + const uint64_t S3 = X03 + X07 + X09 + X11; + const uint64_t S4 = X04 + X08 + X10; + const uint64_t S5 = X05 + X09 + X11; + + x.mask_bits(192); + + uint64_t S = 0; + uint32_t R0 = 0, R1 = 0; + + S += S0; + R0 = static_cast(S); + S >>= 32; + + S += S1; + R1 = static_cast(S); + S >>= 32; + + set_words(x, 0, R0, R1); + + S += S2; + R0 = static_cast(S); + S >>= 32; + + S += S3; + R1 = static_cast(S); + S >>= 32; + + set_words(x, 2, R0, R1); + + S += S4; + R0 = static_cast(S); + S >>= 32; + + S += S5; + R1 = static_cast(S); + S >>= 32; + + set_words(x, 4, R0, R1); + + // No underflow possible + + BOTAN_ASSERT(S <= 2, "Expected overflow in P-192 reduce"); + + /* + This is a table of (i*P-192) % 2**192 for i in 1...3 + */ + static const word p192_mults[3][p192_limbs] = { +#if (BOTAN_MP_WORD_BITS == 64) + {0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFE, 0xFFFFFFFFFFFFFFFF}, + {0xFFFFFFFFFFFFFFFE, 0xFFFFFFFFFFFFFFFD, 0xFFFFFFFFFFFFFFFF}, + {0xFFFFFFFFFFFFFFFD, 0xFFFFFFFFFFFFFFFC, 0xFFFFFFFFFFFFFFFF}, +#else + {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}, + {0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}, + {0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFC, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}, +#endif + }; + + if(S == 0 && x.word_at(p192_limbs-1) < p192_mults[0][p192_limbs-1]) + { + return; + } + + word borrow = bigint_sub2(x.mutable_data(), x.size(), p192_mults[S], p192_limbs); + + BOTAN_ASSERT(borrow == 0 || borrow == 1, "Expected borrow during P-192 reduction"); + + if(borrow) + { + bigint_add2(x.mutable_data(), x.size() - 1, p192_mults[0], p192_limbs); + } + } + +const BigInt& prime_p224() + { + static const BigInt p224("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001"); + return p224; + } + +void redc_p224(BigInt& x, secure_vector& ws) + { + static const size_t p224_limbs = (BOTAN_MP_WORD_BITS == 32) ? 7 : 4; + + BOTAN_UNUSED(ws); + + const int64_t X00 = get_uint32_t(x, 0); + const int64_t X01 = get_uint32_t(x, 1); + const int64_t X02 = get_uint32_t(x, 2); + const int64_t X03 = get_uint32_t(x, 3); + const int64_t X04 = get_uint32_t(x, 4); + const int64_t X05 = get_uint32_t(x, 5); + const int64_t X06 = get_uint32_t(x, 6); + const int64_t X07 = get_uint32_t(x, 7); + const int64_t X08 = get_uint32_t(x, 8); + const int64_t X09 = get_uint32_t(x, 9); + const int64_t X10 = get_uint32_t(x, 10); + const int64_t X11 = get_uint32_t(x, 11); + const int64_t X12 = get_uint32_t(x, 12); + const int64_t X13 = get_uint32_t(x, 13); + + // One full copy of P224 is added, so the result is always positive + + const int64_t S0 = 0x00000001 + X00 - X07 - X11; + const int64_t S1 = 0x00000000 + X01 - X08 - X12; + const int64_t S2 = 0x00000000 + X02 - X09 - X13; + const int64_t S3 = 0xFFFFFFFF + X03 + X07 + X11 - X10; + const int64_t S4 = 0xFFFFFFFF + X04 + X08 + X12 - X11; + const int64_t S5 = 0xFFFFFFFF + X05 + X09 + X13 - X12; + const int64_t S6 = 0xFFFFFFFF + X06 + X10 - X13; + + x.mask_bits(224); + x.shrink_to_fit(p224_limbs + 1); + + int64_t S = 0; + uint32_t R0 = 0, R1 = 0; + + S += S0; + R0 = static_cast(S); + S >>= 32; + + S += S1; + R1 = static_cast(S); + S >>= 32; + + set_words(x, 0, R0, R1); + + S += S2; + R0 = static_cast(S); + S >>= 32; + + S += S3; + R1 = static_cast(S); + S >>= 32; + + set_words(x, 2, R0, R1); + + S += S4; + R0 = static_cast(S); + S >>= 32; + + S += S5; + R1 = static_cast(S); + S >>= 32; + + set_words(x, 4, R0, R1); + + S += S6; + R0 = static_cast(S); + S >>= 32; + + set_words(x, 6, R0, 0); + + BOTAN_ASSERT(S >= 0 && S <= 2, "Expected overflow in P-224 reduce"); + + static const word p224_mults[3][p224_limbs] = { +#if (BOTAN_MP_WORD_BITS == 64) + {0x0000000000000001, 0xFFFFFFFF00000000, 0xFFFFFFFFFFFFFFFF, 0x00000000FFFFFFFF}, + {0x0000000000000002, 0xFFFFFFFE00000000, 0xFFFFFFFFFFFFFFFF, 0x00000000FFFFFFFF}, + {0x0000000000000003, 0xFFFFFFFD00000000, 0xFFFFFFFFFFFFFFFF, 0x00000000FFFFFFFF}, +#else + {0x00000001, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}, + {0x00000002, 0x00000000, 0x00000000, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}, + {0x00000003, 0x00000000, 0x00000000, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF} +#endif + + }; + + if(S == 0 && x.word_at(p224_limbs-1) < p224_mults[0][p224_limbs-1]) + { + return; + } + + word borrow = bigint_sub2(x.mutable_data(), x.size(), p224_mults[S], p224_limbs); + + BOTAN_ASSERT(borrow == 0 || borrow == 1, "Expected borrow during P-224 reduction"); + + if(borrow) + { + bigint_add2(x.mutable_data(), x.size() - 1, p224_mults[0], p224_limbs); + } + } + +const BigInt& prime_p256() + { + static const BigInt p256("0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF"); + return p256; + } + +void redc_p256(BigInt& x, secure_vector& ws) + { + static const size_t p256_limbs = (BOTAN_MP_WORD_BITS == 32) ? 8 : 4; + + BOTAN_UNUSED(ws); + + const int64_t X00 = get_uint32_t(x, 0); + const int64_t X01 = get_uint32_t(x, 1); + const int64_t X02 = get_uint32_t(x, 2); + const int64_t X03 = get_uint32_t(x, 3); + const int64_t X04 = get_uint32_t(x, 4); + const int64_t X05 = get_uint32_t(x, 5); + const int64_t X06 = get_uint32_t(x, 6); + const int64_t X07 = get_uint32_t(x, 7); + const int64_t X08 = get_uint32_t(x, 8); + const int64_t X09 = get_uint32_t(x, 9); + const int64_t X10 = get_uint32_t(x, 10); + const int64_t X11 = get_uint32_t(x, 11); + const int64_t X12 = get_uint32_t(x, 12); + const int64_t X13 = get_uint32_t(x, 13); + const int64_t X14 = get_uint32_t(x, 14); + const int64_t X15 = get_uint32_t(x, 15); + + // Adds 6 * P-256 to prevent underflow + const int64_t S0 = 0xFFFFFFFA + X00 + X08 + X09 - X11 - X12 - X13 - X14; + const int64_t S1 = 0xFFFFFFFF + X01 + X09 + X10 - X12 - X13 - X14 - X15; + const int64_t S2 = 0xFFFFFFFF + X02 + X10 + X11 - X13 - X14 - X15; + const int64_t S3 = 0x00000005 + X03 + (X11 + X12)*2 + X13 - X15 - X08 - X09; + const int64_t S4 = 0x00000000 + X04 + (X12 + X13)*2 + X14 - X09 - X10; + const int64_t S5 = 0x00000000 + X05 + (X13 + X14)*2 + X15 - X10 - X11; + const int64_t S6 = 0x00000006 + X06 + X13 + X14*3 + X15*2 - X08 - X09; + const int64_t S7 = 0xFFFFFFFA + X07 + X15*3 + X08 - X10 - X11 - X12 - X13; + + x.mask_bits(256); + x.shrink_to_fit(p256_limbs + 1); + + int64_t S = 0; + + uint32_t R0 = 0, R1 = 0; + + S += S0; + R0 = static_cast(S); + S >>= 32; + + S += S1; + R1 = static_cast(S); + S >>= 32; + + set_words(x, 0, R0, R1); + + S += S2; + R0 = static_cast(S); + S >>= 32; + + S += S3; + R1 = static_cast(S); + S >>= 32; + + set_words(x, 2, R0, R1); + + S += S4; + R0 = static_cast(S); + S >>= 32; + + S += S5; + R1 = static_cast(S); + S >>= 32; + + set_words(x, 4, R0, R1); + + S += S6; + R0 = static_cast(S); + S >>= 32; + + S += S7; + R1 = static_cast(S); + S >>= 32; + set_words(x, 6, R0, R1); + + S += 5; // the top digits of 6*P-256 + + BOTAN_ASSERT(S >= 0 && S <= 10, "Expected overflow"); + + /* + This is a table of (i*P-256) % 2**256 for i in 1...10 + */ + static const word p256_mults[11][p256_limbs] = { +#if (BOTAN_MP_WORD_BITS == 64) + {0xFFFFFFFFFFFFFFFF, 0x00000000FFFFFFFF, 0x0000000000000000, 0xFFFFFFFF00000001}, + {0xFFFFFFFFFFFFFFFE, 0x00000001FFFFFFFF, 0x0000000000000000, 0xFFFFFFFE00000002}, + {0xFFFFFFFFFFFFFFFD, 0x00000002FFFFFFFF, 0x0000000000000000, 0xFFFFFFFD00000003}, + {0xFFFFFFFFFFFFFFFC, 0x00000003FFFFFFFF, 0x0000000000000000, 0xFFFFFFFC00000004}, + {0xFFFFFFFFFFFFFFFB, 0x00000004FFFFFFFF, 0x0000000000000000, 0xFFFFFFFB00000005}, + {0xFFFFFFFFFFFFFFFA, 0x00000005FFFFFFFF, 0x0000000000000000, 0xFFFFFFFA00000006}, + {0xFFFFFFFFFFFFFFF9, 0x00000006FFFFFFFF, 0x0000000000000000, 0xFFFFFFF900000007}, + {0xFFFFFFFFFFFFFFF8, 0x00000007FFFFFFFF, 0x0000000000000000, 0xFFFFFFF800000008}, + {0xFFFFFFFFFFFFFFF7, 0x00000008FFFFFFFF, 0x0000000000000000, 0xFFFFFFF700000009}, + {0xFFFFFFFFFFFFFFF6, 0x00000009FFFFFFFF, 0x0000000000000000, 0xFFFFFFF60000000A}, + {0xFFFFFFFFFFFFFFF5, 0x0000000AFFFFFFFF, 0x0000000000000000, 0xFFFFFFF50000000B}, +#else + {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0xFFFFFFFF}, + {0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000001, 0x00000000, 0x00000000, 0x00000002, 0xFFFFFFFE}, + {0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000002, 0x00000000, 0x00000000, 0x00000003, 0xFFFFFFFD}, + {0xFFFFFFFC, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000003, 0x00000000, 0x00000000, 0x00000004, 0xFFFFFFFC}, + {0xFFFFFFFB, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000004, 0x00000000, 0x00000000, 0x00000005, 0xFFFFFFFB}, + {0xFFFFFFFA, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000005, 0x00000000, 0x00000000, 0x00000006, 0xFFFFFFFA}, + {0xFFFFFFF9, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000006, 0x00000000, 0x00000000, 0x00000007, 0xFFFFFFF9}, + {0xFFFFFFF8, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000007, 0x00000000, 0x00000000, 0x00000008, 0xFFFFFFF8}, + {0xFFFFFFF7, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000008, 0x00000000, 0x00000000, 0x00000009, 0xFFFFFFF7}, + {0xFFFFFFF6, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000009, 0x00000000, 0x00000000, 0x0000000A, 0xFFFFFFF6}, + {0xFFFFFFF5, 0xFFFFFFFF, 0xFFFFFFFF, 0x0000000A, 0x00000000, 0x00000000, 0x0000000B, 0xFFFFFFF5}, +#endif + }; + + if(S == 0 && x.word_at(p256_limbs-1) < p256_mults[0][p256_limbs-1]) + { + return; + } + + word borrow = bigint_sub2(x.mutable_data(), x.size(), p256_mults[S], p256_limbs); + + BOTAN_ASSERT(borrow == 0 || borrow == 1, "Expected borrow during P-256 reduction"); + + if(borrow) + { + bigint_add2(x.mutable_data(), x.size() - 1, p256_mults[0], p256_limbs); + } + } + +const BigInt& prime_p384() + { + static const BigInt p384("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF"); + return p384; + } + +void redc_p384(BigInt& x, secure_vector& ws) + { + BOTAN_UNUSED(ws); + + static const size_t p384_limbs = (BOTAN_MP_WORD_BITS == 32) ? 12 : 6; + + const int64_t X00 = get_uint32_t(x, 0); + const int64_t X01 = get_uint32_t(x, 1); + const int64_t X02 = get_uint32_t(x, 2); + const int64_t X03 = get_uint32_t(x, 3); + const int64_t X04 = get_uint32_t(x, 4); + const int64_t X05 = get_uint32_t(x, 5); + const int64_t X06 = get_uint32_t(x, 6); + const int64_t X07 = get_uint32_t(x, 7); + const int64_t X08 = get_uint32_t(x, 8); + const int64_t X09 = get_uint32_t(x, 9); + const int64_t X10 = get_uint32_t(x, 10); + const int64_t X11 = get_uint32_t(x, 11); + const int64_t X12 = get_uint32_t(x, 12); + const int64_t X13 = get_uint32_t(x, 13); + const int64_t X14 = get_uint32_t(x, 14); + const int64_t X15 = get_uint32_t(x, 15); + const int64_t X16 = get_uint32_t(x, 16); + const int64_t X17 = get_uint32_t(x, 17); + const int64_t X18 = get_uint32_t(x, 18); + const int64_t X19 = get_uint32_t(x, 19); + const int64_t X20 = get_uint32_t(x, 20); + const int64_t X21 = get_uint32_t(x, 21); + const int64_t X22 = get_uint32_t(x, 22); + const int64_t X23 = get_uint32_t(x, 23); + + // One copy of P-384 is added to prevent underflow + const int64_t S0 = 0xFFFFFFFF + X00 + X12 + X20 + X21 - X23; + const int64_t S1 = 0x00000000 + X01 + X13 + X22 + X23 - X12 - X20; + const int64_t S2 = 0x00000000 + X02 + X14 + X23 - X13 - X21; + const int64_t S3 = 0xFFFFFFFF + X03 + X12 + X15 + X20 + X21 - X14 - X22 - X23; + const int64_t S4 = 0xFFFFFFFE + X04 + X12 + X13 + X16 + X20 + X21*2 + X22 - X15 - X23*2; + const int64_t S5 = 0xFFFFFFFF + X05 + X13 + X14 + X17 + X21 + X22*2 + X23 - X16; + const int64_t S6 = 0xFFFFFFFF + X06 + X14 + X15 + X18 + X22 + X23*2 - X17; + const int64_t S7 = 0xFFFFFFFF + X07 + X15 + X16 + X19 + X23 - X18; + const int64_t S8 = 0xFFFFFFFF + X08 + X16 + X17 + X20 - X19; + const int64_t S9 = 0xFFFFFFFF + X09 + X17 + X18 + X21 - X20; + const int64_t SA = 0xFFFFFFFF + X10 + X18 + X19 + X22 - X21; + const int64_t SB = 0xFFFFFFFF + X11 + X19 + X20 + X23 - X22; + + x.mask_bits(384); + x.shrink_to_fit(p384_limbs + 1); + + int64_t S = 0; + + uint32_t R0 = 0, R1 = 0; + + S += S0; + R0 = static_cast(S); + S >>= 32; + + S += S1; + R1 = static_cast(S); + S >>= 32; + + set_words(x, 0, R0, R1); + + S += S2; + R0 = static_cast(S); + S >>= 32; + + S += S3; + R1 = static_cast(S); + S >>= 32; + + set_words(x, 2, R0, R1); + + S += S4; + R0 = static_cast(S); + S >>= 32; + + S += S5; + R1 = static_cast(S); + S >>= 32; + + set_words(x, 4, R0, R1); + + S += S6; + R0 = static_cast(S); + S >>= 32; + + S += S7; + R1 = static_cast(S); + S >>= 32; + + set_words(x, 6, R0, R1); + + S += S8; + R0 = static_cast(S); + S >>= 32; + + S += S9; + R1 = static_cast(S); + S >>= 32; + + set_words(x, 8, R0, R1); + + S += SA; + R0 = static_cast(S); + S >>= 32; + + S += SB; + R1 = static_cast(S); + S >>= 32; + + set_words(x, 10, R0, R1); + + BOTAN_ASSERT(S >= 0 && S <= 4, "Expected overflow in P-384 reduction"); + + /* + This is a table of (i*P-384) % 2**384 for i in 1...4 + */ + static const word p384_mults[5][p384_limbs] = { +#if (BOTAN_MP_WORD_BITS == 64) + {0x00000000FFFFFFFF, 0xFFFFFFFF00000000, 0xFFFFFFFFFFFFFFFE, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF}, + {0x00000001FFFFFFFE, 0xFFFFFFFE00000000, 0xFFFFFFFFFFFFFFFD, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF}, + {0x00000002FFFFFFFD, 0xFFFFFFFD00000000, 0xFFFFFFFFFFFFFFFC, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF}, + {0x00000003FFFFFFFC, 0xFFFFFFFC00000000, 0xFFFFFFFFFFFFFFFB, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF}, + {0x00000004FFFFFFFB, 0xFFFFFFFB00000000, 0xFFFFFFFFFFFFFFFA, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF}, + +#else + {0xFFFFFFFF, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}, + {0xFFFFFFFE, 0x00000001, 0x00000000, 0xFFFFFFFE, 0xFFFFFFFD, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}, + {0xFFFFFFFD, 0x00000002, 0x00000000, 0xFFFFFFFD, 0xFFFFFFFC, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}, + {0xFFFFFFFC, 0x00000003, 0x00000000, 0xFFFFFFFC, 0xFFFFFFFB, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}, + {0xFFFFFFFB, 0x00000004, 0x00000000, 0xFFFFFFFB, 0xFFFFFFFA, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}, +#endif + }; + + if(S == 0 && x.word_at(p384_limbs-1) < p384_mults[0][p384_limbs-1]) + { + return; + } + + word borrow = bigint_sub2(x.mutable_data(), x.size(), p384_mults[S], p384_limbs); + + BOTAN_ASSERT(borrow == 0 || borrow == 1, "Expected borrow during P-384 reduction"); + + if(borrow) + { + bigint_add2(x.mutable_data(), x.size() - 1, p384_mults[0], p384_limbs); + } + } + +#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 new file mode 100644 index 0000000000..a312ba3a1c --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/math/numbertheory/numthry.cpp @@ -0,0 +1,566 @@ +/* +* Number Theory Functions +* (C) 1999-2011,2016,2018 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Botan { + +/* +* Return the number of 0 bits at the end of n +*/ +size_t low_zero_bits(const BigInt& n) + { + size_t low_zero = 0; + + if(n.is_positive() && n.is_nonzero()) + { + for(size_t i = 0; i != n.size(); ++i) + { + const word x = n.word_at(i); + + if(x) + { + low_zero += ctz(x); + break; + } + else + low_zero += BOTAN_MP_WORD_BITS; + } + } + + return low_zero; + } + +/* +* Calculate the GCD +*/ +BigInt gcd(const BigInt& a, const BigInt& b) + { + if(a.is_zero() || b.is_zero()) + return 0; + if(a == 1 || b == 1) + return 1; + + BigInt X[2] = { a, b }; + X[0].set_sign(BigInt::Positive); + X[1].set_sign(BigInt::Positive); + + const size_t shift = std::min(low_zero_bits(X[0]), low_zero_bits(X[1])); + + X[0] >>= shift; + X[1] >>= shift; + + while(X[0].is_nonzero()) + { + X[0] >>= low_zero_bits(X[0]); + X[1] >>= low_zero_bits(X[1]); + + const uint8_t sel = static_cast(X[0] >= X[1]); + + X[sel^1] -= X[sel]; + X[sel^1] >>= 1; + } + + return (X[1] << shift); + } + +/* +* Calculate the LCM +*/ +BigInt lcm(const BigInt& a, const BigInt& b) + { + return ((a * b) / gcd(a, b)); + } + +/* +Sets result to a^-1 * 2^k mod a +with n <= k <= 2n +Returns k + +"The Montgomery Modular Inverse - Revisited" Çetin Koç, E. Savas +https://citeseerx.ist.psu.edu/viewdoc/citations?doi=10.1.1.75.8377 + +A const time implementation of this algorithm is described in +"Constant Time Modular Inversion" Joppe W. Bos +http://www.joppebos.com/files/CTInversion.pdf +*/ +size_t almost_montgomery_inverse(BigInt& result, + const BigInt& a, + const BigInt& p) + { + size_t k = 0; + + BigInt u = p, v = a, r = 0, s = 1; + + while(v > 0) + { + if(u.is_even()) + { + u >>= 1; + s <<= 1; + } + else if(v.is_even()) + { + v >>= 1; + r <<= 1; + } + else if(u > v) + { + u -= v; + u >>= 1; + r += s; + s <<= 1; + } + else + { + v -= u; + v >>= 1; + s += r; + r <<= 1; + } + + ++k; + } + + if(r >= p) + { + r -= p; + } + + result = p - r; + + return k; + } + +BigInt normalized_montgomery_inverse(const BigInt& a, const BigInt& p) + { + BigInt r; + size_t k = almost_montgomery_inverse(r, a, p); + + for(size_t i = 0; i != k; ++i) + { + if(r.is_odd()) + r += p; + r >>= 1; + } + + return r; + } + +BigInt ct_inverse_mod_odd_modulus(const BigInt& n, const BigInt& mod) + { + if(n.is_negative() || mod.is_negative()) + throw Invalid_Argument("ct_inverse_mod_odd_modulus: arguments must be non-negative"); + if(mod < 3 || mod.is_even()) + throw Invalid_Argument("Bad modulus to ct_inverse_mod_odd_modulus"); + if(n >= mod) + throw Invalid_Argument("ct_inverse_mod_odd_modulus n >= mod not supported"); + + /* + This uses a modular inversion algorithm designed by Niels Möller + and implemented in Nettle. The same algorithm was later also + adapted to GMP in mpn_sec_invert. + + It can be easily implemented in a way that does not depend on + secret branches or memory lookups, providing resistance against + some forms of side channel attack. + + There is also a description of the algorithm in Appendix 5 of "Fast + Software Polynomial Multiplication on ARM Processors using the NEON Engine" + by Danilo Câmara, Conrado P. L. Gouvêa, Julio López, and Ricardo + Dahab in LNCS 8182 + https://conradoplg.cryptoland.net/files/2010/12/mocrysen13.pdf + + Thanks to Niels for creating the algorithm, explaining some things + about it, and the reference to the paper. + */ + + // todo allow this to be pre-calculated and passed in as arg + BigInt mp1o2 = (mod + 1) >> 1; + + const size_t mod_words = mod.sig_words(); + BOTAN_ASSERT(mod_words > 0, "Not empty"); + + BigInt a = n; + BigInt b = mod; + BigInt u = 1, v = 0; + + a.grow_to(mod_words); + u.grow_to(mod_words); + v.grow_to(mod_words); + mp1o2.grow_to(mod_words); + + secure_vector& a_w = a.get_word_vector(); + secure_vector& b_w = b.get_word_vector(); + secure_vector& u_w = u.get_word_vector(); + secure_vector& v_w = v.get_word_vector(); + + CT::poison(a_w.data(), a_w.size()); + CT::poison(b_w.data(), b_w.size()); + CT::poison(u_w.data(), u_w.size()); + CT::poison(v_w.data(), v_w.size()); + + // Only n.bits() + mod.bits() iterations are required, but avoid leaking the size of n + size_t bits = 2 * mod.bits(); + + while(bits--) + { + /* + const word odd = a.is_odd(); + a -= odd * b; + const word underflow = a.is_negative(); + b += a * underflow; + a.set_sign(BigInt::Positive); + + a >>= 1; + + if(underflow) + { + std::swap(u, v); + } + + u -= odd * v; + u += u.is_negative() * mod; + + const word odd_u = u.is_odd(); + + u >>= 1; + u += mp1o2 * odd_u; + */ + + const word odd_a = a_w[0] & 1; + + //if(odd_a) a -= b + word underflow = bigint_cnd_sub(odd_a, a_w.data(), b_w.data(), mod_words); + + //if(underflow) { b -= a; a = abs(a); swap(u, v); } + bigint_cnd_add(underflow, b_w.data(), a_w.data(), mod_words); + bigint_cnd_abs(underflow, a_w.data(), mod_words); + bigint_cnd_swap(underflow, u_w.data(), v_w.data(), mod_words); + + // a >>= 1 + bigint_shr1(a_w.data(), mod_words, 0, 1); + + //if(odd_a) u -= v; + word borrow = bigint_cnd_sub(odd_a, u_w.data(), v_w.data(), mod_words); + + // if(borrow) u += p + bigint_cnd_add(borrow, u_w.data(), mod.data(), mod_words); + + const word odd_u = u_w[0] & 1; + + // u >>= 1 + bigint_shr1(u_w.data(), mod_words, 0, 1); + + //if(odd_u) u += mp1o2; + bigint_cnd_add(odd_u, u_w.data(), mp1o2.data(), mod_words); + } + + CT::unpoison(a_w.data(), a_w.size()); + CT::unpoison(b_w.data(), b_w.size()); + CT::unpoison(u_w.data(), u_w.size()); + CT::unpoison(v_w.data(), v_w.size()); + + BOTAN_ASSERT(a.is_zero(), "A is zero"); + + if(b != 1) + return 0; + + return v; + } + +/* +* Find the Modular Inverse +*/ +BigInt inverse_mod(const BigInt& n, const BigInt& mod) + { + if(mod.is_zero()) + throw BigInt::DivideByZero(); + if(mod.is_negative() || n.is_negative()) + throw Invalid_Argument("inverse_mod: arguments must be non-negative"); + + if(n.is_zero() || (n.is_even() && mod.is_even())) + return 0; // fast fail checks + + if(mod.is_odd() && n < mod) + return ct_inverse_mod_odd_modulus(n, mod); + + return inverse_euclid(n, mod); + } + +BigInt inverse_euclid(const BigInt& n, const BigInt& mod) + { + if(mod.is_zero()) + throw BigInt::DivideByZero(); + if(mod.is_negative() || n.is_negative()) + throw Invalid_Argument("inverse_mod: arguments must be non-negative"); + + if(n.is_zero() || (n.is_even() && mod.is_even())) + return 0; // fast fail checks + + BigInt u = mod, v = n; + BigInt A = 1, B = 0, C = 0, D = 1; + + while(u.is_nonzero()) + { + const size_t u_zero_bits = low_zero_bits(u); + u >>= u_zero_bits; + for(size_t i = 0; i != u_zero_bits; ++i) + { + if(A.is_odd() || B.is_odd()) + { A += n; B -= mod; } + A >>= 1; B >>= 1; + } + + const size_t v_zero_bits = low_zero_bits(v); + v >>= v_zero_bits; + for(size_t i = 0; i != v_zero_bits; ++i) + { + if(C.is_odd() || D.is_odd()) + { C += n; D -= mod; } + C >>= 1; D >>= 1; + } + + if(u >= v) { u -= v; A -= C; B -= D; } + else { v -= u; C -= A; D -= B; } + } + + if(v != 1) + return 0; // no modular inverse + + while(D.is_negative()) D += mod; + while(D >= mod) D -= mod; + + return D; + } + +word monty_inverse(word input) + { + if(input == 0) + throw Exception("monty_inverse: divide by zero"); + + word b = input; + word x2 = 1, x1 = 0, y2 = 0, y1 = 1; + + // First iteration, a = n+1 + word q = bigint_divop(1, 0, b); + word r = (MP_WORD_MAX - q*b) + 1; + word x = x2 - q*x1; + word y = y2 - q*y1; + + word a = b; + b = r; + x2 = x1; + x1 = x; + y2 = y1; + y1 = y; + + while(b > 0) + { + q = a / b; + r = a - q*b; + x = x2 - q*x1; + y = y2 - q*y1; + + a = b; + b = r; + x2 = x1; + x1 = x; + y2 = y1; + y1 = y; + } + + const word check = y2 * input; + BOTAN_ASSERT_EQUAL(check, 1, "monty_inverse result is inverse of input"); + + // Now invert in addition space + y2 = (MP_WORD_MAX - y2) + 1; + + return y2; + } + +/* +* Modular Exponentiation +*/ +BigInt power_mod(const BigInt& base, const BigInt& exp, const BigInt& mod) + { + if(mod.is_negative() || mod == 1) + { + return 0; + } + + if(base.is_zero() || mod.is_zero()) + { + if(exp.is_zero()) + return 1; + return 0; + } + + Power_Mod pow_mod(mod); + + /* + * Calling set_base before set_exponent means we end up using a + * minimal window. This makes sense given that here we know that any + * precomputation is wasted. + */ + + if(base.is_negative()) + { + pow_mod.set_base(-base); + pow_mod.set_exponent(exp); + if(exp.is_even()) + return pow_mod.execute(); + else + return (mod - pow_mod.execute()); + } + else + { + pow_mod.set_base(base); + pow_mod.set_exponent(exp); + return pow_mod.execute(); + } + } + +namespace { + +bool mr_witness(BigInt&& y, + const Modular_Reducer& reducer_n, + const BigInt& n_minus_1, size_t s) + { + 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 + } + +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 + + /* + * 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; + } + +} + +/* +* Test for primality using Miller-Rabin +*/ +bool is_prime(const BigInt& n, RandomNumberGenerator& rng, + size_t prob, bool is_random) + { + if(n == 2) + return true; + if(n <= 1 || n.is_even()) + return false; + + // Fast path testing for small numbers (<= 65521) + if(n <= PRIMES[PRIME_TABLE_SIZE-1]) + { + const uint16_t num = static_cast(n.word_at(0)); + + 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 Modular_Reducer mod_n(n); + auto monty_n = std::make_shared(n, mod_n); + + const size_t powm_window = 4; + + for(size_t i = 0; i != test_iterations; ++i) + { + 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)) + return false; + } + + return true; + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/math/numbertheory/numthry.h b/src/libs/3rdparty/botan/src/lib/math/numbertheory/numthry.h new file mode 100644 index 0000000000..7097979bd7 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/math/numbertheory/numthry.h @@ -0,0 +1,278 @@ +/* +* Number Theory Functions +* (C) 1999-2007 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_NUMBER_THEORY_H_ +#define BOTAN_NUMBER_THEORY_H_ + +#include + +namespace Botan { + +class RandomNumberGenerator; + +/** +* Fused multiply-add +* @param a an integer +* @param b an integer +* @param c an integer +* @return (a*b)+c +*/ +BigInt BOTAN_PUBLIC_API(2,0) mul_add(const BigInt& a, + const BigInt& b, + const BigInt& c); + +/** +* Fused subtract-multiply +* @param a an integer +* @param b an integer +* @param c an integer +* @return (a-b)*c +*/ +BigInt BOTAN_PUBLIC_API(2,0) sub_mul(const BigInt& a, + const BigInt& b, + const BigInt& c); + +/** +* Fused multiply-subtract +* @param a an integer +* @param b an integer +* @param c an integer +* @return (a*b)-c +*/ +BigInt BOTAN_PUBLIC_API(2,0) mul_sub(const BigInt& a, + const BigInt& b, + const BigInt& c); + +/** +* Return the absolute value +* @param n an integer +* @return absolute value of n +*/ +inline BigInt abs(const BigInt& n) { return n.abs(); } + +/** +* Compute the greatest common divisor +* @param x a positive integer +* @param y a positive integer +* @return gcd(x,y) +*/ +BigInt BOTAN_PUBLIC_API(2,0) gcd(const BigInt& x, const BigInt& y); + +/** +* Least common multiple +* @param x a positive integer +* @param y a positive integer +* @return z, smallest integer such that z % x == 0 and z % y == 0 +*/ +BigInt BOTAN_PUBLIC_API(2,0) lcm(const BigInt& x, const BigInt& y); + +/** +* @param x an integer +* @return (x*x) +*/ +BigInt BOTAN_PUBLIC_API(2,0) square(const BigInt& x); + +/** +* Modular inversion +* @param x a positive integer +* @param modulus a positive integer +* @return y st (x*y) % modulus == 1 or 0 if no such value +* Not const time +*/ +BigInt BOTAN_PUBLIC_API(2,0) inverse_mod(const BigInt& x, + const BigInt& modulus); + +/** +* Modular inversion using extended binary Euclidian algorithm +* @param x a positive integer +* @param modulus a positive integer +* @return y st (x*y) % modulus == 1 or 0 if no such value +* Not const time +*/ +BigInt BOTAN_PUBLIC_API(2,5) inverse_euclid(const BigInt& x, + const BigInt& modulus); + +/** +* Const time modular inversion +* Requires the modulus be odd +*/ +BigInt BOTAN_PUBLIC_API(2,0) ct_inverse_mod_odd_modulus(const BigInt& n, const BigInt& mod); + +/** +* Return a^-1 * 2^k mod b +* Returns k, between n and 2n +* Not const time +*/ +size_t BOTAN_PUBLIC_API(2,0) almost_montgomery_inverse(BigInt& result, + const BigInt& a, + const BigInt& b); + +/** +* Call almost_montgomery_inverse and correct the result to a^-1 mod b +*/ +BigInt BOTAN_PUBLIC_API(2,0) normalized_montgomery_inverse(const BigInt& a, const BigInt& b); + + +/** +* Compute the Jacobi symbol. If n is prime, this is equivalent +* to the Legendre symbol. +* @see http://mathworld.wolfram.com/JacobiSymbol.html +* +* @param a is a non-negative integer +* @param n is an odd integer > 1 +* @return (n / m) +*/ +int32_t BOTAN_PUBLIC_API(2,0) jacobi(const BigInt& a, + const BigInt& n); + +/** +* Modular exponentation +* @param b an integer base +* @param x a positive exponent +* @param m a positive modulus +* @return (b^x) % m +*/ +BigInt BOTAN_PUBLIC_API(2,0) power_mod(const BigInt& b, + const BigInt& x, + const BigInt& m); + +/** +* Compute the square root of x modulo a prime using the +* Shanks-Tonnelli algorithm +* +* @param x the input +* @param p the prime +* @return y such that (y*y)%p == x, or -1 if no such integer +*/ +BigInt BOTAN_PUBLIC_API(2,0) ressol(const BigInt& x, const BigInt& p); + +/* +* Compute -input^-1 mod 2^MP_WORD_BITS. Returns zero if input +* is even. If input is odd, input and 2^n are relatively prime +* and an inverse exists. +*/ +word BOTAN_PUBLIC_API(2,0) monty_inverse(word input); + +/** +* @param x a positive integer +* @return count of the zero bits in x, or, equivalently, the largest +* value of n such that 2^n divides x evenly. Returns zero if +* n is less than or equal to zero. +*/ +size_t BOTAN_PUBLIC_API(2,0) low_zero_bits(const BigInt& x); + +/** +* Check for primality +* @param n a positive integer to test for primality +* @param rng a random number generator +* @param prob chance of false positive is bounded by 1/2**prob +* @param is_random true if n was randomly chosen by us +* @return true if all primality tests passed, otherwise false +*/ +bool BOTAN_PUBLIC_API(2,0) is_prime(const BigInt& n, + RandomNumberGenerator& rng, + size_t prob = 56, + bool is_random = false); + +inline bool quick_check_prime(const BigInt& n, RandomNumberGenerator& rng) + { return is_prime(n, rng, 32); } + +inline bool check_prime(const BigInt& n, RandomNumberGenerator& rng) + { return is_prime(n, rng, 56); } + +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 +* @param bits how large the resulting prime should be in bits +* @param coprime a positive integer that (prime - 1) should be coprime to +* @param equiv a non-negative number that the result should be + equivalent to modulo equiv_mod +* @param equiv_mod the modulus equiv should be checked against +* @param prob use test so false positive is bounded by 1/2**prob +* @return random prime with the specified criteria +*/ +BigInt BOTAN_PUBLIC_API(2,0) random_prime(RandomNumberGenerator& rng, + size_t bits, + const BigInt& coprime = 0, + size_t equiv = 1, + size_t equiv_mod = 2, + size_t prob = 128); + +/** +* Generate a prime suitable for RSA p/q +* @param keygen_rng a random number generator +* @param prime_test_rng a random number generator +* @param bits how large the resulting prime should be in bits (must be >= 512) +* @param coprime a positive integer that (prime - 1) should be coprime to +* @param prob use test so false positive is bounded by 1/2**prob +* @return random prime with the specified criteria +*/ +BigInt BOTAN_PUBLIC_API(2,7) generate_rsa_prime(RandomNumberGenerator& keygen_rng, + RandomNumberGenerator& prime_test_rng, + size_t bits, + const BigInt& coprime, + size_t prob = 128); + +/** +* Return a 'safe' prime, of the form p=2*q+1 with q prime +* @param rng a random number generator +* @param bits is how long the resulting prime should be +* @return prime randomly chosen from safe primes of length bits +*/ +BigInt BOTAN_PUBLIC_API(2,0) random_safe_prime(RandomNumberGenerator& rng, + size_t bits); + +/** +* Generate DSA parameters using the FIPS 186 kosherizer +* @param rng a random number generator +* @param p_out where the prime p will be stored +* @param q_out where the prime q will be stored +* @param pbits how long p will be in bits +* @param qbits how long q will be in bits +* @return random seed used to generate this parameter set +*/ +std::vector BOTAN_PUBLIC_API(2,0) +generate_dsa_primes(RandomNumberGenerator& rng, + BigInt& p_out, BigInt& q_out, + size_t pbits, size_t qbits); + +/** +* Generate DSA parameters using the FIPS 186 kosherizer +* @param rng a random number generator +* @param p_out where the prime p will be stored +* @param q_out where the prime q will be stored +* @param pbits how long p will be in bits +* @param qbits how long q will be in bits +* @param seed the seed used to generate the parameters +* @param offset optional offset from seed to start searching at +* @return true if seed generated a valid DSA parameter set, otherwise + false. p_out and q_out are only valid if true was returned. +*/ +bool BOTAN_PUBLIC_API(2,0) +generate_dsa_primes(RandomNumberGenerator& rng, + BigInt& p_out, BigInt& q_out, + size_t pbits, size_t qbits, + const std::vector& seed, + size_t offset = 0); + +/** +* The size of the PRIMES[] array +*/ +const size_t PRIME_TABLE_SIZE = 6541; + +/** +* A const array of all primes less than 65535 +*/ +extern const uint16_t BOTAN_PUBLIC_API(2,0) PRIMES[]; + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/math/numbertheory/pow_mod.cpp b/src/libs/3rdparty/botan/src/lib/math/numbertheory/pow_mod.cpp new file mode 100644 index 0000000000..00917a5f91 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/math/numbertheory/pow_mod.cpp @@ -0,0 +1,196 @@ +/* +* Modular Exponentiation Proxy +* (C) 1999-2007 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include + +namespace Botan { + +/* +* Power_Mod Constructor +*/ +Power_Mod::Power_Mod(const BigInt& n, Usage_Hints hints, bool disable_monty) + { + set_modulus(n, hints, disable_monty); + } + +/* +* Power_Mod Copy Constructor +*/ +Power_Mod::Power_Mod(const Power_Mod& other) + { + if(other.m_core.get()) + m_core.reset(other.m_core->copy()); + } + +/* +* Power_Mod Assignment Operator +*/ +Power_Mod& Power_Mod::operator=(const Power_Mod& other) + { + if(this != &other) + { + if(other.m_core) + m_core.reset(other.m_core->copy()); + else + m_core.reset(); + } + return (*this); + } + +/* +* Set the modulus +*/ +void Power_Mod::set_modulus(const BigInt& n, Usage_Hints hints, bool disable_monty) const + { + // Allow set_modulus(0) to mean "drop old state" + + m_core.reset(); + + if(n != 0) + { + if(n.is_odd() && disable_monty == false) + m_core.reset(new Montgomery_Exponentiator(n, hints)); + else + m_core.reset(new Fixed_Window_Exponentiator(n, hints)); + } + } + +/* +* Set the base +*/ +void Power_Mod::set_base(const BigInt& b) const + { + if(b.is_zero() || b.is_negative()) + throw Invalid_Argument("Power_Mod::set_base: arg must be > 0"); + + if(!m_core) + throw Internal_Error("Power_Mod::set_base: m_core was NULL"); + m_core->set_base(b); + } + +/* +* Set the exponent +*/ +void Power_Mod::set_exponent(const BigInt& e) const + { + if(e.is_negative()) + throw Invalid_Argument("Power_Mod::set_exponent: arg must be > 0"); + + if(!m_core) + throw Internal_Error("Power_Mod::set_exponent: m_core was NULL"); + m_core->set_exponent(e); + } + +/* +* Compute the result +*/ +BigInt Power_Mod::execute() const + { + if(!m_core) + throw Internal_Error("Power_Mod::execute: m_core was NULL"); + return m_core->execute(); + } + +/* +* Try to choose a good window size +*/ +size_t Power_Mod::window_bits(size_t exp_bits, size_t, + Power_Mod::Usage_Hints hints) + { + static const size_t wsize[][2] = { + { 1434, 7 }, + { 539, 6 }, + { 197, 4 }, + { 70, 3 }, + { 17, 2 }, + { 0, 0 } + }; + + size_t window_bits = 1; + + if(exp_bits) + { + for(size_t j = 0; wsize[j][0]; ++j) + { + if(exp_bits >= wsize[j][0]) + { + window_bits += wsize[j][1]; + break; + } + } + } + + if(hints & Power_Mod::BASE_IS_FIXED) + window_bits += 2; + if(hints & Power_Mod::EXP_IS_LARGE) + ++window_bits; + + return window_bits; + } + +namespace { + +/* +* Choose potentially useful hints +*/ +Power_Mod::Usage_Hints choose_base_hints(const BigInt& b, const BigInt& n) + { + if(b == 2) + return Power_Mod::Usage_Hints(Power_Mod::BASE_IS_2 | + Power_Mod::BASE_IS_SMALL); + + const size_t b_bits = b.bits(); + const size_t n_bits = n.bits(); + + if(b_bits < n_bits / 32) + return Power_Mod::BASE_IS_SMALL; + if(b_bits > n_bits / 4) + return Power_Mod::BASE_IS_LARGE; + + return Power_Mod::NO_HINTS; + } + +/* +* Choose potentially useful hints +*/ +Power_Mod::Usage_Hints choose_exp_hints(const BigInt& e, const BigInt& n) + { + const size_t e_bits = e.bits(); + const size_t n_bits = n.bits(); + + if(e_bits < n_bits / 32) + return Power_Mod::BASE_IS_SMALL; + if(e_bits > n_bits / 4) + return Power_Mod::BASE_IS_LARGE; + return Power_Mod::NO_HINTS; + } + +} + +/* +* Fixed_Exponent_Power_Mod Constructor +*/ +Fixed_Exponent_Power_Mod::Fixed_Exponent_Power_Mod(const BigInt& e, + const BigInt& n, + Usage_Hints hints) : + Power_Mod(n, Usage_Hints(hints | EXP_IS_FIXED | choose_exp_hints(e, n))) + { + set_exponent(e); + } + +/* +* Fixed_Base_Power_Mod Constructor +*/ +Fixed_Base_Power_Mod::Fixed_Base_Power_Mod(const BigInt& b, const BigInt& n, + Usage_Hints hints) : + Power_Mod(n, Usage_Hints(hints | BASE_IS_FIXED | choose_base_hints(b, n))) + { + set_base(b); + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/math/numbertheory/pow_mod.h b/src/libs/3rdparty/botan/src/lib/math/numbertheory/pow_mod.h new file mode 100644 index 0000000000..077f4ccf72 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/math/numbertheory/pow_mod.h @@ -0,0 +1,135 @@ +/* +* Modular Exponentiator +* (C) 1999-2007 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_POWER_MOD_H_ +#define BOTAN_POWER_MOD_H_ + +#include + +namespace Botan { + +/** +* Modular Exponentiator Interface +*/ +class BOTAN_PUBLIC_API(2,0) Modular_Exponentiator + { + public: + virtual void set_base(const BigInt&) = 0; + virtual void set_exponent(const BigInt&) = 0; + virtual BigInt execute() const = 0; + virtual Modular_Exponentiator* copy() const = 0; + + Modular_Exponentiator() = default; + Modular_Exponentiator(const Modular_Exponentiator&) = default; + Modular_Exponentiator & operator=(const Modular_Exponentiator&) = default; + virtual ~Modular_Exponentiator() = default; + }; + +/** +* Modular Exponentiator Proxy +*/ +class BOTAN_PUBLIC_API(2,0) Power_Mod + { + public: + + enum Usage_Hints { + NO_HINTS = 0x0000, + + BASE_IS_FIXED = 0x0001, + BASE_IS_SMALL = 0x0002, + BASE_IS_LARGE = 0x0004, + BASE_IS_2 = 0x0008, + + EXP_IS_FIXED = 0x0100, + EXP_IS_SMALL = 0x0200, + EXP_IS_LARGE = 0x0400 + }; + + /* + * Try to choose a good window size + */ + static size_t window_bits(size_t exp_bits, size_t base_bits, + Power_Mod::Usage_Hints hints); + + /** + * @param modulus the modulus + * @param hints Passed to set_modulus if modulus > 0 + * @param disable_montgomery_arith Disables use of Montgomery + * representation. Likely only useful for testing. + */ + void set_modulus(const BigInt& modulus, + Usage_Hints hints = NO_HINTS, + bool disable_montgomery_arith = false) const; + + /** + * Set the base + */ + void set_base(const BigInt& base) const; + + /** + * Set the exponent + */ + void set_exponent(const BigInt& exponent) const; + + /** + * All three of the above functions must have already been called. + * @return result of g^x%p + */ + BigInt execute() const; + + Power_Mod& operator=(const Power_Mod&); + + /** + * @param modulus Optionally call set_modulus + * @param hints Passed to set_modulus if modulus > 0 + * @param disable_montgomery_arith Disables use of Montgomery + * representation. Likely only useful for testing. + */ + Power_Mod(const BigInt& modulus = 0, + Usage_Hints hints = NO_HINTS, + bool disable_montgomery_arith = false); + Power_Mod(const Power_Mod&); + virtual ~Power_Mod() = default; + private: + mutable std::unique_ptr m_core; + }; + +/** +* Fixed Exponent Modular Exponentiator Proxy +*/ +class BOTAN_PUBLIC_API(2,0) Fixed_Exponent_Power_Mod final : public Power_Mod + { + public: + BigInt operator()(const BigInt& b) const + { set_base(b); return execute(); } + + Fixed_Exponent_Power_Mod() = default; + + Fixed_Exponent_Power_Mod(const BigInt& exponent, + const BigInt& modulus, + Usage_Hints hints = NO_HINTS); + }; + +/** +* Fixed Base Modular Exponentiator Proxy +*/ +class BOTAN_PUBLIC_API(2,0) Fixed_Base_Power_Mod final : public Power_Mod + { + public: + BigInt operator()(const BigInt& e) const + { set_exponent(e); return execute(); } + + Fixed_Base_Power_Mod() = default; + + Fixed_Base_Power_Mod(const BigInt& base, + const BigInt& modulus, + Usage_Hints hints = NO_HINTS); + }; + +} + +#endif 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 new file mode 100644 index 0000000000..85a0364b5a --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/math/numbertheory/powm_fw.cpp @@ -0,0 +1,65 @@ +/* +* Fixed Window Exponentiation +* (C) 1999-2007 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include + +namespace Botan { + +/* +* Set the exponent +*/ +void Fixed_Window_Exponentiator::set_exponent(const BigInt& e) + { + m_exp = e; + } + +/* +* Set the base +*/ +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[0] = 1; + m_g[1] = base; + + for(size_t i = 2; i != m_g.size(); ++i) + m_g[i] = m_reducer.multiply(m_g[i-1], m_g[1]); + } + +/* +* Compute the result +*/ +BigInt Fixed_Window_Exponentiator::execute() const + { + const size_t exp_nibbles = (m_exp.bits() + m_window_bits - 1) / m_window_bits; + + BigInt x = 1; + + for(size_t i = exp_nibbles; i > 0; --i) + { + for(size_t j = 0; j != m_window_bits; ++j) + x = m_reducer.square(x); + + const uint32_t nibble = m_exp.get_substring(m_window_bits*(i-1), m_window_bits); + + x = m_reducer.multiply(x, m_g[nibble]); + } + return x; + } + +/* +* Fixed_Window_Exponentiator Constructor +*/ +Fixed_Window_Exponentiator::Fixed_Window_Exponentiator(const BigInt& n, + Power_Mod::Usage_Hints hints) + : m_reducer{Modular_Reducer(n)}, m_exp{}, m_window_bits{}, m_g{}, m_hints{hints} + {} + +} diff --git a/src/libs/3rdparty/botan/src/lib/math/numbertheory/powm_mnt.cpp b/src/libs/3rdparty/botan/src/lib/math/numbertheory/powm_mnt.cpp new file mode 100644 index 0000000000..8cb3f6a08e --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/math/numbertheory/powm_mnt.cpp @@ -0,0 +1,46 @@ +/* +* Montgomery Exponentiation +* (C) 1999-2010,2012,2018 Jack Lloyd +* 2016 Matthias Gierlings +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include +#include + +namespace Botan { + +void Montgomery_Exponentiator::set_exponent(const BigInt& exp) + { + m_e = exp; + } + +void Montgomery_Exponentiator::set_base(const BigInt& base) + { + size_t window_bits = Power_Mod::window_bits(m_e.bits(), base.bits(), m_hints); + m_monty = monty_precompute(m_monty_params, base, window_bits); + } + +BigInt Montgomery_Exponentiator::execute() const + { + /* + This leaks size of e via loop iterations, not possible to fix without + breaking this API. Round up to avoid leaking fine details. + */ + return monty_execute(*m_monty, m_e, round_up(m_e.bits(), 8)); + } + +Montgomery_Exponentiator::Montgomery_Exponentiator(const BigInt& mod, + Power_Mod::Usage_Hints hints) : + m_p(mod), + m_mod_p(mod), + m_monty_params(std::make_shared(m_p, m_mod_p)), + m_hints(hints) + { + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/math/numbertheory/primes.cpp b/src/libs/3rdparty/botan/src/lib/math/numbertheory/primes.cpp new file mode 100644 index 0000000000..4a3eb46f2c --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/math/numbertheory/primes.cpp @@ -0,0 +1,609 @@ +/* +* Small Primes Table +* (C) 1999-2007 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include + +namespace Botan { + +const uint16_t PRIMES[PRIME_TABLE_SIZE+1] = { + 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, + 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, + 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, + 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, + 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, + 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, + 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, + 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, + 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, + 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, + 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, + 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, + 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, + 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, + 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, + 991, 997, 1009, 1013, 1019, 1021, 1031, 1033, 1039, 1049, 1051, + 1061, 1063, 1069, 1087, 1091, 1093, 1097, 1103, 1109, 1117, 1123, + 1129, 1151, 1153, 1163, 1171, 1181, 1187, 1193, 1201, 1213, 1217, + 1223, 1229, 1231, 1237, 1249, 1259, 1277, 1279, 1283, 1289, 1291, + 1297, 1301, 1303, 1307, 1319, 1321, 1327, 1361, 1367, 1373, 1381, + 1399, 1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451, 1453, 1459, + 1471, 1481, 1483, 1487, 1489, 1493, 1499, 1511, 1523, 1531, 1543, + 1549, 1553, 1559, 1567, 1571, 1579, 1583, 1597, 1601, 1607, 1609, + 1613, 1619, 1621, 1627, 1637, 1657, 1663, 1667, 1669, 1693, 1697, + 1699, 1709, 1721, 1723, 1733, 1741, 1747, 1753, 1759, 1777, 1783, + 1787, 1789, 1801, 1811, 1823, 1831, 1847, 1861, 1867, 1871, 1873, + 1877, 1879, 1889, 1901, 1907, 1913, 1931, 1933, 1949, 1951, 1973, + 1979, 1987, 1993, 1997, 1999, 2003, 2011, 2017, 2027, 2029, 2039, + 2053, 2063, 2069, 2081, 2083, 2087, 2089, 2099, 2111, 2113, 2129, + 2131, 2137, 2141, 2143, 2153, 2161, 2179, 2203, 2207, 2213, 2221, + 2237, 2239, 2243, 2251, 2267, 2269, 2273, 2281, 2287, 2293, 2297, + 2309, 2311, 2333, 2339, 2341, 2347, 2351, 2357, 2371, 2377, 2381, + 2383, 2389, 2393, 2399, 2411, 2417, 2423, 2437, 2441, 2447, 2459, + 2467, 2473, 2477, 2503, 2521, 2531, 2539, 2543, 2549, 2551, 2557, + 2579, 2591, 2593, 2609, 2617, 2621, 2633, 2647, 2657, 2659, 2663, + 2671, 2677, 2683, 2687, 2689, 2693, 2699, 2707, 2711, 2713, 2719, + 2729, 2731, 2741, 2749, 2753, 2767, 2777, 2789, 2791, 2797, 2801, + 2803, 2819, 2833, 2837, 2843, 2851, 2857, 2861, 2879, 2887, 2897, + 2903, 2909, 2917, 2927, 2939, 2953, 2957, 2963, 2969, 2971, 2999, + 3001, 3011, 3019, 3023, 3037, 3041, 3049, 3061, 3067, 3079, 3083, + 3089, 3109, 3119, 3121, 3137, 3163, 3167, 3169, 3181, 3187, 3191, + 3203, 3209, 3217, 3221, 3229, 3251, 3253, 3257, 3259, 3271, 3299, + 3301, 3307, 3313, 3319, 3323, 3329, 3331, 3343, 3347, 3359, 3361, + 3371, 3373, 3389, 3391, 3407, 3413, 3433, 3449, 3457, 3461, 3463, + 3467, 3469, 3491, 3499, 3511, 3517, 3527, 3529, 3533, 3539, 3541, + 3547, 3557, 3559, 3571, 3581, 3583, 3593, 3607, 3613, 3617, 3623, + 3631, 3637, 3643, 3659, 3671, 3673, 3677, 3691, 3697, 3701, 3709, + 3719, 3727, 3733, 3739, 3761, 3767, 3769, 3779, 3793, 3797, 3803, + 3821, 3823, 3833, 3847, 3851, 3853, 3863, 3877, 3881, 3889, 3907, + 3911, 3917, 3919, 3923, 3929, 3931, 3943, 3947, 3967, 3989, 4001, + 4003, 4007, 4013, 4019, 4021, 4027, 4049, 4051, 4057, 4073, 4079, + 4091, 4093, 4099, 4111, 4127, 4129, 4133, 4139, 4153, 4157, 4159, + 4177, 4201, 4211, 4217, 4219, 4229, 4231, 4241, 4243, 4253, 4259, + 4261, 4271, 4273, 4283, 4289, 4297, 4327, 4337, 4339, 4349, 4357, + 4363, 4373, 4391, 4397, 4409, 4421, 4423, 4441, 4447, 4451, 4457, + 4463, 4481, 4483, 4493, 4507, 4513, 4517, 4519, 4523, 4547, 4549, + 4561, 4567, 4583, 4591, 4597, 4603, 4621, 4637, 4639, 4643, 4649, + 4651, 4657, 4663, 4673, 4679, 4691, 4703, 4721, 4723, 4729, 4733, + 4751, 4759, 4783, 4787, 4789, 4793, 4799, 4801, 4813, 4817, 4831, + 4861, 4871, 4877, 4889, 4903, 4909, 4919, 4931, 4933, 4937, 4943, + 4951, 4957, 4967, 4969, 4973, 4987, 4993, 4999, 5003, 5009, 5011, + 5021, 5023, 5039, 5051, 5059, 5077, 5081, 5087, 5099, 5101, 5107, + 5113, 5119, 5147, 5153, 5167, 5171, 5179, 5189, 5197, 5209, 5227, + 5231, 5233, 5237, 5261, 5273, 5279, 5281, 5297, 5303, 5309, 5323, + 5333, 5347, 5351, 5381, 5387, 5393, 5399, 5407, 5413, 5417, 5419, + 5431, 5437, 5441, 5443, 5449, 5471, 5477, 5479, 5483, 5501, 5503, + 5507, 5519, 5521, 5527, 5531, 5557, 5563, 5569, 5573, 5581, 5591, + 5623, 5639, 5641, 5647, 5651, 5653, 5657, 5659, 5669, 5683, 5689, + 5693, 5701, 5711, 5717, 5737, 5741, 5743, 5749, 5779, 5783, 5791, + 5801, 5807, 5813, 5821, 5827, 5839, 5843, 5849, 5851, 5857, 5861, + 5867, 5869, 5879, 5881, 5897, 5903, 5923, 5927, 5939, 5953, 5981, + 5987, 6007, 6011, 6029, 6037, 6043, 6047, 6053, 6067, 6073, 6079, + 6089, 6091, 6101, 6113, 6121, 6131, 6133, 6143, 6151, 6163, 6173, + 6197, 6199, 6203, 6211, 6217, 6221, 6229, 6247, 6257, 6263, 6269, + 6271, 6277, 6287, 6299, 6301, 6311, 6317, 6323, 6329, 6337, 6343, + 6353, 6359, 6361, 6367, 6373, 6379, 6389, 6397, 6421, 6427, 6449, + 6451, 6469, 6473, 6481, 6491, 6521, 6529, 6547, 6551, 6553, 6563, + 6569, 6571, 6577, 6581, 6599, 6607, 6619, 6637, 6653, 6659, 6661, + 6673, 6679, 6689, 6691, 6701, 6703, 6709, 6719, 6733, 6737, 6761, + 6763, 6779, 6781, 6791, 6793, 6803, 6823, 6827, 6829, 6833, 6841, + 6857, 6863, 6869, 6871, 6883, 6899, 6907, 6911, 6917, 6947, 6949, + 6959, 6961, 6967, 6971, 6977, 6983, 6991, 6997, 7001, 7013, 7019, + 7027, 7039, 7043, 7057, 7069, 7079, 7103, 7109, 7121, 7127, 7129, + 7151, 7159, 7177, 7187, 7193, 7207, 7211, 7213, 7219, 7229, 7237, + 7243, 7247, 7253, 7283, 7297, 7307, 7309, 7321, 7331, 7333, 7349, + 7351, 7369, 7393, 7411, 7417, 7433, 7451, 7457, 7459, 7477, 7481, + 7487, 7489, 7499, 7507, 7517, 7523, 7529, 7537, 7541, 7547, 7549, + 7559, 7561, 7573, 7577, 7583, 7589, 7591, 7603, 7607, 7621, 7639, + 7643, 7649, 7669, 7673, 7681, 7687, 7691, 7699, 7703, 7717, 7723, + 7727, 7741, 7753, 7757, 7759, 7789, 7793, 7817, 7823, 7829, 7841, + 7853, 7867, 7873, 7877, 7879, 7883, 7901, 7907, 7919, 7927, 7933, + 7937, 7949, 7951, 7963, 7993, 8009, 8011, 8017, 8039, 8053, 8059, + 8069, 8081, 8087, 8089, 8093, 8101, 8111, 8117, 8123, 8147, 8161, + 8167, 8171, 8179, 8191, 8209, 8219, 8221, 8231, 8233, 8237, 8243, + 8263, 8269, 8273, 8287, 8291, 8293, 8297, 8311, 8317, 8329, 8353, + 8363, 8369, 8377, 8387, 8389, 8419, 8423, 8429, 8431, 8443, 8447, + 8461, 8467, 8501, 8513, 8521, 8527, 8537, 8539, 8543, 8563, 8573, + 8581, 8597, 8599, 8609, 8623, 8627, 8629, 8641, 8647, 8663, 8669, + 8677, 8681, 8689, 8693, 8699, 8707, 8713, 8719, 8731, 8737, 8741, + 8747, 8753, 8761, 8779, 8783, 8803, 8807, 8819, 8821, 8831, 8837, + 8839, 8849, 8861, 8863, 8867, 8887, 8893, 8923, 8929, 8933, 8941, + 8951, 8963, 8969, 8971, 8999, 9001, 9007, 9011, 9013, 9029, 9041, + 9043, 9049, 9059, 9067, 9091, 9103, 9109, 9127, 9133, 9137, 9151, + 9157, 9161, 9173, 9181, 9187, 9199, 9203, 9209, 9221, 9227, 9239, + 9241, 9257, 9277, 9281, 9283, 9293, 9311, 9319, 9323, 9337, 9341, + 9343, 9349, 9371, 9377, 9391, 9397, 9403, 9413, 9419, 9421, 9431, + 9433, 9437, 9439, 9461, 9463, 9467, 9473, 9479, 9491, 9497, 9511, + 9521, 9533, 9539, 9547, 9551, 9587, 9601, 9613, 9619, 9623, 9629, + 9631, 9643, 9649, 9661, 9677, 9679, 9689, 9697, 9719, 9721, 9733, + 9739, 9743, 9749, 9767, 9769, 9781, 9787, 9791, 9803, 9811, 9817, + 9829, 9833, 9839, 9851, 9857, 9859, 9871, 9883, 9887, 9901, 9907, + 9923, 9929, 9931, 9941, 9949, 9967, 9973, 10007, 10009, 10037, 10039, +10061, 10067, 10069, 10079, 10091, 10093, 10099, 10103, 10111, 10133, 10139, +10141, 10151, 10159, 10163, 10169, 10177, 10181, 10193, 10211, 10223, 10243, +10247, 10253, 10259, 10267, 10271, 10273, 10289, 10301, 10303, 10313, 10321, +10331, 10333, 10337, 10343, 10357, 10369, 10391, 10399, 10427, 10429, 10433, +10453, 10457, 10459, 10463, 10477, 10487, 10499, 10501, 10513, 10529, 10531, +10559, 10567, 10589, 10597, 10601, 10607, 10613, 10627, 10631, 10639, 10651, +10657, 10663, 10667, 10687, 10691, 10709, 10711, 10723, 10729, 10733, 10739, +10753, 10771, 10781, 10789, 10799, 10831, 10837, 10847, 10853, 10859, 10861, +10867, 10883, 10889, 10891, 10903, 10909, 10937, 10939, 10949, 10957, 10973, +10979, 10987, 10993, 11003, 11027, 11047, 11057, 11059, 11069, 11071, 11083, +11087, 11093, 11113, 11117, 11119, 11131, 11149, 11159, 11161, 11171, 11173, +11177, 11197, 11213, 11239, 11243, 11251, 11257, 11261, 11273, 11279, 11287, +11299, 11311, 11317, 11321, 11329, 11351, 11353, 11369, 11383, 11393, 11399, +11411, 11423, 11437, 11443, 11447, 11467, 11471, 11483, 11489, 11491, 11497, +11503, 11519, 11527, 11549, 11551, 11579, 11587, 11593, 11597, 11617, 11621, +11633, 11657, 11677, 11681, 11689, 11699, 11701, 11717, 11719, 11731, 11743, +11777, 11779, 11783, 11789, 11801, 11807, 11813, 11821, 11827, 11831, 11833, +11839, 11863, 11867, 11887, 11897, 11903, 11909, 11923, 11927, 11933, 11939, +11941, 11953, 11959, 11969, 11971, 11981, 11987, 12007, 12011, 12037, 12041, +12043, 12049, 12071, 12073, 12097, 12101, 12107, 12109, 12113, 12119, 12143, +12149, 12157, 12161, 12163, 12197, 12203, 12211, 12227, 12239, 12241, 12251, +12253, 12263, 12269, 12277, 12281, 12289, 12301, 12323, 12329, 12343, 12347, +12373, 12377, 12379, 12391, 12401, 12409, 12413, 12421, 12433, 12437, 12451, +12457, 12473, 12479, 12487, 12491, 12497, 12503, 12511, 12517, 12527, 12539, +12541, 12547, 12553, 12569, 12577, 12583, 12589, 12601, 12611, 12613, 12619, +12637, 12641, 12647, 12653, 12659, 12671, 12689, 12697, 12703, 12713, 12721, +12739, 12743, 12757, 12763, 12781, 12791, 12799, 12809, 12821, 12823, 12829, +12841, 12853, 12889, 12893, 12899, 12907, 12911, 12917, 12919, 12923, 12941, +12953, 12959, 12967, 12973, 12979, 12983, 13001, 13003, 13007, 13009, 13033, +13037, 13043, 13049, 13063, 13093, 13099, 13103, 13109, 13121, 13127, 13147, +13151, 13159, 13163, 13171, 13177, 13183, 13187, 13217, 13219, 13229, 13241, +13249, 13259, 13267, 13291, 13297, 13309, 13313, 13327, 13331, 13337, 13339, +13367, 13381, 13397, 13399, 13411, 13417, 13421, 13441, 13451, 13457, 13463, +13469, 13477, 13487, 13499, 13513, 13523, 13537, 13553, 13567, 13577, 13591, +13597, 13613, 13619, 13627, 13633, 13649, 13669, 13679, 13681, 13687, 13691, +13693, 13697, 13709, 13711, 13721, 13723, 13729, 13751, 13757, 13759, 13763, +13781, 13789, 13799, 13807, 13829, 13831, 13841, 13859, 13873, 13877, 13879, +13883, 13901, 13903, 13907, 13913, 13921, 13931, 13933, 13963, 13967, 13997, +13999, 14009, 14011, 14029, 14033, 14051, 14057, 14071, 14081, 14083, 14087, +14107, 14143, 14149, 14153, 14159, 14173, 14177, 14197, 14207, 14221, 14243, +14249, 14251, 14281, 14293, 14303, 14321, 14323, 14327, 14341, 14347, 14369, +14387, 14389, 14401, 14407, 14411, 14419, 14423, 14431, 14437, 14447, 14449, +14461, 14479, 14489, 14503, 14519, 14533, 14537, 14543, 14549, 14551, 14557, +14561, 14563, 14591, 14593, 14621, 14627, 14629, 14633, 14639, 14653, 14657, +14669, 14683, 14699, 14713, 14717, 14723, 14731, 14737, 14741, 14747, 14753, +14759, 14767, 14771, 14779, 14783, 14797, 14813, 14821, 14827, 14831, 14843, +14851, 14867, 14869, 14879, 14887, 14891, 14897, 14923, 14929, 14939, 14947, +14951, 14957, 14969, 14983, 15013, 15017, 15031, 15053, 15061, 15073, 15077, +15083, 15091, 15101, 15107, 15121, 15131, 15137, 15139, 15149, 15161, 15173, +15187, 15193, 15199, 15217, 15227, 15233, 15241, 15259, 15263, 15269, 15271, +15277, 15287, 15289, 15299, 15307, 15313, 15319, 15329, 15331, 15349, 15359, +15361, 15373, 15377, 15383, 15391, 15401, 15413, 15427, 15439, 15443, 15451, +15461, 15467, 15473, 15493, 15497, 15511, 15527, 15541, 15551, 15559, 15569, +15581, 15583, 15601, 15607, 15619, 15629, 15641, 15643, 15647, 15649, 15661, +15667, 15671, 15679, 15683, 15727, 15731, 15733, 15737, 15739, 15749, 15761, +15767, 15773, 15787, 15791, 15797, 15803, 15809, 15817, 15823, 15859, 15877, +15881, 15887, 15889, 15901, 15907, 15913, 15919, 15923, 15937, 15959, 15971, +15973, 15991, 16001, 16007, 16033, 16057, 16061, 16063, 16067, 16069, 16073, +16087, 16091, 16097, 16103, 16111, 16127, 16139, 16141, 16183, 16187, 16189, +16193, 16217, 16223, 16229, 16231, 16249, 16253, 16267, 16273, 16301, 16319, +16333, 16339, 16349, 16361, 16363, 16369, 16381, 16411, 16417, 16421, 16427, +16433, 16447, 16451, 16453, 16477, 16481, 16487, 16493, 16519, 16529, 16547, +16553, 16561, 16567, 16573, 16603, 16607, 16619, 16631, 16633, 16649, 16651, +16657, 16661, 16673, 16691, 16693, 16699, 16703, 16729, 16741, 16747, 16759, +16763, 16787, 16811, 16823, 16829, 16831, 16843, 16871, 16879, 16883, 16889, +16901, 16903, 16921, 16927, 16931, 16937, 16943, 16963, 16979, 16981, 16987, +16993, 17011, 17021, 17027, 17029, 17033, 17041, 17047, 17053, 17077, 17093, +17099, 17107, 17117, 17123, 17137, 17159, 17167, 17183, 17189, 17191, 17203, +17207, 17209, 17231, 17239, 17257, 17291, 17293, 17299, 17317, 17321, 17327, +17333, 17341, 17351, 17359, 17377, 17383, 17387, 17389, 17393, 17401, 17417, +17419, 17431, 17443, 17449, 17467, 17471, 17477, 17483, 17489, 17491, 17497, +17509, 17519, 17539, 17551, 17569, 17573, 17579, 17581, 17597, 17599, 17609, +17623, 17627, 17657, 17659, 17669, 17681, 17683, 17707, 17713, 17729, 17737, +17747, 17749, 17761, 17783, 17789, 17791, 17807, 17827, 17837, 17839, 17851, +17863, 17881, 17891, 17903, 17909, 17911, 17921, 17923, 17929, 17939, 17957, +17959, 17971, 17977, 17981, 17987, 17989, 18013, 18041, 18043, 18047, 18049, +18059, 18061, 18077, 18089, 18097, 18119, 18121, 18127, 18131, 18133, 18143, +18149, 18169, 18181, 18191, 18199, 18211, 18217, 18223, 18229, 18233, 18251, +18253, 18257, 18269, 18287, 18289, 18301, 18307, 18311, 18313, 18329, 18341, +18353, 18367, 18371, 18379, 18397, 18401, 18413, 18427, 18433, 18439, 18443, +18451, 18457, 18461, 18481, 18493, 18503, 18517, 18521, 18523, 18539, 18541, +18553, 18583, 18587, 18593, 18617, 18637, 18661, 18671, 18679, 18691, 18701, +18713, 18719, 18731, 18743, 18749, 18757, 18773, 18787, 18793, 18797, 18803, +18839, 18859, 18869, 18899, 18911, 18913, 18917, 18919, 18947, 18959, 18973, +18979, 19001, 19009, 19013, 19031, 19037, 19051, 19069, 19073, 19079, 19081, +19087, 19121, 19139, 19141, 19157, 19163, 19181, 19183, 19207, 19211, 19213, +19219, 19231, 19237, 19249, 19259, 19267, 19273, 19289, 19301, 19309, 19319, +19333, 19373, 19379, 19381, 19387, 19391, 19403, 19417, 19421, 19423, 19427, +19429, 19433, 19441, 19447, 19457, 19463, 19469, 19471, 19477, 19483, 19489, +19501, 19507, 19531, 19541, 19543, 19553, 19559, 19571, 19577, 19583, 19597, +19603, 19609, 19661, 19681, 19687, 19697, 19699, 19709, 19717, 19727, 19739, +19751, 19753, 19759, 19763, 19777, 19793, 19801, 19813, 19819, 19841, 19843, +19853, 19861, 19867, 19889, 19891, 19913, 19919, 19927, 19937, 19949, 19961, +19963, 19973, 19979, 19991, 19993, 19997, 20011, 20021, 20023, 20029, 20047, +20051, 20063, 20071, 20089, 20101, 20107, 20113, 20117, 20123, 20129, 20143, +20147, 20149, 20161, 20173, 20177, 20183, 20201, 20219, 20231, 20233, 20249, +20261, 20269, 20287, 20297, 20323, 20327, 20333, 20341, 20347, 20353, 20357, +20359, 20369, 20389, 20393, 20399, 20407, 20411, 20431, 20441, 20443, 20477, +20479, 20483, 20507, 20509, 20521, 20533, 20543, 20549, 20551, 20563, 20593, +20599, 20611, 20627, 20639, 20641, 20663, 20681, 20693, 20707, 20717, 20719, +20731, 20743, 20747, 20749, 20753, 20759, 20771, 20773, 20789, 20807, 20809, +20849, 20857, 20873, 20879, 20887, 20897, 20899, 20903, 20921, 20929, 20939, +20947, 20959, 20963, 20981, 20983, 21001, 21011, 21013, 21017, 21019, 21023, +21031, 21059, 21061, 21067, 21089, 21101, 21107, 21121, 21139, 21143, 21149, +21157, 21163, 21169, 21179, 21187, 21191, 21193, 21211, 21221, 21227, 21247, +21269, 21277, 21283, 21313, 21317, 21319, 21323, 21341, 21347, 21377, 21379, +21383, 21391, 21397, 21401, 21407, 21419, 21433, 21467, 21481, 21487, 21491, +21493, 21499, 21503, 21517, 21521, 21523, 21529, 21557, 21559, 21563, 21569, +21577, 21587, 21589, 21599, 21601, 21611, 21613, 21617, 21647, 21649, 21661, +21673, 21683, 21701, 21713, 21727, 21737, 21739, 21751, 21757, 21767, 21773, +21787, 21799, 21803, 21817, 21821, 21839, 21841, 21851, 21859, 21863, 21871, +21881, 21893, 21911, 21929, 21937, 21943, 21961, 21977, 21991, 21997, 22003, +22013, 22027, 22031, 22037, 22039, 22051, 22063, 22067, 22073, 22079, 22091, +22093, 22109, 22111, 22123, 22129, 22133, 22147, 22153, 22157, 22159, 22171, +22189, 22193, 22229, 22247, 22259, 22271, 22273, 22277, 22279, 22283, 22291, +22303, 22307, 22343, 22349, 22367, 22369, 22381, 22391, 22397, 22409, 22433, +22441, 22447, 22453, 22469, 22481, 22483, 22501, 22511, 22531, 22541, 22543, +22549, 22567, 22571, 22573, 22613, 22619, 22621, 22637, 22639, 22643, 22651, +22669, 22679, 22691, 22697, 22699, 22709, 22717, 22721, 22727, 22739, 22741, +22751, 22769, 22777, 22783, 22787, 22807, 22811, 22817, 22853, 22859, 22861, +22871, 22877, 22901, 22907, 22921, 22937, 22943, 22961, 22963, 22973, 22993, +23003, 23011, 23017, 23021, 23027, 23029, 23039, 23041, 23053, 23057, 23059, +23063, 23071, 23081, 23087, 23099, 23117, 23131, 23143, 23159, 23167, 23173, +23189, 23197, 23201, 23203, 23209, 23227, 23251, 23269, 23279, 23291, 23293, +23297, 23311, 23321, 23327, 23333, 23339, 23357, 23369, 23371, 23399, 23417, +23431, 23447, 23459, 23473, 23497, 23509, 23531, 23537, 23539, 23549, 23557, +23561, 23563, 23567, 23581, 23593, 23599, 23603, 23609, 23623, 23627, 23629, +23633, 23663, 23669, 23671, 23677, 23687, 23689, 23719, 23741, 23743, 23747, +23753, 23761, 23767, 23773, 23789, 23801, 23813, 23819, 23827, 23831, 23833, +23857, 23869, 23873, 23879, 23887, 23893, 23899, 23909, 23911, 23917, 23929, +23957, 23971, 23977, 23981, 23993, 24001, 24007, 24019, 24023, 24029, 24043, +24049, 24061, 24071, 24077, 24083, 24091, 24097, 24103, 24107, 24109, 24113, +24121, 24133, 24137, 24151, 24169, 24179, 24181, 24197, 24203, 24223, 24229, +24239, 24247, 24251, 24281, 24317, 24329, 24337, 24359, 24371, 24373, 24379, +24391, 24407, 24413, 24419, 24421, 24439, 24443, 24469, 24473, 24481, 24499, +24509, 24517, 24527, 24533, 24547, 24551, 24571, 24593, 24611, 24623, 24631, +24659, 24671, 24677, 24683, 24691, 24697, 24709, 24733, 24749, 24763, 24767, +24781, 24793, 24799, 24809, 24821, 24841, 24847, 24851, 24859, 24877, 24889, +24907, 24917, 24919, 24923, 24943, 24953, 24967, 24971, 24977, 24979, 24989, +25013, 25031, 25033, 25037, 25057, 25073, 25087, 25097, 25111, 25117, 25121, +25127, 25147, 25153, 25163, 25169, 25171, 25183, 25189, 25219, 25229, 25237, +25243, 25247, 25253, 25261, 25301, 25303, 25307, 25309, 25321, 25339, 25343, +25349, 25357, 25367, 25373, 25391, 25409, 25411, 25423, 25439, 25447, 25453, +25457, 25463, 25469, 25471, 25523, 25537, 25541, 25561, 25577, 25579, 25583, +25589, 25601, 25603, 25609, 25621, 25633, 25639, 25643, 25657, 25667, 25673, +25679, 25693, 25703, 25717, 25733, 25741, 25747, 25759, 25763, 25771, 25793, +25799, 25801, 25819, 25841, 25847, 25849, 25867, 25873, 25889, 25903, 25913, +25919, 25931, 25933, 25939, 25943, 25951, 25969, 25981, 25997, 25999, 26003, +26017, 26021, 26029, 26041, 26053, 26083, 26099, 26107, 26111, 26113, 26119, +26141, 26153, 26161, 26171, 26177, 26183, 26189, 26203, 26209, 26227, 26237, +26249, 26251, 26261, 26263, 26267, 26293, 26297, 26309, 26317, 26321, 26339, +26347, 26357, 26371, 26387, 26393, 26399, 26407, 26417, 26423, 26431, 26437, +26449, 26459, 26479, 26489, 26497, 26501, 26513, 26539, 26557, 26561, 26573, +26591, 26597, 26627, 26633, 26641, 26647, 26669, 26681, 26683, 26687, 26693, +26699, 26701, 26711, 26713, 26717, 26723, 26729, 26731, 26737, 26759, 26777, +26783, 26801, 26813, 26821, 26833, 26839, 26849, 26861, 26863, 26879, 26881, +26891, 26893, 26903, 26921, 26927, 26947, 26951, 26953, 26959, 26981, 26987, +26993, 27011, 27017, 27031, 27043, 27059, 27061, 27067, 27073, 27077, 27091, +27103, 27107, 27109, 27127, 27143, 27179, 27191, 27197, 27211, 27239, 27241, +27253, 27259, 27271, 27277, 27281, 27283, 27299, 27329, 27337, 27361, 27367, +27397, 27407, 27409, 27427, 27431, 27437, 27449, 27457, 27479, 27481, 27487, +27509, 27527, 27529, 27539, 27541, 27551, 27581, 27583, 27611, 27617, 27631, +27647, 27653, 27673, 27689, 27691, 27697, 27701, 27733, 27737, 27739, 27743, +27749, 27751, 27763, 27767, 27773, 27779, 27791, 27793, 27799, 27803, 27809, +27817, 27823, 27827, 27847, 27851, 27883, 27893, 27901, 27917, 27919, 27941, +27943, 27947, 27953, 27961, 27967, 27983, 27997, 28001, 28019, 28027, 28031, +28051, 28057, 28069, 28081, 28087, 28097, 28099, 28109, 28111, 28123, 28151, +28163, 28181, 28183, 28201, 28211, 28219, 28229, 28277, 28279, 28283, 28289, +28297, 28307, 28309, 28319, 28349, 28351, 28387, 28393, 28403, 28409, 28411, +28429, 28433, 28439, 28447, 28463, 28477, 28493, 28499, 28513, 28517, 28537, +28541, 28547, 28549, 28559, 28571, 28573, 28579, 28591, 28597, 28603, 28607, +28619, 28621, 28627, 28631, 28643, 28649, 28657, 28661, 28663, 28669, 28687, +28697, 28703, 28711, 28723, 28729, 28751, 28753, 28759, 28771, 28789, 28793, +28807, 28813, 28817, 28837, 28843, 28859, 28867, 28871, 28879, 28901, 28909, +28921, 28927, 28933, 28949, 28961, 28979, 29009, 29017, 29021, 29023, 29027, +29033, 29059, 29063, 29077, 29101, 29123, 29129, 29131, 29137, 29147, 29153, +29167, 29173, 29179, 29191, 29201, 29207, 29209, 29221, 29231, 29243, 29251, +29269, 29287, 29297, 29303, 29311, 29327, 29333, 29339, 29347, 29363, 29383, +29387, 29389, 29399, 29401, 29411, 29423, 29429, 29437, 29443, 29453, 29473, +29483, 29501, 29527, 29531, 29537, 29567, 29569, 29573, 29581, 29587, 29599, +29611, 29629, 29633, 29641, 29663, 29669, 29671, 29683, 29717, 29723, 29741, +29753, 29759, 29761, 29789, 29803, 29819, 29833, 29837, 29851, 29863, 29867, +29873, 29879, 29881, 29917, 29921, 29927, 29947, 29959, 29983, 29989, 30011, +30013, 30029, 30047, 30059, 30071, 30089, 30091, 30097, 30103, 30109, 30113, +30119, 30133, 30137, 30139, 30161, 30169, 30181, 30187, 30197, 30203, 30211, +30223, 30241, 30253, 30259, 30269, 30271, 30293, 30307, 30313, 30319, 30323, +30341, 30347, 30367, 30389, 30391, 30403, 30427, 30431, 30449, 30467, 30469, +30491, 30493, 30497, 30509, 30517, 30529, 30539, 30553, 30557, 30559, 30577, +30593, 30631, 30637, 30643, 30649, 30661, 30671, 30677, 30689, 30697, 30703, +30707, 30713, 30727, 30757, 30763, 30773, 30781, 30803, 30809, 30817, 30829, +30839, 30841, 30851, 30853, 30859, 30869, 30871, 30881, 30893, 30911, 30931, +30937, 30941, 30949, 30971, 30977, 30983, 31013, 31019, 31033, 31039, 31051, +31063, 31069, 31079, 31081, 31091, 31121, 31123, 31139, 31147, 31151, 31153, +31159, 31177, 31181, 31183, 31189, 31193, 31219, 31223, 31231, 31237, 31247, +31249, 31253, 31259, 31267, 31271, 31277, 31307, 31319, 31321, 31327, 31333, +31337, 31357, 31379, 31387, 31391, 31393, 31397, 31469, 31477, 31481, 31489, +31511, 31513, 31517, 31531, 31541, 31543, 31547, 31567, 31573, 31583, 31601, +31607, 31627, 31643, 31649, 31657, 31663, 31667, 31687, 31699, 31721, 31723, +31727, 31729, 31741, 31751, 31769, 31771, 31793, 31799, 31817, 31847, 31849, +31859, 31873, 31883, 31891, 31907, 31957, 31963, 31973, 31981, 31991, 32003, +32009, 32027, 32029, 32051, 32057, 32059, 32063, 32069, 32077, 32083, 32089, +32099, 32117, 32119, 32141, 32143, 32159, 32173, 32183, 32189, 32191, 32203, +32213, 32233, 32237, 32251, 32257, 32261, 32297, 32299, 32303, 32309, 32321, +32323, 32327, 32341, 32353, 32359, 32363, 32369, 32371, 32377, 32381, 32401, +32411, 32413, 32423, 32429, 32441, 32443, 32467, 32479, 32491, 32497, 32503, +32507, 32531, 32533, 32537, 32561, 32563, 32569, 32573, 32579, 32587, 32603, +32609, 32611, 32621, 32633, 32647, 32653, 32687, 32693, 32707, 32713, 32717, +32719, 32749, 32771, 32779, 32783, 32789, 32797, 32801, 32803, 32831, 32833, +32839, 32843, 32869, 32887, 32909, 32911, 32917, 32933, 32939, 32941, 32957, +32969, 32971, 32983, 32987, 32993, 32999, 33013, 33023, 33029, 33037, 33049, +33053, 33071, 33073, 33083, 33091, 33107, 33113, 33119, 33149, 33151, 33161, +33179, 33181, 33191, 33199, 33203, 33211, 33223, 33247, 33287, 33289, 33301, +33311, 33317, 33329, 33331, 33343, 33347, 33349, 33353, 33359, 33377, 33391, +33403, 33409, 33413, 33427, 33457, 33461, 33469, 33479, 33487, 33493, 33503, +33521, 33529, 33533, 33547, 33563, 33569, 33577, 33581, 33587, 33589, 33599, +33601, 33613, 33617, 33619, 33623, 33629, 33637, 33641, 33647, 33679, 33703, +33713, 33721, 33739, 33749, 33751, 33757, 33767, 33769, 33773, 33791, 33797, +33809, 33811, 33827, 33829, 33851, 33857, 33863, 33871, 33889, 33893, 33911, +33923, 33931, 33937, 33941, 33961, 33967, 33997, 34019, 34031, 34033, 34039, +34057, 34061, 34123, 34127, 34129, 34141, 34147, 34157, 34159, 34171, 34183, +34211, 34213, 34217, 34231, 34253, 34259, 34261, 34267, 34273, 34283, 34297, +34301, 34303, 34313, 34319, 34327, 34337, 34351, 34361, 34367, 34369, 34381, +34403, 34421, 34429, 34439, 34457, 34469, 34471, 34483, 34487, 34499, 34501, +34511, 34513, 34519, 34537, 34543, 34549, 34583, 34589, 34591, 34603, 34607, +34613, 34631, 34649, 34651, 34667, 34673, 34679, 34687, 34693, 34703, 34721, +34729, 34739, 34747, 34757, 34759, 34763, 34781, 34807, 34819, 34841, 34843, +34847, 34849, 34871, 34877, 34883, 34897, 34913, 34919, 34939, 34949, 34961, +34963, 34981, 35023, 35027, 35051, 35053, 35059, 35069, 35081, 35083, 35089, +35099, 35107, 35111, 35117, 35129, 35141, 35149, 35153, 35159, 35171, 35201, +35221, 35227, 35251, 35257, 35267, 35279, 35281, 35291, 35311, 35317, 35323, +35327, 35339, 35353, 35363, 35381, 35393, 35401, 35407, 35419, 35423, 35437, +35447, 35449, 35461, 35491, 35507, 35509, 35521, 35527, 35531, 35533, 35537, +35543, 35569, 35573, 35591, 35593, 35597, 35603, 35617, 35671, 35677, 35729, +35731, 35747, 35753, 35759, 35771, 35797, 35801, 35803, 35809, 35831, 35837, +35839, 35851, 35863, 35869, 35879, 35897, 35899, 35911, 35923, 35933, 35951, +35963, 35969, 35977, 35983, 35993, 35999, 36007, 36011, 36013, 36017, 36037, +36061, 36067, 36073, 36083, 36097, 36107, 36109, 36131, 36137, 36151, 36161, +36187, 36191, 36209, 36217, 36229, 36241, 36251, 36263, 36269, 36277, 36293, +36299, 36307, 36313, 36319, 36341, 36343, 36353, 36373, 36383, 36389, 36433, +36451, 36457, 36467, 36469, 36473, 36479, 36493, 36497, 36523, 36527, 36529, +36541, 36551, 36559, 36563, 36571, 36583, 36587, 36599, 36607, 36629, 36637, +36643, 36653, 36671, 36677, 36683, 36691, 36697, 36709, 36713, 36721, 36739, +36749, 36761, 36767, 36779, 36781, 36787, 36791, 36793, 36809, 36821, 36833, +36847, 36857, 36871, 36877, 36887, 36899, 36901, 36913, 36919, 36923, 36929, +36931, 36943, 36947, 36973, 36979, 36997, 37003, 37013, 37019, 37021, 37039, +37049, 37057, 37061, 37087, 37097, 37117, 37123, 37139, 37159, 37171, 37181, +37189, 37199, 37201, 37217, 37223, 37243, 37253, 37273, 37277, 37307, 37309, +37313, 37321, 37337, 37339, 37357, 37361, 37363, 37369, 37379, 37397, 37409, +37423, 37441, 37447, 37463, 37483, 37489, 37493, 37501, 37507, 37511, 37517, +37529, 37537, 37547, 37549, 37561, 37567, 37571, 37573, 37579, 37589, 37591, +37607, 37619, 37633, 37643, 37649, 37657, 37663, 37691, 37693, 37699, 37717, +37747, 37781, 37783, 37799, 37811, 37813, 37831, 37847, 37853, 37861, 37871, +37879, 37889, 37897, 37907, 37951, 37957, 37963, 37967, 37987, 37991, 37993, +37997, 38011, 38039, 38047, 38053, 38069, 38083, 38113, 38119, 38149, 38153, +38167, 38177, 38183, 38189, 38197, 38201, 38219, 38231, 38237, 38239, 38261, +38273, 38281, 38287, 38299, 38303, 38317, 38321, 38327, 38329, 38333, 38351, +38371, 38377, 38393, 38431, 38447, 38449, 38453, 38459, 38461, 38501, 38543, +38557, 38561, 38567, 38569, 38593, 38603, 38609, 38611, 38629, 38639, 38651, +38653, 38669, 38671, 38677, 38693, 38699, 38707, 38711, 38713, 38723, 38729, +38737, 38747, 38749, 38767, 38783, 38791, 38803, 38821, 38833, 38839, 38851, +38861, 38867, 38873, 38891, 38903, 38917, 38921, 38923, 38933, 38953, 38959, +38971, 38977, 38993, 39019, 39023, 39041, 39043, 39047, 39079, 39089, 39097, +39103, 39107, 39113, 39119, 39133, 39139, 39157, 39161, 39163, 39181, 39191, +39199, 39209, 39217, 39227, 39229, 39233, 39239, 39241, 39251, 39293, 39301, +39313, 39317, 39323, 39341, 39343, 39359, 39367, 39371, 39373, 39383, 39397, +39409, 39419, 39439, 39443, 39451, 39461, 39499, 39503, 39509, 39511, 39521, +39541, 39551, 39563, 39569, 39581, 39607, 39619, 39623, 39631, 39659, 39667, +39671, 39679, 39703, 39709, 39719, 39727, 39733, 39749, 39761, 39769, 39779, +39791, 39799, 39821, 39827, 39829, 39839, 39841, 39847, 39857, 39863, 39869, +39877, 39883, 39887, 39901, 39929, 39937, 39953, 39971, 39979, 39983, 39989, +40009, 40013, 40031, 40037, 40039, 40063, 40087, 40093, 40099, 40111, 40123, +40127, 40129, 40151, 40153, 40163, 40169, 40177, 40189, 40193, 40213, 40231, +40237, 40241, 40253, 40277, 40283, 40289, 40343, 40351, 40357, 40361, 40387, +40423, 40427, 40429, 40433, 40459, 40471, 40483, 40487, 40493, 40499, 40507, +40519, 40529, 40531, 40543, 40559, 40577, 40583, 40591, 40597, 40609, 40627, +40637, 40639, 40693, 40697, 40699, 40709, 40739, 40751, 40759, 40763, 40771, +40787, 40801, 40813, 40819, 40823, 40829, 40841, 40847, 40849, 40853, 40867, +40879, 40883, 40897, 40903, 40927, 40933, 40939, 40949, 40961, 40973, 40993, +41011, 41017, 41023, 41039, 41047, 41051, 41057, 41077, 41081, 41113, 41117, +41131, 41141, 41143, 41149, 41161, 41177, 41179, 41183, 41189, 41201, 41203, +41213, 41221, 41227, 41231, 41233, 41243, 41257, 41263, 41269, 41281, 41299, +41333, 41341, 41351, 41357, 41381, 41387, 41389, 41399, 41411, 41413, 41443, +41453, 41467, 41479, 41491, 41507, 41513, 41519, 41521, 41539, 41543, 41549, +41579, 41593, 41597, 41603, 41609, 41611, 41617, 41621, 41627, 41641, 41647, +41651, 41659, 41669, 41681, 41687, 41719, 41729, 41737, 41759, 41761, 41771, +41777, 41801, 41809, 41813, 41843, 41849, 41851, 41863, 41879, 41887, 41893, +41897, 41903, 41911, 41927, 41941, 41947, 41953, 41957, 41959, 41969, 41981, +41983, 41999, 42013, 42017, 42019, 42023, 42043, 42061, 42071, 42073, 42083, +42089, 42101, 42131, 42139, 42157, 42169, 42179, 42181, 42187, 42193, 42197, +42209, 42221, 42223, 42227, 42239, 42257, 42281, 42283, 42293, 42299, 42307, +42323, 42331, 42337, 42349, 42359, 42373, 42379, 42391, 42397, 42403, 42407, +42409, 42433, 42437, 42443, 42451, 42457, 42461, 42463, 42467, 42473, 42487, +42491, 42499, 42509, 42533, 42557, 42569, 42571, 42577, 42589, 42611, 42641, +42643, 42649, 42667, 42677, 42683, 42689, 42697, 42701, 42703, 42709, 42719, +42727, 42737, 42743, 42751, 42767, 42773, 42787, 42793, 42797, 42821, 42829, +42839, 42841, 42853, 42859, 42863, 42899, 42901, 42923, 42929, 42937, 42943, +42953, 42961, 42967, 42979, 42989, 43003, 43013, 43019, 43037, 43049, 43051, +43063, 43067, 43093, 43103, 43117, 43133, 43151, 43159, 43177, 43189, 43201, +43207, 43223, 43237, 43261, 43271, 43283, 43291, 43313, 43319, 43321, 43331, +43391, 43397, 43399, 43403, 43411, 43427, 43441, 43451, 43457, 43481, 43487, +43499, 43517, 43541, 43543, 43573, 43577, 43579, 43591, 43597, 43607, 43609, +43613, 43627, 43633, 43649, 43651, 43661, 43669, 43691, 43711, 43717, 43721, +43753, 43759, 43777, 43781, 43783, 43787, 43789, 43793, 43801, 43853, 43867, +43889, 43891, 43913, 43933, 43943, 43951, 43961, 43963, 43969, 43973, 43987, +43991, 43997, 44017, 44021, 44027, 44029, 44041, 44053, 44059, 44071, 44087, +44089, 44101, 44111, 44119, 44123, 44129, 44131, 44159, 44171, 44179, 44189, +44201, 44203, 44207, 44221, 44249, 44257, 44263, 44267, 44269, 44273, 44279, +44281, 44293, 44351, 44357, 44371, 44381, 44383, 44389, 44417, 44449, 44453, +44483, 44491, 44497, 44501, 44507, 44519, 44531, 44533, 44537, 44543, 44549, +44563, 44579, 44587, 44617, 44621, 44623, 44633, 44641, 44647, 44651, 44657, +44683, 44687, 44699, 44701, 44711, 44729, 44741, 44753, 44771, 44773, 44777, +44789, 44797, 44809, 44819, 44839, 44843, 44851, 44867, 44879, 44887, 44893, +44909, 44917, 44927, 44939, 44953, 44959, 44963, 44971, 44983, 44987, 45007, +45013, 45053, 45061, 45077, 45083, 45119, 45121, 45127, 45131, 45137, 45139, +45161, 45179, 45181, 45191, 45197, 45233, 45247, 45259, 45263, 45281, 45289, +45293, 45307, 45317, 45319, 45329, 45337, 45341, 45343, 45361, 45377, 45389, +45403, 45413, 45427, 45433, 45439, 45481, 45491, 45497, 45503, 45523, 45533, +45541, 45553, 45557, 45569, 45587, 45589, 45599, 45613, 45631, 45641, 45659, +45667, 45673, 45677, 45691, 45697, 45707, 45737, 45751, 45757, 45763, 45767, +45779, 45817, 45821, 45823, 45827, 45833, 45841, 45853, 45863, 45869, 45887, +45893, 45943, 45949, 45953, 45959, 45971, 45979, 45989, 46021, 46027, 46049, +46051, 46061, 46073, 46091, 46093, 46099, 46103, 46133, 46141, 46147, 46153, +46171, 46181, 46183, 46187, 46199, 46219, 46229, 46237, 46261, 46271, 46273, +46279, 46301, 46307, 46309, 46327, 46337, 46349, 46351, 46381, 46399, 46411, +46439, 46441, 46447, 46451, 46457, 46471, 46477, 46489, 46499, 46507, 46511, +46523, 46549, 46559, 46567, 46573, 46589, 46591, 46601, 46619, 46633, 46639, +46643, 46649, 46663, 46679, 46681, 46687, 46691, 46703, 46723, 46727, 46747, +46751, 46757, 46769, 46771, 46807, 46811, 46817, 46819, 46829, 46831, 46853, +46861, 46867, 46877, 46889, 46901, 46919, 46933, 46957, 46993, 46997, 47017, +47041, 47051, 47057, 47059, 47087, 47093, 47111, 47119, 47123, 47129, 47137, +47143, 47147, 47149, 47161, 47189, 47207, 47221, 47237, 47251, 47269, 47279, +47287, 47293, 47297, 47303, 47309, 47317, 47339, 47351, 47353, 47363, 47381, +47387, 47389, 47407, 47417, 47419, 47431, 47441, 47459, 47491, 47497, 47501, +47507, 47513, 47521, 47527, 47533, 47543, 47563, 47569, 47581, 47591, 47599, +47609, 47623, 47629, 47639, 47653, 47657, 47659, 47681, 47699, 47701, 47711, +47713, 47717, 47737, 47741, 47743, 47777, 47779, 47791, 47797, 47807, 47809, +47819, 47837, 47843, 47857, 47869, 47881, 47903, 47911, 47917, 47933, 47939, +47947, 47951, 47963, 47969, 47977, 47981, 48017, 48023, 48029, 48049, 48073, +48079, 48091, 48109, 48119, 48121, 48131, 48157, 48163, 48179, 48187, 48193, +48197, 48221, 48239, 48247, 48259, 48271, 48281, 48299, 48311, 48313, 48337, +48341, 48353, 48371, 48383, 48397, 48407, 48409, 48413, 48437, 48449, 48463, +48473, 48479, 48481, 48487, 48491, 48497, 48523, 48527, 48533, 48539, 48541, +48563, 48571, 48589, 48593, 48611, 48619, 48623, 48647, 48649, 48661, 48673, +48677, 48679, 48731, 48733, 48751, 48757, 48761, 48767, 48779, 48781, 48787, +48799, 48809, 48817, 48821, 48823, 48847, 48857, 48859, 48869, 48871, 48883, +48889, 48907, 48947, 48953, 48973, 48989, 48991, 49003, 49009, 49019, 49031, +49033, 49037, 49043, 49057, 49069, 49081, 49103, 49109, 49117, 49121, 49123, +49139, 49157, 49169, 49171, 49177, 49193, 49199, 49201, 49207, 49211, 49223, +49253, 49261, 49277, 49279, 49297, 49307, 49331, 49333, 49339, 49363, 49367, +49369, 49391, 49393, 49409, 49411, 49417, 49429, 49433, 49451, 49459, 49463, +49477, 49481, 49499, 49523, 49529, 49531, 49537, 49547, 49549, 49559, 49597, +49603, 49613, 49627, 49633, 49639, 49663, 49667, 49669, 49681, 49697, 49711, +49727, 49739, 49741, 49747, 49757, 49783, 49787, 49789, 49801, 49807, 49811, +49823, 49831, 49843, 49853, 49871, 49877, 49891, 49919, 49921, 49927, 49937, +49939, 49943, 49957, 49991, 49993, 49999, 50021, 50023, 50033, 50047, 50051, +50053, 50069, 50077, 50087, 50093, 50101, 50111, 50119, 50123, 50129, 50131, +50147, 50153, 50159, 50177, 50207, 50221, 50227, 50231, 50261, 50263, 50273, +50287, 50291, 50311, 50321, 50329, 50333, 50341, 50359, 50363, 50377, 50383, +50387, 50411, 50417, 50423, 50441, 50459, 50461, 50497, 50503, 50513, 50527, +50539, 50543, 50549, 50551, 50581, 50587, 50591, 50593, 50599, 50627, 50647, +50651, 50671, 50683, 50707, 50723, 50741, 50753, 50767, 50773, 50777, 50789, +50821, 50833, 50839, 50849, 50857, 50867, 50873, 50891, 50893, 50909, 50923, +50929, 50951, 50957, 50969, 50971, 50989, 50993, 51001, 51031, 51043, 51047, +51059, 51061, 51071, 51109, 51131, 51133, 51137, 51151, 51157, 51169, 51193, +51197, 51199, 51203, 51217, 51229, 51239, 51241, 51257, 51263, 51283, 51287, +51307, 51329, 51341, 51343, 51347, 51349, 51361, 51383, 51407, 51413, 51419, +51421, 51427, 51431, 51437, 51439, 51449, 51461, 51473, 51479, 51481, 51487, +51503, 51511, 51517, 51521, 51539, 51551, 51563, 51577, 51581, 51593, 51599, +51607, 51613, 51631, 51637, 51647, 51659, 51673, 51679, 51683, 51691, 51713, +51719, 51721, 51749, 51767, 51769, 51787, 51797, 51803, 51817, 51827, 51829, +51839, 51853, 51859, 51869, 51871, 51893, 51899, 51907, 51913, 51929, 51941, +51949, 51971, 51973, 51977, 51991, 52009, 52021, 52027, 52051, 52057, 52067, +52069, 52081, 52103, 52121, 52127, 52147, 52153, 52163, 52177, 52181, 52183, +52189, 52201, 52223, 52237, 52249, 52253, 52259, 52267, 52289, 52291, 52301, +52313, 52321, 52361, 52363, 52369, 52379, 52387, 52391, 52433, 52453, 52457, +52489, 52501, 52511, 52517, 52529, 52541, 52543, 52553, 52561, 52567, 52571, +52579, 52583, 52609, 52627, 52631, 52639, 52667, 52673, 52691, 52697, 52709, +52711, 52721, 52727, 52733, 52747, 52757, 52769, 52783, 52807, 52813, 52817, +52837, 52859, 52861, 52879, 52883, 52889, 52901, 52903, 52919, 52937, 52951, +52957, 52963, 52967, 52973, 52981, 52999, 53003, 53017, 53047, 53051, 53069, +53077, 53087, 53089, 53093, 53101, 53113, 53117, 53129, 53147, 53149, 53161, +53171, 53173, 53189, 53197, 53201, 53231, 53233, 53239, 53267, 53269, 53279, +53281, 53299, 53309, 53323, 53327, 53353, 53359, 53377, 53381, 53401, 53407, +53411, 53419, 53437, 53441, 53453, 53479, 53503, 53507, 53527, 53549, 53551, +53569, 53591, 53593, 53597, 53609, 53611, 53617, 53623, 53629, 53633, 53639, +53653, 53657, 53681, 53693, 53699, 53717, 53719, 53731, 53759, 53773, 53777, +53783, 53791, 53813, 53819, 53831, 53849, 53857, 53861, 53881, 53887, 53891, +53897, 53899, 53917, 53923, 53927, 53939, 53951, 53959, 53987, 53993, 54001, +54011, 54013, 54037, 54049, 54059, 54083, 54091, 54101, 54121, 54133, 54139, +54151, 54163, 54167, 54181, 54193, 54217, 54251, 54269, 54277, 54287, 54293, +54311, 54319, 54323, 54331, 54347, 54361, 54367, 54371, 54377, 54401, 54403, +54409, 54413, 54419, 54421, 54437, 54443, 54449, 54469, 54493, 54497, 54499, +54503, 54517, 54521, 54539, 54541, 54547, 54559, 54563, 54577, 54581, 54583, +54601, 54617, 54623, 54629, 54631, 54647, 54667, 54673, 54679, 54709, 54713, +54721, 54727, 54751, 54767, 54773, 54779, 54787, 54799, 54829, 54833, 54851, +54869, 54877, 54881, 54907, 54917, 54919, 54941, 54949, 54959, 54973, 54979, +54983, 55001, 55009, 55021, 55049, 55051, 55057, 55061, 55073, 55079, 55103, +55109, 55117, 55127, 55147, 55163, 55171, 55201, 55207, 55213, 55217, 55219, +55229, 55243, 55249, 55259, 55291, 55313, 55331, 55333, 55337, 55339, 55343, +55351, 55373, 55381, 55399, 55411, 55439, 55441, 55457, 55469, 55487, 55501, +55511, 55529, 55541, 55547, 55579, 55589, 55603, 55609, 55619, 55621, 55631, +55633, 55639, 55661, 55663, 55667, 55673, 55681, 55691, 55697, 55711, 55717, +55721, 55733, 55763, 55787, 55793, 55799, 55807, 55813, 55817, 55819, 55823, +55829, 55837, 55843, 55849, 55871, 55889, 55897, 55901, 55903, 55921, 55927, +55931, 55933, 55949, 55967, 55987, 55997, 56003, 56009, 56039, 56041, 56053, +56081, 56087, 56093, 56099, 56101, 56113, 56123, 56131, 56149, 56167, 56171, +56179, 56197, 56207, 56209, 56237, 56239, 56249, 56263, 56267, 56269, 56299, +56311, 56333, 56359, 56369, 56377, 56383, 56393, 56401, 56417, 56431, 56437, +56443, 56453, 56467, 56473, 56477, 56479, 56489, 56501, 56503, 56509, 56519, +56527, 56531, 56533, 56543, 56569, 56591, 56597, 56599, 56611, 56629, 56633, +56659, 56663, 56671, 56681, 56687, 56701, 56711, 56713, 56731, 56737, 56747, +56767, 56773, 56779, 56783, 56807, 56809, 56813, 56821, 56827, 56843, 56857, +56873, 56891, 56893, 56897, 56909, 56911, 56921, 56923, 56929, 56941, 56951, +56957, 56963, 56983, 56989, 56993, 56999, 57037, 57041, 57047, 57059, 57073, +57077, 57089, 57097, 57107, 57119, 57131, 57139, 57143, 57149, 57163, 57173, +57179, 57191, 57193, 57203, 57221, 57223, 57241, 57251, 57259, 57269, 57271, +57283, 57287, 57301, 57329, 57331, 57347, 57349, 57367, 57373, 57383, 57389, +57397, 57413, 57427, 57457, 57467, 57487, 57493, 57503, 57527, 57529, 57557, +57559, 57571, 57587, 57593, 57601, 57637, 57641, 57649, 57653, 57667, 57679, +57689, 57697, 57709, 57713, 57719, 57727, 57731, 57737, 57751, 57773, 57781, +57787, 57791, 57793, 57803, 57809, 57829, 57839, 57847, 57853, 57859, 57881, +57899, 57901, 57917, 57923, 57943, 57947, 57973, 57977, 57991, 58013, 58027, +58031, 58043, 58049, 58057, 58061, 58067, 58073, 58099, 58109, 58111, 58129, +58147, 58151, 58153, 58169, 58171, 58189, 58193, 58199, 58207, 58211, 58217, +58229, 58231, 58237, 58243, 58271, 58309, 58313, 58321, 58337, 58363, 58367, +58369, 58379, 58391, 58393, 58403, 58411, 58417, 58427, 58439, 58441, 58451, +58453, 58477, 58481, 58511, 58537, 58543, 58549, 58567, 58573, 58579, 58601, +58603, 58613, 58631, 58657, 58661, 58679, 58687, 58693, 58699, 58711, 58727, +58733, 58741, 58757, 58763, 58771, 58787, 58789, 58831, 58889, 58897, 58901, +58907, 58909, 58913, 58921, 58937, 58943, 58963, 58967, 58979, 58991, 58997, +59009, 59011, 59021, 59023, 59029, 59051, 59053, 59063, 59069, 59077, 59083, +59093, 59107, 59113, 59119, 59123, 59141, 59149, 59159, 59167, 59183, 59197, +59207, 59209, 59219, 59221, 59233, 59239, 59243, 59263, 59273, 59281, 59333, +59341, 59351, 59357, 59359, 59369, 59377, 59387, 59393, 59399, 59407, 59417, +59419, 59441, 59443, 59447, 59453, 59467, 59471, 59473, 59497, 59509, 59513, +59539, 59557, 59561, 59567, 59581, 59611, 59617, 59621, 59627, 59629, 59651, +59659, 59663, 59669, 59671, 59693, 59699, 59707, 59723, 59729, 59743, 59747, +59753, 59771, 59779, 59791, 59797, 59809, 59833, 59863, 59879, 59887, 59921, +59929, 59951, 59957, 59971, 59981, 59999, 60013, 60017, 60029, 60037, 60041, +60077, 60083, 60089, 60091, 60101, 60103, 60107, 60127, 60133, 60139, 60149, +60161, 60167, 60169, 60209, 60217, 60223, 60251, 60257, 60259, 60271, 60289, +60293, 60317, 60331, 60337, 60343, 60353, 60373, 60383, 60397, 60413, 60427, +60443, 60449, 60457, 60493, 60497, 60509, 60521, 60527, 60539, 60589, 60601, +60607, 60611, 60617, 60623, 60631, 60637, 60647, 60649, 60659, 60661, 60679, +60689, 60703, 60719, 60727, 60733, 60737, 60757, 60761, 60763, 60773, 60779, +60793, 60811, 60821, 60859, 60869, 60887, 60889, 60899, 60901, 60913, 60917, +60919, 60923, 60937, 60943, 60953, 60961, 61001, 61007, 61027, 61031, 61043, +61051, 61057, 61091, 61099, 61121, 61129, 61141, 61151, 61153, 61169, 61211, +61223, 61231, 61253, 61261, 61283, 61291, 61297, 61331, 61333, 61339, 61343, +61357, 61363, 61379, 61381, 61403, 61409, 61417, 61441, 61463, 61469, 61471, +61483, 61487, 61493, 61507, 61511, 61519, 61543, 61547, 61553, 61559, 61561, +61583, 61603, 61609, 61613, 61627, 61631, 61637, 61643, 61651, 61657, 61667, +61673, 61681, 61687, 61703, 61717, 61723, 61729, 61751, 61757, 61781, 61813, +61819, 61837, 61843, 61861, 61871, 61879, 61909, 61927, 61933, 61949, 61961, +61967, 61979, 61981, 61987, 61991, 62003, 62011, 62017, 62039, 62047, 62053, +62057, 62071, 62081, 62099, 62119, 62129, 62131, 62137, 62141, 62143, 62171, +62189, 62191, 62201, 62207, 62213, 62219, 62233, 62273, 62297, 62299, 62303, +62311, 62323, 62327, 62347, 62351, 62383, 62401, 62417, 62423, 62459, 62467, +62473, 62477, 62483, 62497, 62501, 62507, 62533, 62539, 62549, 62563, 62581, +62591, 62597, 62603, 62617, 62627, 62633, 62639, 62653, 62659, 62683, 62687, +62701, 62723, 62731, 62743, 62753, 62761, 62773, 62791, 62801, 62819, 62827, +62851, 62861, 62869, 62873, 62897, 62903, 62921, 62927, 62929, 62939, 62969, +62971, 62981, 62983, 62987, 62989, 63029, 63031, 63059, 63067, 63073, 63079, +63097, 63103, 63113, 63127, 63131, 63149, 63179, 63197, 63199, 63211, 63241, +63247, 63277, 63281, 63299, 63311, 63313, 63317, 63331, 63337, 63347, 63353, +63361, 63367, 63377, 63389, 63391, 63397, 63409, 63419, 63421, 63439, 63443, +63463, 63467, 63473, 63487, 63493, 63499, 63521, 63527, 63533, 63541, 63559, +63577, 63587, 63589, 63599, 63601, 63607, 63611, 63617, 63629, 63647, 63649, +63659, 63667, 63671, 63689, 63691, 63697, 63703, 63709, 63719, 63727, 63737, +63743, 63761, 63773, 63781, 63793, 63799, 63803, 63809, 63823, 63839, 63841, +63853, 63857, 63863, 63901, 63907, 63913, 63929, 63949, 63977, 63997, 64007, +64013, 64019, 64033, 64037, 64063, 64067, 64081, 64091, 64109, 64123, 64151, +64153, 64157, 64171, 64187, 64189, 64217, 64223, 64231, 64237, 64271, 64279, +64283, 64301, 64303, 64319, 64327, 64333, 64373, 64381, 64399, 64403, 64433, +64439, 64451, 64453, 64483, 64489, 64499, 64513, 64553, 64567, 64577, 64579, +64591, 64601, 64609, 64613, 64621, 64627, 64633, 64661, 64663, 64667, 64679, +64693, 64709, 64717, 64747, 64763, 64781, 64783, 64793, 64811, 64817, 64849, +64853, 64871, 64877, 64879, 64891, 64901, 64919, 64921, 64927, 64937, 64951, +64969, 64997, 65003, 65011, 65027, 65029, 65033, 65053, 65063, 65071, 65089, +65099, 65101, 65111, 65119, 65123, 65129, 65141, 65147, 65167, 65171, 65173, +65179, 65183, 65203, 65213, 65239, 65257, 65267, 65269, 65287, 65293, 65309, +65323, 65327, 65353, 65357, 65371, 65381, 65393, 65407, 65413, 65419, 65423, +65437, 65447, 65449, 65479, 65497, 65519, 65521, 0 }; + +} diff --git a/src/libs/3rdparty/botan/src/lib/math/numbertheory/reducer.cpp b/src/libs/3rdparty/botan/src/lib/math/numbertheory/reducer.cpp new file mode 100644 index 0000000000..98cf698ed7 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/math/numbertheory/reducer.cpp @@ -0,0 +1,90 @@ +/* +* Modular Reducer +* (C) 1999-2011,2018 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include + +namespace Botan { + +/* +* Modular_Reducer Constructor +*/ +Modular_Reducer::Modular_Reducer(const BigInt& mod) + { + if(mod < 0) + throw Invalid_Argument("Modular_Reducer: modulus must be positive"); + + // Left uninitialized if mod == 0 + m_mod_words = 0; + + if(mod > 0) + { + m_modulus = mod; + m_mod_words = m_modulus.sig_words(); + + m_modulus_2 = Botan::square(m_modulus); + + m_mu = BigInt::power_of_2(2 * BOTAN_MP_WORD_BITS * m_mod_words) / m_modulus; + } + } + +/* +* Barrett Reduction +*/ +BigInt Modular_Reducer::reduce(const BigInt& x) const + { + if(m_mod_words == 0) + throw Invalid_State("Modular_Reducer: Never initalized"); + + const size_t x_sw = x.sig_words(); + + 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); + } + + secure_vector ws; + + BigInt t1 = x; + t1.set_sign(BigInt::Positive); + t1 >>= (BOTAN_MP_WORD_BITS * (m_mod_words - 1)); + + t1.mul(m_mu, ws); + t1 >>= (BOTAN_MP_WORD_BITS * (m_mod_words + 1)); + + // TODO add masked mul to avoid computing high bits + t1.mul(m_modulus, ws); + t1.mask_bits(BOTAN_MP_WORD_BITS * (m_mod_words + 1)); + + t1.rev_sub(x.data(), std::min(x_sw, m_mod_words + 1), ws); + + /* + * If t1 < 0 then we must add b^(k+1) where b = 2^w. To avoid a + * side channel perform the addition unconditionally, with ws set + * to either b^(k+1) or else 0. + */ + const word t1_neg = t1.is_negative(); + + if(ws.size() < m_mod_words + 2) + ws.resize(m_mod_words + 2); + clear_mem(ws.data(), ws.size()); + ws[m_mod_words + 1] = t1_neg; + + t1.add(ws.data(), m_mod_words + 2, BigInt::Positive); + + t1.reduce_below(m_modulus, ws); + + if(x.is_negative() && t1.is_nonzero()) + { + 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 new file mode 100644 index 0000000000..c66c220342 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/math/numbertheory/reducer.h @@ -0,0 +1,61 @@ +/* +* Modular Reducer +* (C) 1999-2010 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_MODULAR_REDUCER_H_ +#define BOTAN_MODULAR_REDUCER_H_ + +#include + +namespace Botan { + +/** +* Modular Reducer (using Barrett's technique) +*/ +class BOTAN_PUBLIC_API(2,0) Modular_Reducer + { + public: + const BigInt& get_modulus() const { return m_modulus; } + + BigInt reduce(const BigInt& x) const; + + /** + * Multiply mod p + * @param x the first operand + * @param y the second operand + * @return (x * y) % p + */ + BigInt multiply(const BigInt& x, const BigInt& y) const + { return reduce(x * y); } + + /** + * Square mod p + * @param x the value to square + * @return (x * x) % p + */ + BigInt square(const BigInt& x) const + { return reduce(Botan::square(x)); } + + /** + * Cube mod p + * @param x the value to cube + * @return (x * x * x) % p + */ + BigInt cube(const BigInt& x) const + { return multiply(x, this->square(x)); } + + bool initialized() const { return (m_mod_words != 0); } + + Modular_Reducer() { m_mod_words = 0; } + explicit Modular_Reducer(const BigInt& mod); + private: + BigInt m_modulus, m_modulus_2, m_mu; + size_t m_mod_words; + }; + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/math/numbertheory/ressol.cpp b/src/libs/3rdparty/botan/src/lib/math/numbertheory/ressol.cpp new file mode 100644 index 0000000000..9d11ebbc42 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/math/numbertheory/ressol.cpp @@ -0,0 +1,87 @@ +/* +* Shanks-Tonnelli (RESSOL) +* (C) 2007-2008 Falko Strenzke, FlexSecure GmbH +* (C) 2008 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include + +namespace Botan { + +/* +* Shanks-Tonnelli algorithm +*/ +BigInt ressol(const BigInt& a, const BigInt& p) + { + if(a == 0) + return 0; + else if(a < 0) + throw Invalid_Argument("ressol: value to solve for must be positive"); + else if(a >= p) + throw Invalid_Argument("ressol: value to solve for must be less than p"); + + if(p == 2) + return a; + else if(p <= 1) + throw Invalid_Argument("ressol: prime must be > 1 a"); + else if(p.is_even()) + throw Invalid_Argument("ressol: invalid prime"); + + if(jacobi(a, p) != 1) // not a quadratic residue + return -BigInt(1); + + if(p % 4 == 3) + return power_mod(a, ((p+1) >> 2), p); + + size_t s = low_zero_bits(p - 1); + BigInt q = p >> s; + + q -= 1; + q >>= 1; + + Modular_Reducer mod_p(p); + + BigInt r = power_mod(a, q, p); + BigInt n = mod_p.multiply(a, mod_p.square(r)); + r = mod_p.multiply(r, a); + + if(n == 1) + return r; + + // find random non quadratic residue z + BigInt z = 2; + while(jacobi(z, p) == 1) // while z quadratic residue + ++z; + + BigInt c = power_mod(z, (q << 1) + 1, p); + + while(n > 1) + { + q = n; + + size_t i = 0; + while(q != 1) + { + q = mod_p.square(q); + ++i; + + if(i >= s) + { + return -BigInt(1); + } + } + + c = power_mod(c, BigInt::power_of_2(s-i-1), p); + r = mod_p.multiply(r, c); + c = mod_p.square(c); + n = mod_p.multiply(n, c); + s = i; + } + + return r; + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/modes/cbc/cbc.cpp b/src/libs/3rdparty/botan/src/lib/modes/cbc/cbc.cpp new file mode 100644 index 0000000000..c67664a6e7 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/modes/cbc/cbc.cpp @@ -0,0 +1,312 @@ +/* +* CBC Mode +* (C) 1999-2007,2013,2017 Jack Lloyd +* (C) 2016 Daniel Neus, Rohde & Schwarz Cybersecurity +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include + +namespace Botan { + +CBC_Mode::CBC_Mode(BlockCipher* cipher, BlockCipherModePaddingMethod* padding) : + m_cipher(cipher), + m_padding(padding), + m_state(m_cipher->block_size()) + { + if(m_padding && !m_padding->valid_blocksize(cipher->block_size())) + throw Invalid_Argument("Padding " + m_padding->name() + + " cannot be used with " + + cipher->name() + "/CBC"); + } + +void CBC_Mode::clear() + { + m_cipher->clear(); + reset(); + } + +void CBC_Mode::reset() + { + zeroise(m_state); + } + +std::string CBC_Mode::name() const + { + if(m_padding) + return cipher().name() + "/CBC/" + padding().name(); + else + return cipher().name() + "/CBC/CTS"; + } + +size_t CBC_Mode::update_granularity() const + { + return cipher().parallel_bytes(); + } + +Key_Length_Specification CBC_Mode::key_spec() const + { + return cipher().key_spec(); + } + +size_t CBC_Mode::default_nonce_length() const + { + return block_size(); + } + +bool CBC_Mode::valid_nonce_length(size_t n) const + { + return (n == 0 || n == block_size()); + } + +void CBC_Mode::key_schedule(const uint8_t key[], size_t length) + { + m_cipher->set_key(key, length); + } + +void CBC_Mode::start_msg(const uint8_t nonce[], size_t nonce_len) + { + if(!valid_nonce_length(nonce_len)) + throw Invalid_IV_Length(name(), nonce_len); + + /* + * A nonce of zero length means carry the last ciphertext value over + * as the new IV, as unfortunately some protocols require this. If + * this is the first message then we use an IV of all zeros. + */ + if(nonce_len) + m_state.assign(nonce, nonce + nonce_len); + } + +size_t CBC_Encryption::minimum_final_size() const + { + return 0; + } + +size_t CBC_Encryption::output_length(size_t input_length) const + { + if(input_length == 0) + return block_size(); + else + return round_up(input_length, block_size()); + } + +size_t CBC_Encryption::process(uint8_t buf[], size_t sz) + { + const size_t BS = block_size(); + + BOTAN_ASSERT(sz % BS == 0, "CBC input is full blocks"); + const size_t blocks = sz / BS; + + if(blocks > 0) + { + xor_buf(&buf[0], state_ptr(), BS); + cipher().encrypt(&buf[0]); + + for(size_t i = 1; i != blocks; ++i) + { + xor_buf(&buf[BS*i], &buf[BS*(i-1)], BS); + cipher().encrypt(&buf[BS*i]); + } + + state().assign(&buf[BS*(blocks-1)], &buf[BS*blocks]); + } + + return sz; + } + +void CBC_Encryption::finish(secure_vector& buffer, size_t offset) + { + BOTAN_ASSERT(buffer.size() >= offset, "Offset is sane"); + + const size_t BS = block_size(); + + const size_t bytes_in_final_block = (buffer.size()-offset) % BS; + + padding().add_padding(buffer, bytes_in_final_block, BS); + + if((buffer.size()-offset) % BS) + throw Exception("Did not pad to full block size in " + name()); + + update(buffer, offset); + } + +bool CTS_Encryption::valid_nonce_length(size_t n) const + { + return (n == block_size()); + } + +size_t CTS_Encryption::minimum_final_size() const + { + return block_size() + 1; + } + +size_t CTS_Encryption::output_length(size_t input_length) const + { + return input_length; // no ciphertext expansion in CTS + } + +void CTS_Encryption::finish(secure_vector& buffer, size_t offset) + { + BOTAN_ASSERT(buffer.size() >= offset, "Offset is sane"); + uint8_t* buf = buffer.data() + offset; + const size_t sz = buffer.size() - offset; + + const size_t BS = block_size(); + + if(sz < BS + 1) + throw Encoding_Error(name() + ": insufficient data to encrypt"); + + if(sz % BS == 0) + { + update(buffer, offset); + + // swap last two blocks + for(size_t i = 0; i != BS; ++i) + std::swap(buffer[buffer.size()-BS+i], buffer[buffer.size()-2*BS+i]); + } + else + { + const size_t full_blocks = ((sz / BS) - 1) * BS; + const size_t final_bytes = sz - full_blocks; + BOTAN_ASSERT(final_bytes > BS && final_bytes < 2*BS, "Left over size in expected range"); + + secure_vector last(buf + full_blocks, buf + full_blocks + final_bytes); + buffer.resize(full_blocks + offset); + update(buffer, offset); + + xor_buf(last.data(), state_ptr(), BS); + cipher().encrypt(last.data()); + + for(size_t i = 0; i != final_bytes - BS; ++i) + { + last[i] ^= last[i + BS]; + last[i + BS] ^= last[i]; + } + + cipher().encrypt(last.data()); + + buffer += last; + } + } + +size_t CBC_Decryption::output_length(size_t input_length) const + { + return input_length; // precise for CTS, worst case otherwise + } + +size_t CBC_Decryption::minimum_final_size() const + { + return block_size(); + } + +size_t CBC_Decryption::process(uint8_t buf[], size_t sz) + { + const size_t BS = block_size(); + + BOTAN_ASSERT(sz % BS == 0, "Input is full blocks"); + size_t blocks = sz / BS; + + while(blocks) + { + const size_t to_proc = std::min(BS * blocks, m_tempbuf.size()); + + cipher().decrypt_n(buf, m_tempbuf.data(), to_proc / BS); + + xor_buf(m_tempbuf.data(), state_ptr(), BS); + xor_buf(&m_tempbuf[BS], buf, to_proc - BS); + copy_mem(state_ptr(), buf + (to_proc - BS), BS); + + copy_mem(buf, m_tempbuf.data(), to_proc); + + buf += to_proc; + blocks -= to_proc / BS; + } + + return sz; + } + +void CBC_Decryption::finish(secure_vector& buffer, size_t offset) + { + BOTAN_ASSERT(buffer.size() >= offset, "Offset is sane"); + const size_t sz = buffer.size() - offset; + + const size_t BS = block_size(); + + if(sz == 0 || sz % BS) + throw Decoding_Error(name() + ": Ciphertext not a multiple of block size"); + + update(buffer, offset); + + const size_t pad_bytes = BS - padding().unpad(&buffer[buffer.size()-BS], BS); + buffer.resize(buffer.size() - pad_bytes); // remove padding + if(pad_bytes == 0 && padding().name() != "NoPadding") + { + throw Decoding_Error(name()); + } + } + +void CBC_Decryption::reset() + { + zeroise(state()); + zeroise(m_tempbuf); + } + +bool CTS_Decryption::valid_nonce_length(size_t n) const + { + return (n == block_size()); + } + +size_t CTS_Decryption::minimum_final_size() const + { + return block_size() + 1; + } + +void CTS_Decryption::finish(secure_vector& buffer, size_t offset) + { + BOTAN_ASSERT(buffer.size() >= offset, "Offset is sane"); + const size_t sz = buffer.size() - offset; + uint8_t* buf = buffer.data() + offset; + + const size_t BS = block_size(); + + if(sz < BS + 1) + throw Encoding_Error(name() + ": insufficient data to decrypt"); + + if(sz % BS == 0) + { + // swap last two blocks + + for(size_t i = 0; i != BS; ++i) + std::swap(buffer[buffer.size()-BS+i], buffer[buffer.size()-2*BS+i]); + + update(buffer, offset); + } + else + { + const size_t full_blocks = ((sz / BS) - 1) * BS; + const size_t final_bytes = sz - full_blocks; + BOTAN_ASSERT(final_bytes > BS && final_bytes < 2*BS, "Left over size in expected range"); + + secure_vector last(buf + full_blocks, buf + full_blocks + final_bytes); + buffer.resize(full_blocks + offset); + update(buffer, offset); + + cipher().decrypt(last.data()); + + xor_buf(last.data(), &last[BS], final_bytes - BS); + + for(size_t i = 0; i != final_bytes - BS; ++i) + std::swap(last[i], last[i + BS]); + + cipher().decrypt(last.data()); + xor_buf(last.data(), state_ptr(), BS); + + buffer += last; + } + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/modes/cbc/cbc.h b/src/libs/3rdparty/botan/src/lib/modes/cbc/cbc.h new file mode 100644 index 0000000000..65b6395115 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/modes/cbc/cbc.h @@ -0,0 +1,154 @@ +/* +* CBC mode +* (C) 1999-2007,2013 Jack Lloyd +* (C) 2016 Daniel Neus, Rohde & Schwarz Cybersecurity +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_MODE_CBC_H_ +#define BOTAN_MODE_CBC_H_ + +#include +#include +#include + +namespace Botan { + +/** +* CBC Mode +*/ +class BOTAN_PUBLIC_API(2,0) CBC_Mode : public Cipher_Mode + { + public: + std::string name() const override; + + size_t update_granularity() const override; + + Key_Length_Specification key_spec() const override; + + size_t default_nonce_length() const override; + + bool valid_nonce_length(size_t n) const override; + + void clear() override; + + void reset() override; + + protected: + CBC_Mode(BlockCipher* cipher, BlockCipherModePaddingMethod* padding); + + const BlockCipher& cipher() const { return *m_cipher; } + + const BlockCipherModePaddingMethod& padding() const + { + BOTAN_ASSERT_NONNULL(m_padding); + return *m_padding; + } + + secure_vector& state() { return m_state; } + + size_t block_size() const { return m_state.size(); } + + uint8_t* state_ptr() { return m_state.data(); } + + private: + void start_msg(const uint8_t nonce[], size_t nonce_len) override; + + void key_schedule(const uint8_t key[], size_t length) override; + + std::unique_ptr m_cipher; + std::unique_ptr m_padding; + secure_vector m_state; + }; + +/** +* CBC Encryption +*/ +class BOTAN_PUBLIC_API(2,0) CBC_Encryption : public CBC_Mode + { + public: + /** + * @param cipher block cipher to use + * @param padding padding method to use + */ + CBC_Encryption(BlockCipher* cipher, BlockCipherModePaddingMethod* padding) : + CBC_Mode(cipher, padding) {} + + size_t process(uint8_t buf[], size_t size) override; + + void finish(secure_vector& final_block, size_t offset = 0) override; + + size_t output_length(size_t input_length) const override; + + size_t minimum_final_size() const override; + }; + +/** +* CBC Encryption with ciphertext stealing (CBC-CS3 variant) +*/ +class BOTAN_PUBLIC_API(2,0) CTS_Encryption final : public CBC_Encryption + { + public: + /** + * @param cipher block cipher to use + */ + explicit CTS_Encryption(BlockCipher* cipher) : CBC_Encryption(cipher, nullptr) {} + + size_t output_length(size_t input_length) const override; + + void finish(secure_vector& final_block, size_t offset = 0) override; + + size_t minimum_final_size() const override; + + bool valid_nonce_length(size_t n) const override; + }; + +/** +* CBC Decryption +*/ +class BOTAN_PUBLIC_API(2,0) CBC_Decryption : public CBC_Mode + { + public: + /** + * @param cipher block cipher to use + * @param padding padding method to use + */ + CBC_Decryption(BlockCipher* cipher, BlockCipherModePaddingMethod* padding) : + CBC_Mode(cipher, padding), m_tempbuf(update_granularity()) {} + + size_t process(uint8_t buf[], size_t size) override; + + void finish(secure_vector& final_block, size_t offset = 0) override; + + size_t output_length(size_t input_length) const override; + + size_t minimum_final_size() const override; + + void reset() override; + + private: + secure_vector m_tempbuf; + }; + +/** +* CBC Decryption with ciphertext stealing (CBC-CS3 variant) +*/ +class BOTAN_PUBLIC_API(2,0) CTS_Decryption final : public CBC_Decryption + { + public: + /** + * @param cipher block cipher to use + */ + explicit CTS_Decryption(BlockCipher* cipher) : CBC_Decryption(cipher, nullptr) {} + + void finish(secure_vector& final_block, size_t offset = 0) override; + + size_t minimum_final_size() const override; + + bool valid_nonce_length(size_t n) const override; + }; + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/modes/cbc/info.txt b/src/libs/3rdparty/botan/src/lib/modes/cbc/info.txt new file mode 100644 index 0000000000..778ba1e252 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/modes/cbc/info.txt @@ -0,0 +1,8 @@ + +MODE_CBC -> 20131128 + + + +block +mode_pad + diff --git a/src/libs/3rdparty/botan/src/lib/modes/cipher_mode.cpp b/src/libs/3rdparty/botan/src/lib/modes/cipher_mode.cpp new file mode 100644 index 0000000000..00d7a4db08 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/modes/cipher_mode.cpp @@ -0,0 +1,188 @@ +/* +* Cipher Modes +* (C) 2015 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include +#include + +#if defined(BOTAN_HAS_BLOCK_CIPHER) + #include +#endif + +#if defined(BOTAN_HAS_AEAD_MODES) + #include +#endif + +#if defined(BOTAN_HAS_MODE_CBC) + #include +#endif + +#if defined(BOTAN_HAS_MODE_CFB) + #include +#endif + +#if defined(BOTAN_HAS_MODE_XTS) + #include +#endif + +#if defined(BOTAN_HAS_OPENSSL) + #include +#endif + +namespace Botan { + +std::unique_ptr Cipher_Mode::create_or_throw(const std::string& algo, + Cipher_Dir direction, + const std::string& provider) + { + if(auto mode = Cipher_Mode::create(algo, direction, provider)) + return mode; + + throw Lookup_Error("Cipher mode", algo, provider); + } + +std::unique_ptr Cipher_Mode::create(const std::string& algo, + Cipher_Dir direction, + const std::string& provider) + { +#if defined(BOTAN_HAS_OPENSSL) + if(provider.empty() || provider == "openssl") + { + std::unique_ptr openssl_cipher(make_openssl_cipher_mode(algo, direction)); + + if(openssl_cipher) + return openssl_cipher; + + if(!provider.empty()) + return std::unique_ptr(); + } +#endif + +#if defined(BOTAN_HAS_STREAM_CIPHER) + if(auto sc = StreamCipher::create(algo)) + { + return std::unique_ptr(new Stream_Cipher_Mode(sc.release())); + } +#endif + +#if defined(BOTAN_HAS_AEAD_MODES) + if(auto aead = AEAD_Mode::create(algo, direction)) + { + return std::unique_ptr(aead.release()); + } +#endif + + if(algo.find('/') != std::string::npos) + { + const std::vector algo_parts = split_on(algo, '/'); + const std::string cipher_name = algo_parts[0]; + const std::vector mode_info = parse_algorithm_name(algo_parts[1]); + + if(mode_info.empty()) + return std::unique_ptr(); + + std::ostringstream alg_args; + + alg_args << '(' << cipher_name; + for(size_t i = 1; i < mode_info.size(); ++i) + alg_args << ',' << mode_info[i]; + for(size_t i = 2; i < algo_parts.size(); ++i) + alg_args << ',' << algo_parts[i]; + alg_args << ')'; + + const std::string mode_name = mode_info[0] + alg_args.str(); + return Cipher_Mode::create(mode_name, direction, provider); + } + +#if defined(BOTAN_HAS_BLOCK_CIPHER) + + SCAN_Name spec(algo); + + if(spec.arg_count() == 0) + { + return std::unique_ptr(); + } + + std::unique_ptr bc(BlockCipher::create(spec.arg(0), provider)); + + if(!bc) + { + return std::unique_ptr(); + } + +#if defined(BOTAN_HAS_MODE_CBC) + if(spec.algo_name() == "CBC") + { + const std::string padding = spec.arg(1, "PKCS7"); + + if(padding == "CTS") + { + if(direction == ENCRYPTION) + return std::unique_ptr(new CTS_Encryption(bc.release())); + else + return std::unique_ptr(new CTS_Decryption(bc.release())); + } + else + { + std::unique_ptr pad(get_bc_pad(padding)); + + if(pad) + { + if(direction == ENCRYPTION) + return std::unique_ptr(new CBC_Encryption(bc.release(), pad.release())); + else + return std::unique_ptr(new CBC_Decryption(bc.release(), pad.release())); + } + } + } +#endif + +#if defined(BOTAN_HAS_MODE_XTS) + if(spec.algo_name() == "XTS") + { + if(direction == ENCRYPTION) + return std::unique_ptr(new XTS_Encryption(bc.release())); + else + return std::unique_ptr(new XTS_Decryption(bc.release())); + } +#endif + +#if defined(BOTAN_HAS_MODE_CFB) + if(spec.algo_name() == "CFB") + { + const size_t feedback_bits = spec.arg_as_integer(1, 8*bc->block_size()); + if(direction == ENCRYPTION) + return std::unique_ptr(new CFB_Encryption(bc.release(), feedback_bits)); + else + return std::unique_ptr(new CFB_Decryption(bc.release(), feedback_bits)); + } +#endif + +#endif + + return std::unique_ptr(); + } + +//static +std::vector Cipher_Mode::providers(const std::string& algo_spec) + { + const std::vector& possible = { "base", "openssl" }; + std::vector providers; + for(auto&& prov : possible) + { + std::unique_ptr mode = Cipher_Mode::create(algo_spec, ENCRYPTION, prov); + if(mode) + { + providers.push_back(prov); // available + } + } + return providers; + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/modes/cipher_mode.h b/src/libs/3rdparty/botan/src/lib/modes/cipher_mode.h new file mode 100644 index 0000000000..f67e737a43 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/modes/cipher_mode.h @@ -0,0 +1,257 @@ +/* +* Cipher Modes +* (C) 2013,2016 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_CIPHER_MODE_H_ +#define BOTAN_CIPHER_MODE_H_ + +#include +#include +#include +#include +#include +#include + +namespace Botan { + +/** +* The two possible directions for cipher filters, determining whether they +* actually perform encryption or decryption. +*/ +enum Cipher_Dir : int { ENCRYPTION, DECRYPTION }; + +/** +* Interface for cipher modes +*/ +class BOTAN_PUBLIC_API(2,0) Cipher_Mode + { + public: + virtual ~Cipher_Mode() = default; + + /** + * @return list of available providers for this algorithm, empty if not available + * @param algo_spec algorithm name + */ + static std::vector providers(const std::string& algo_spec); + + /** + * Create an AEAD mode + * @param algo the algorithm to create + * @param direction specify if this should be an encryption or decryption AEAD + * @param provider optional specification for provider to use + * @return an AEAD mode or a null pointer if not available + */ + static std::unique_ptr create(const std::string& algo, + Cipher_Dir direction, + const std::string& provider = ""); + + /** + * Create an AEAD mode, or throw + * @param algo the algorithm to create + * @param direction specify if this should be an encryption or decryption AEAD + * @param provider optional specification for provider to use + * @return an AEAD mode, or throw an exception + */ + static std::unique_ptr create_or_throw(const std::string& algo, + Cipher_Dir direction, + const std::string& provider = ""); + + /* + * Prepare for processing a message under the specified nonce + */ + virtual void start_msg(const uint8_t nonce[], size_t nonce_len) = 0; + + /** + * Begin processing a message. + * @param nonce the per message nonce + */ + template + void start(const std::vector& nonce) + { + start_msg(nonce.data(), nonce.size()); + } + + /** + * Begin processing a message. + * @param nonce the per message nonce + * @param nonce_len length of nonce + */ + void start(const uint8_t nonce[], size_t nonce_len) + { + start_msg(nonce, nonce_len); + } + + /** + * Begin processing a message. + */ + void start() + { + return start_msg(nullptr, 0); + } + + /** + * Process message blocks + * + * Input must be a multiple of update_granularity + * + * Processes msg in place and returns bytes written. Normally + * this will be either msg_len (indicating the entire message was + * processed) or for certain AEAD modes zero (indicating that the + * mode requires the entire message be processed in one pass). + * + * @param msg the message to be processed + * @param msg_len length of the message in bytes + */ + virtual size_t process(uint8_t msg[], size_t msg_len) = 0; + + /** + * Process some data. Input must be in size update_granularity() uint8_t blocks. + * @param buffer in/out parameter which will possibly be resized + * @param offset an offset into blocks to begin processing + */ + void update(secure_vector& buffer, size_t offset = 0) + { + BOTAN_ASSERT(buffer.size() >= offset, "Offset ok"); + uint8_t* buf = buffer.data() + offset; + const size_t buf_size = buffer.size() - offset; + + const size_t written = process(buf, buf_size); + buffer.resize(offset + written); + } + + /** + * Complete processing of a message. + * + * @param final_block in/out parameter which must be at least + * minimum_final_size() bytes, and will be set to any final output + * @param offset an offset into final_block to begin processing + */ + virtual void finish(secure_vector& final_block, size_t offset = 0) = 0; + + /** + * 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. + */ + virtual size_t output_length(size_t input_length) const = 0; + + /** + * @return size of required blocks to update + */ + virtual size_t update_granularity() const = 0; + + /** + * @return required minimium size to finalize() - may be any + * length larger than this. + */ + virtual size_t minimum_final_size() const = 0; + + /** + * @return the default size for a nonce + */ + virtual size_t default_nonce_length() const = 0; + + /** + * @return true iff nonce_len is a valid length for the nonce + */ + 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 + */ + virtual void reset() = 0; + + /** + * @return true iff this mode provides authentication as well as + * confidentiality. + */ + virtual bool authenticated() const { return false; } + + /** + * @return the size of the authentication tag used (in bytes) + */ + 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 + void set_key(const std::vector& 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; + }; + +/** +* Get a cipher mode by name (eg "AES-128/CBC" or "Serpent/XTS") +* @param algo_spec cipher name +* @param direction ENCRYPTION or DECRYPTION +* @param provider provider implementation to choose +*/ +inline Cipher_Mode* get_cipher_mode(const std::string& algo_spec, + Cipher_Dir direction, + const std::string& provider = "") + { + return Cipher_Mode::create(algo_spec, direction, provider).release(); + } + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/modes/info.txt b/src/libs/3rdparty/botan/src/lib/modes/info.txt new file mode 100644 index 0000000000..4c19db04ca --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/modes/info.txt @@ -0,0 +1,9 @@ + +MODES -> 20150626 +CIPHER_MODES -> 20180124 + + + +cipher_mode.h +stream_mode.h + diff --git a/src/libs/3rdparty/botan/src/lib/modes/mode_pad/info.txt b/src/libs/3rdparty/botan/src/lib/modes/mode_pad/info.txt new file mode 100644 index 0000000000..12b6e5b3a9 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/modes/mode_pad/info.txt @@ -0,0 +1,3 @@ + +CIPHER_MODE_PADDING -> 20131128 + 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 new file mode 100644 index 0000000000..f93b2dcccc --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/modes/mode_pad/mode_pad.cpp @@ -0,0 +1,196 @@ +/* +* CBC Padding Methods +* (C) 1999-2007,2013 Jack Lloyd +* (C) 2016 René Korthaus, Rohde & Schwarz Cybersecurity +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include + +namespace Botan { + +/** +* Get a block cipher padding method by name +*/ +BlockCipherModePaddingMethod* get_bc_pad(const std::string& algo_spec) + { + if(algo_spec == "NoPadding") + return new Null_Padding; + + if(algo_spec == "PKCS7") + return new PKCS7_Padding; + + if(algo_spec == "OneAndZeros") + return new OneAndZeros_Padding; + + if(algo_spec == "X9.23") + return new ANSI_X923_Padding; + + if(algo_spec == "ESP") + return new ESP_Padding; + + return nullptr; + } + +/* +* Pad with PKCS #7 Method +*/ +void PKCS7_Padding::add_padding(secure_vector& buffer, + size_t last_byte_pos, + size_t block_size) const + { + const uint8_t pad_value = static_cast(block_size - last_byte_pos); + + for(size_t i = 0; i != pad_value; ++i) + buffer.push_back(pad_value); + } + +/* +* Unpad with PKCS #7 Method +*/ +size_t PKCS7_Padding::unpad(const uint8_t block[], size_t size) const + { + CT::poison(block,size); + size_t bad_input = 0; + const uint8_t last_byte = block[size-1]; + + bad_input |= CT::expand_mask(last_byte > size); + + size_t pad_pos = size - last_byte; + size_t i = size - 2; + while(i) + { + bad_input |= (~CT::is_equal(block[i],last_byte)) & CT::expand_mask(i >= pad_pos); + --i; + } + + CT::conditional_copy_mem(bad_input,&pad_pos,&size,&pad_pos,1); + CT::unpoison(block,size); + CT::unpoison(pad_pos); + return pad_pos; + } + +/* +* Pad with ANSI X9.23 Method +*/ +void ANSI_X923_Padding::add_padding(secure_vector& buffer, + size_t last_byte_pos, + size_t block_size) const + { + const uint8_t pad_value = static_cast(block_size - last_byte_pos); + + for(size_t i = last_byte_pos; i < block_size-1; ++i) + { + buffer.push_back(0); + } + buffer.push_back(pad_value); + } + +/* +* Unpad with ANSI X9.23 Method +*/ +size_t ANSI_X923_Padding::unpad(const uint8_t block[], size_t size) const + { + CT::poison(block,size); + size_t bad_input = 0; + const size_t last_byte = block[size-1]; + + bad_input |= CT::expand_mask(last_byte > size); + + size_t pad_pos = size - last_byte; + size_t i = size - 2; + while(i) + { + bad_input |= (~CT::is_zero(block[i])) & CT::expand_mask(i >= pad_pos); + --i; + } + CT::conditional_copy_mem(bad_input,&pad_pos,&size,&pad_pos,1); + CT::unpoison(block,size); + CT::unpoison(pad_pos); + return pad_pos; + } + +/* +* Pad with One and Zeros Method +*/ +void OneAndZeros_Padding::add_padding(secure_vector& buffer, + size_t last_byte_pos, + size_t block_size) const + { + buffer.push_back(0x80); + + for(size_t i = last_byte_pos + 1; i % block_size; ++i) + buffer.push_back(0x00); + } + +/* +* Unpad with One and Zeros Method +*/ +size_t OneAndZeros_Padding::unpad(const uint8_t block[], size_t size) const + { + CT::poison(block, size); + uint8_t bad_input = 0; + uint8_t seen_one = 0; + size_t pad_pos = size - 1; + size_t i = size; + + while(i) + { + seen_one |= CT::is_equal(block[i-1],0x80); + pad_pos -= CT::select(~seen_one, 1, 0); + bad_input |= ~CT::is_zero(block[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; + } + +/* +* Pad with ESP Padding Method +*/ +void ESP_Padding::add_padding(secure_vector& buffer, + size_t last_byte_pos, + size_t block_size) const + { + uint8_t pad_value = 0x01; + + for(size_t i = last_byte_pos; i < block_size; ++i) + { + buffer.push_back(pad_value++); + } + } + +/* +* Unpad with ESP Padding Method +*/ +size_t ESP_Padding::unpad(const uint8_t block[], size_t size) const + { + CT::poison(block,size); + + const size_t last_byte = block[size-1]; + size_t bad_input = 0; + bad_input |= CT::expand_mask(last_byte > size); + + size_t pad_pos = size - last_byte; + size_t i = size - 1; + while(i) + { + bad_input |= ~CT::is_equal(size_t(block[i-1]),size_t(block[i])-1) & CT::expand_mask(i > pad_pos); + --i; + } + CT::conditional_copy_mem(bad_input,&pad_pos,&size,&pad_pos,1); + CT::unpoison(block, size); + CT::unpoison(pad_pos); + return 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 new file mode 100644 index 0000000000..cc196d251b --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/modes/mode_pad/mode_pad.h @@ -0,0 +1,159 @@ +/* +* CBC Padding Methods +* (C) 1999-2008,2013 Jack Lloyd +* (C) 2016 René Korthaus, Rohde & Schwarz Cybersecurity +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_MODE_PADDING_H_ +#define BOTAN_MODE_PADDING_H_ + +#include +#include + +namespace Botan { + +/** +* Block Cipher Mode Padding Method +* This class is pretty limited, it cannot deal well with +* randomized padding methods, or any padding method that +* wants to add more than one block. For instance, it should +* be possible to define cipher text stealing mode as simply +* a padding mode for CBC, which happens to consume the last +* two block (and requires use of the block cipher). +*/ +class BOTAN_PUBLIC_API(2,0) BlockCipherModePaddingMethod + { + public: + /** + * Add padding bytes to buffer. + * @param buffer data to pad + * @param final_block_bytes size of the final block in bytes + * @param block_size size of each block in bytes + */ + virtual void add_padding(secure_vector& buffer, + size_t final_block_bytes, + size_t block_size) const = 0; + + /** + * Remove padding bytes from block + * @param block the last block + * @param size the size of the block in bytes + * @return number of padding bytes + */ + virtual size_t unpad(const uint8_t block[], + size_t size) const = 0; + + /** + * @param block_size of the cipher + * @return valid block size for this padding mode + */ + virtual bool valid_blocksize(size_t block_size) const = 0; + + /** + * @return name of the mode + */ + virtual std::string name() const = 0; + + /** + * virtual destructor + */ + virtual ~BlockCipherModePaddingMethod() = default; + }; + +/** +* PKCS#7 Padding +*/ +class BOTAN_PUBLIC_API(2,0) PKCS7_Padding final : public BlockCipherModePaddingMethod + { + public: + void add_padding(secure_vector& buffer, + size_t final_block_bytes, + size_t block_size) const override; + + size_t unpad(const uint8_t[], size_t) const override; + + bool valid_blocksize(size_t bs) const override { return (bs > 0 && bs < 256); } + + std::string name() const override { return "PKCS7"; } + }; + +/** +* ANSI X9.23 Padding +*/ +class BOTAN_PUBLIC_API(2,0) ANSI_X923_Padding final : public BlockCipherModePaddingMethod + { + public: + void add_padding(secure_vector& buffer, + size_t final_block_bytes, + size_t block_size) const override; + + size_t unpad(const uint8_t[], size_t) const override; + + bool valid_blocksize(size_t bs) const override { return (bs > 0 && bs < 256); } + + std::string name() const override { return "X9.23"; } + }; + +/** +* One And Zeros Padding (ISO/IEC 9797-1, padding method 2) +*/ +class BOTAN_PUBLIC_API(2,0) OneAndZeros_Padding final : public BlockCipherModePaddingMethod + { + public: + void add_padding(secure_vector& buffer, + size_t final_block_bytes, + size_t block_size) const override; + + size_t unpad(const uint8_t[], size_t) const override; + + bool valid_blocksize(size_t bs) const override { return (bs > 0); } + + std::string name() const override { return "OneAndZeros"; } + }; + +/** +* ESP Padding (RFC 4304) +*/ +class BOTAN_PUBLIC_API(2,0) ESP_Padding final : public BlockCipherModePaddingMethod + { + public: + void add_padding(secure_vector& buffer, + size_t final_block_bytes, + size_t block_size) const override; + + size_t unpad(const uint8_t[], size_t) const override; + + bool valid_blocksize(size_t bs) const override { return (bs > 0); } + + std::string name() const override { return "ESP"; } + }; + +/** +* Null Padding +*/ +class BOTAN_PUBLIC_API(2,0) Null_Padding final : public BlockCipherModePaddingMethod + { + public: + void add_padding(secure_vector&, size_t, size_t) const override + { + /* no padding */ + } + + size_t unpad(const uint8_t[], size_t size) const override { return size; } + + bool valid_blocksize(size_t) const override { return true; } + + std::string name() const override { return "NoPadding"; } + }; + +/** +* Get a block cipher padding mode by name (eg "NoPadding" or "PKCS7") +* @param algo_spec block cipher padding mode name +*/ +BOTAN_PUBLIC_API(2,0) BlockCipherModePaddingMethod* get_bc_pad(const std::string& algo_spec); + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/modes/stream_mode.h b/src/libs/3rdparty/botan/src/lib/modes/stream_mode.h new file mode 100644 index 0000000000..3bce01731a --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/modes/stream_mode.h @@ -0,0 +1,82 @@ +/* +* (C) 2015 Jack Lloyd +* (C) 2016 Daniel Neus, Rohde & Schwarz Cybersecurity +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_STREAM_MODE_H_ +#define BOTAN_STREAM_MODE_H_ + +#include + +#if defined(BOTAN_HAS_STREAM_CIPHER) + #include +#endif + +namespace Botan { + +#if defined(BOTAN_HAS_STREAM_CIPHER) + +class BOTAN_PUBLIC_API(2,0) Stream_Cipher_Mode final : public Cipher_Mode + { + public: + /** + * @param cipher underyling stream cipher + */ + explicit Stream_Cipher_Mode(StreamCipher* cipher) : m_cipher(cipher) {} + + size_t process(uint8_t buf[], size_t sz) override + { + m_cipher->cipher1(buf, sz); + return sz; + } + + void finish(secure_vector& buf, size_t offset) override + { return update(buf, offset); } + + size_t output_length(size_t input_length) const override { return input_length; } + + size_t update_granularity() const override { return 1; } + + size_t minimum_final_size() const override { return 0; } + + size_t default_nonce_length() const override { return 0; } + + bool valid_nonce_length(size_t nonce_len) const override + { return m_cipher->valid_iv_length(nonce_len); } + + Key_Length_Specification key_spec() const override { return m_cipher->key_spec(); } + + std::string name() const override { return m_cipher->name(); } + + void clear() override + { + m_cipher->clear(); + reset(); + } + + void reset() override { /* no msg state */ } + + private: + void start_msg(const uint8_t nonce[], size_t nonce_len) override + { + if(nonce_len > 0) + { + m_cipher->set_iv(nonce, nonce_len); + } + } + + void key_schedule(const uint8_t key[], size_t length) override + { + m_cipher->set_key(key, length); + } + + std::unique_ptr m_cipher; + }; + +#endif + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/pbkdf/info.txt b/src/libs/3rdparty/botan/src/lib/pbkdf/info.txt new file mode 100644 index 0000000000..48c6b56e66 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pbkdf/info.txt @@ -0,0 +1,12 @@ + +PBKDF -> 20150626 + + + +mac +hash + + + +pbkdf.h + diff --git a/src/libs/3rdparty/botan/src/lib/pbkdf/pbkdf.cpp b/src/libs/3rdparty/botan/src/lib/pbkdf/pbkdf.cpp new file mode 100644 index 0000000000..73b482725c --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pbkdf/pbkdf.cpp @@ -0,0 +1,133 @@ +/* +* PBKDF +* (C) 2012 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include + +#if defined(BOTAN_HAS_PBKDF1) +#include +#endif + +#if defined(BOTAN_HAS_PBKDF2) +#include +#endif + +#if defined(BOTAN_HAS_PGP_S2K) +#include +#endif + +namespace Botan { + +std::unique_ptr PBKDF::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(new PKCS5_PBKDF2(mac.release())); + + if(auto mac = MessageAuthenticationCode::create("HMAC(" + req.arg(0) + ")")) + return std::unique_ptr(new PKCS5_PBKDF2(mac.release())); + } + + return nullptr; + } +#endif + +#if defined(BOTAN_HAS_PBKDF1) + if(req.algo_name() == "PBKDF1" && req.arg_count() == 1) + { + if(auto hash = HashFunction::create(req.arg(0))) + return std::unique_ptr(new PKCS5_PBKDF1(hash.release())); + + } +#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(new OpenPGP_S2K(hash.release())); + } +#endif + + BOTAN_UNUSED(req); + BOTAN_UNUSED(provider); + + return nullptr; + } + +//static +std::unique_ptr +PBKDF::create_or_throw(const std::string& algo, + const std::string& provider) + { + if(auto pbkdf = PBKDF::create(algo, provider)) + { + return pbkdf; + } + throw Lookup_Error("PBKDF", algo, provider); + } + +std::vector PBKDF::providers(const std::string& algo_spec) + { + return probe_providers_of(algo_spec, { "base", "openssl" }); + } + +void PBKDF::pbkdf_timed(uint8_t out[], size_t out_len, + const std::string& passphrase, + const uint8_t salt[], size_t salt_len, + std::chrono::milliseconds msec, + size_t& iterations) const + { + iterations = pbkdf(out, out_len, passphrase, salt, salt_len, 0, msec); + } + +void PBKDF::pbkdf_iterations(uint8_t out[], size_t out_len, + const std::string& passphrase, + const uint8_t salt[], size_t salt_len, + size_t iterations) const + { + if(iterations == 0) + throw Invalid_Argument(name() + ": Invalid iteration count"); + + const size_t iterations_run = pbkdf(out, out_len, passphrase, + salt, salt_len, iterations, + std::chrono::milliseconds(0)); + BOTAN_ASSERT_EQUAL(iterations, iterations_run, "Expected PBKDF iterations"); + } + +secure_vector PBKDF::pbkdf_iterations(size_t out_len, + const std::string& passphrase, + const uint8_t salt[], size_t salt_len, + size_t iterations) const + { + secure_vector out(out_len); + pbkdf_iterations(out.data(), out_len, passphrase, salt, salt_len, iterations); + return out; + } + +secure_vector PBKDF::pbkdf_timed(size_t out_len, + const std::string& passphrase, + const uint8_t salt[], size_t salt_len, + std::chrono::milliseconds msec, + size_t& iterations) const + { + secure_vector out(out_len); + pbkdf_timed(out.data(), out_len, passphrase, salt, salt_len, msec, iterations); + return out; + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/pbkdf/pbkdf.h b/src/libs/3rdparty/botan/src/lib/pbkdf/pbkdf.h new file mode 100644 index 0000000000..7d3bceffcf --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pbkdf/pbkdf.h @@ -0,0 +1,243 @@ +/* +* PBKDF +* (C) 1999-2007,2012,2015 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_PBKDF_H_ +#define BOTAN_PBKDF_H_ + +#include +#include + +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. +*/ +class BOTAN_PUBLIC_API(2,0) PBKDF + { + 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 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 + 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 providers(const std::string& algo_spec); + + /** + * @return new instance of this same algorithm + */ + virtual PBKDF* clone() const = 0; + + /** + * @return name of this PBKDF + */ + virtual std::string name() const = 0; + + virtual ~PBKDF() = default; + + /** + * Derive a key from a passphrase for a number of iterations + * specified by either iterations or if iterations == 0 then + * running until msec time has elapsed. + * + * @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 passphrase the password to derive the key from + * @param salt a randomly chosen salt + * @param salt_len length of salt in bytes + * @param iterations the number of iterations to use (use 10K or more) + * @param msec if iterations is zero, then instead the PBKDF is + * run until msec milliseconds has passed. + * @return the number of iterations performed + */ + virtual size_t pbkdf(uint8_t out[], size_t out_len, + const std::string& passphrase, + const uint8_t salt[], size_t salt_len, + size_t iterations, + std::chrono::milliseconds msec) const = 0; + + /** + * Derive a key from a passphrase for a number of iterations. + * + * @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 passphrase the password to derive the key from + * @param salt a randomly chosen salt + * @param salt_len length of salt in bytes + * @param iterations the number of iterations to use (use 10K or more) + */ + void pbkdf_iterations(uint8_t out[], size_t out_len, + const std::string& passphrase, + const uint8_t salt[], size_t salt_len, + size_t iterations) const; + + /** + * Derive a key from a passphrase, running until msec time has elapsed. + * + * @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 passphrase the password to derive the key from + * @param salt a randomly chosen salt + * @param salt_len length of salt in bytes + * @param msec if iterations is zero, then instead the PBKDF is + * run until msec milliseconds has passed. + * @param iterations set to the number iterations executed + */ + void pbkdf_timed(uint8_t out[], size_t out_len, + const std::string& passphrase, + const uint8_t salt[], size_t salt_len, + std::chrono::milliseconds msec, + size_t& iterations) const; + + /** + * Derive a key from a passphrase for a number of iterations. + * + * @param out_len the desired length of the key to produce + * @param passphrase the password to derive the key from + * @param salt a randomly chosen salt + * @param salt_len length of salt in bytes + * @param iterations the number of iterations to use (use 10K or more) + * @return the derived key + */ + secure_vector pbkdf_iterations(size_t out_len, + const std::string& passphrase, + const uint8_t salt[], size_t salt_len, + size_t iterations) const; + + /** + * Derive a key from a passphrase, running until msec time has elapsed. + * + * @param out_len the desired length of the key to produce + * @param passphrase the password to derive the key from + * @param salt a randomly chosen salt + * @param salt_len length of salt in bytes + * @param msec if iterations is zero, then instead the PBKDF is + * run until msec milliseconds has passed. + * @param iterations set to the number iterations executed + * @return the derived key + */ + secure_vector pbkdf_timed(size_t out_len, + const std::string& passphrase, + const uint8_t salt[], size_t salt_len, + std::chrono::milliseconds msec, + size_t& iterations) const; + + // Following kept for compat with 1.10: + + /** + * Derive a key from a passphrase + * @param out_len the desired length of the key to produce + * @param passphrase the password to derive the key from + * @param salt a randomly chosen salt + * @param salt_len length of salt in bytes + * @param iterations the number of iterations to use (use 10K or more) + */ + OctetString derive_key(size_t out_len, + const std::string& passphrase, + const uint8_t salt[], size_t salt_len, + size_t iterations) const + { + return pbkdf_iterations(out_len, passphrase, salt, salt_len, iterations); + } + + /** + * Derive a key from a passphrase + * @param out_len the desired length of the key to produce + * @param passphrase the password to derive the key from + * @param salt a randomly chosen salt + * @param iterations the number of iterations to use (use 10K or more) + */ + template + OctetString derive_key(size_t out_len, + const std::string& passphrase, + const std::vector& salt, + size_t iterations) const + { + return pbkdf_iterations(out_len, passphrase, salt.data(), salt.size(), iterations); + } + + /** + * Derive a key from a passphrase + * @param out_len the desired length of the key to produce + * @param passphrase the password to derive the key from + * @param salt a randomly chosen salt + * @param salt_len length of salt in bytes + * @param msec is how long to run the PBKDF + * @param iterations is set to the number of iterations used + */ + OctetString derive_key(size_t out_len, + const std::string& passphrase, + const uint8_t salt[], size_t salt_len, + std::chrono::milliseconds msec, + size_t& iterations) const + { + return pbkdf_timed(out_len, passphrase, salt, salt_len, msec, iterations); + } + + /** + * Derive a key from a passphrase using a certain amount of time + * @param out_len the desired length of the key to produce + * @param passphrase the password to derive the key from + * @param salt a randomly chosen salt + * @param msec is how long to run the PBKDF + * @param iterations is set to the number of iterations used + */ + template + OctetString derive_key(size_t out_len, + const std::string& passphrase, + const std::vector& salt, + std::chrono::milliseconds msec, + size_t& iterations) const + { + return pbkdf_timed(out_len, passphrase, salt.data(), salt.size(), msec, iterations); + } + }; + +/* +* Compatability typedef +*/ +typedef PBKDF S2K; + +/** +* Password based key derivation function factory method +* @param algo_spec the name of the desired PBKDF algorithm +* @param provider the provider to use +* @return pointer to newly allocated object of that type +*/ +inline PBKDF* get_pbkdf(const std::string& algo_spec, + const std::string& provider = "") + { + return PBKDF::create_or_throw(algo_spec, provider).release(); + } + +inline PBKDF* get_s2k(const std::string& algo_spec) + { + return get_pbkdf(algo_spec); + } + + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/pbkdf/pbkdf2/info.txt b/src/libs/3rdparty/botan/src/lib/pbkdf/pbkdf2/info.txt new file mode 100644 index 0000000000..bc5c2e4916 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pbkdf/pbkdf2/info.txt @@ -0,0 +1,7 @@ + +PBKDF2 -> 20131128 + + + +hmac + diff --git a/src/libs/3rdparty/botan/src/lib/pbkdf/pbkdf2/pbkdf2.cpp b/src/libs/3rdparty/botan/src/lib/pbkdf/pbkdf2/pbkdf2.cpp new file mode 100644 index 0000000000..cc2982f6e9 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pbkdf/pbkdf2/pbkdf2.cpp @@ -0,0 +1,118 @@ +/* +* PBKDF2 +* (C) 1999-2007 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include + +namespace Botan { + +size_t +pbkdf2(MessageAuthenticationCode& prf, + uint8_t out[], + size_t out_len, + const std::string& passphrase, + 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 + { + 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())); + } + + const size_t prf_sz = prf.output_length(); + secure_vector U(prf_sz); + + const size_t blocks_needed = round_up(out_len, prf_sz) / prf_sz; + + std::chrono::microseconds usec_per_block = + std::chrono::duration_cast(msec) / blocks_needed; + + uint32_t counter = 1; + while(out_len) + { + const size_t prf_output = std::min(prf_sz, out_len); + + prf.update(salt, salt_len); + prf.update_be(counter++); + prf.final(U.data()); + + xor_buf(out, U.data(), prf_output); + + if(iterations == 0) + { + /* + 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(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); + } + } + + out_len -= prf_output; + out += prf_output; + } + + return iterations; + } + +size_t +PKCS5_PBKDF2::pbkdf(uint8_t key[], size_t key_len, + const std::string& passphrase, + 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); + } + + +} diff --git a/src/libs/3rdparty/botan/src/lib/pbkdf/pbkdf2/pbkdf2.h b/src/libs/3rdparty/botan/src/lib/pbkdf/pbkdf2/pbkdf2.h new file mode 100644 index 0000000000..ea357cac0b --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pbkdf/pbkdf2/pbkdf2.h @@ -0,0 +1,57 @@ +/* +* PBKDF2 +* (C) 1999-2007,2012 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_PBKDF2_H_ +#define BOTAN_PBKDF2_H_ + +#include +#include + +namespace Botan { + +BOTAN_PUBLIC_API(2,0) size_t pbkdf2(MessageAuthenticationCode& prf, + uint8_t out[], + size_t out_len, + const std::string& passphrase, + const uint8_t salt[], size_t salt_len, + size_t iterations, + std::chrono::milliseconds msec); + +/** +* PKCS #5 PBKDF2 +*/ +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()); + } + + size_t pbkdf(uint8_t output_buf[], size_t output_len, + const std::string& passphrase, + const uint8_t salt[], size_t salt_len, + size_t iterations, + std::chrono::milliseconds msec) const override; + + /** + * Create a PKCS #5 instance using the specified message auth code + * @param mac_fn the MAC object to use as PRF + */ + explicit PKCS5_PBKDF2(MessageAuthenticationCode* mac_fn) : m_mac(mac_fn) {} + private: + std::unique_ptr m_mac; + }; + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/pk_pad/eme.cpp b/src/libs/3rdparty/botan/src/lib/pk_pad/eme.cpp new file mode 100644 index 0000000000..5164157f76 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pk_pad/eme.cpp @@ -0,0 +1,94 @@ +/* +* EME Base Class +* (C) 1999-2008 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include + +#if defined(BOTAN_HAS_EME_OAEP) +#include +#endif + +#if defined(BOTAN_HAS_EME_PKCS1v15) +#include +#endif + +#if defined(BOTAN_HAS_EME_RAW) +#include +#endif + +namespace Botan { + +EME* get_eme(const std::string& algo_spec) + { +#if defined(BOTAN_HAS_EME_RAW) + if(algo_spec == "Raw") + return new EME_Raw; +#endif + +#if defined(BOTAN_HAS_EME_PKCS1v15) + if(algo_spec == "PKCS1v15" || algo_spec == "EME-PKCS1-v1_5") + return new EME_PKCS1v15; +#endif + +#if defined(BOTAN_HAS_EME_OAEP) + SCAN_Name req(algo_spec); + + if(req.algo_name() == "OAEP" || + req.algo_name() == "EME-OAEP" || + req.algo_name() == "EME1") + { + if(req.arg_count() == 1 || + ((req.arg_count() == 2 || req.arg_count() == 3) && req.arg(1) == "MGF1")) + { + if(auto hash = HashFunction::create(req.arg(0))) + return new OAEP(hash.release(), req.arg(2, "")); + } + else if(req.arg_count() == 2 || req.arg_count() == 3) + { + auto mgf_params = parse_algorithm_name(req.arg(1)); + + if(mgf_params.size() == 2 && mgf_params[0] == "MGF1") + { + auto hash = HashFunction::create(req.arg(0)); + auto mgf1_hash = HashFunction::create(mgf_params[1]); + + if(hash && mgf1_hash) + { + return new OAEP(hash.release(), mgf1_hash.release(), req.arg(2, "")); + } + } + } + } +#endif + + throw Algorithm_Not_Found(algo_spec); + } + +/* +* Encode a message +*/ +secure_vector EME::encode(const uint8_t msg[], size_t msg_len, + size_t key_bits, + RandomNumberGenerator& rng) const + { + return pad(msg, msg_len, key_bits, rng); + } + +/* +* Encode a message +*/ +secure_vector EME::encode(const secure_vector& msg, + size_t key_bits, + RandomNumberGenerator& rng) const + { + return pad(msg.data(), msg.size(), key_bits, rng); + } + + +} diff --git a/src/libs/3rdparty/botan/src/lib/pk_pad/eme.h b/src/libs/3rdparty/botan/src/lib/pk_pad/eme.h new file mode 100644 index 0000000000..26523bc881 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pk_pad/eme.h @@ -0,0 +1,91 @@ +/* +* EME Classes +* (C) 1999-2007 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_PUBKEY_EME_ENCRYPTION_PAD_H_ +#define BOTAN_PUBKEY_EME_ENCRYPTION_PAD_H_ + +#include + +namespace Botan { + +class RandomNumberGenerator; + +/** +* Encoding Method for Encryption +*/ +class BOTAN_PUBLIC_API(2,0) EME + { + public: + virtual ~EME() = default; + + /** + * Return the maximum input size in bytes we can support + * @param keybits the size of the key in bits + * @return upper bound of input in bytes + */ + virtual size_t maximum_input_size(size_t keybits) const = 0; + + /** + * Encode an input + * @param in the plaintext + * @param in_length length of plaintext in bytes + * @param key_length length of the key in bits + * @param rng a random number generator + * @return encoded plaintext + */ + secure_vector encode(const uint8_t in[], + size_t in_length, + size_t key_length, + RandomNumberGenerator& rng) const; + + /** + * Encode an input + * @param in the plaintext + * @param key_length length of the key in bits + * @param rng a random number generator + * @return encoded plaintext + */ + secure_vector encode(const secure_vector& in, + size_t key_length, + RandomNumberGenerator& rng) const; + + /** + * Decode an input + * @param valid_mask written to specifies if output is valid + * @param in the encoded plaintext + * @param in_len length of encoded plaintext in bytes + * @return bytes of out[] written to along with + * validity mask (0xFF if valid, else 0x00) + */ + virtual secure_vector unpad(uint8_t& valid_mask, + const uint8_t in[], + size_t in_len) const = 0; + + /** + * Encode an input + * @param in the plaintext + * @param in_length length of plaintext in bytes + * @param key_length length of the key in bits + * @param rng a random number generator + * @return encoded plaintext + */ + virtual secure_vector pad(const uint8_t in[], + size_t in_length, + size_t key_length, + RandomNumberGenerator& rng) const = 0; + }; + +/** +* Factory method for EME (message-encoding methods for encryption) objects +* @param algo_spec the name of the EME to create +* @return pointer to newly allocated object of that type +*/ +BOTAN_PUBLIC_API(2,0) EME* get_eme(const std::string& algo_spec); + +} + +#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 new file mode 100644 index 0000000000..126e1421df --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pk_pad/emsa.cpp @@ -0,0 +1,183 @@ +/* +* (C) 2015 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include + +#if defined(BOTAN_HAS_EMSA1) + #include +#endif + +#if defined(BOTAN_HAS_EMSA_X931) + #include +#endif + +#if defined(BOTAN_HAS_EMSA_PKCS1) + #include +#endif + +#if defined(BOTAN_HAS_EMSA_PSSR) + #include +#endif + +#if defined(BOTAN_HAS_EMSA_RAW) + #include +#endif + +#if defined(BOTAN_HAS_ISO_9796) + #include +#endif + +namespace Botan { + +AlgorithmIdentifier EMSA::config_for_x509(const Private_Key&, + const std::string&) const + { + throw Not_Implemented("Encoding " + name() + " not supported for signing X509 objects"); + } + +EMSA* get_emsa(const std::string& algo_spec) + { + SCAN_Name req(algo_spec); + +#if defined(BOTAN_HAS_EMSA1) + if(req.algo_name() == "EMSA1" && req.arg_count() == 1) + { + if(auto hash = HashFunction::create(req.arg(0))) + return new EMSA1(hash.release()); + } +#endif + +#if defined(BOTAN_HAS_EMSA_PKCS1) + if(req.algo_name() == "EMSA_PKCS1" || + req.algo_name() == "EMSA-PKCS1-v1_5" || + req.algo_name() == "EMSA3") + { + if(req.arg_count() == 2 && req.arg(0) == "Raw") + { + return new EMSA_PKCS1v15_Raw(req.arg(1)); + } + else if(req.arg_count() == 1) + { + if(req.arg(0) == "Raw") + { + return new EMSA_PKCS1v15_Raw; + } + else + { + if(auto hash = HashFunction::create(req.arg(0))) + { + return new EMSA_PKCS1v15(hash.release()); + } + } + } + } +#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" || + req.algo_name() == "PSSR_Raw") + { + if(req.arg_count_between(1, 3)) + { + 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") + return new PSSR_Raw(h.release(), salt_size); + else + return new PSSR(h.release(), salt_size); + } + } + } +#endif + +#if defined(BOTAN_HAS_ISO_9796) + if(req.algo_name() == "ISO_9796_DS2") + { + if(req.arg_count_between(1, 3)) + { + if(auto h = HashFunction::create(req.arg(0))) + { + const size_t salt_size = req.arg_as_integer(2, h->output_length()); + const bool implicit = req.arg(1, "exp") == "imp"; + return new ISO_9796_DS2(h.release(), implicit, salt_size); + } + } + } + //ISO-9796-2 DS 3 is deterministic and DS2 without a salt + if(req.algo_name() == "ISO_9796_DS3") + { + if(req.arg_count_between(1, 2)) + { + if(auto h = HashFunction::create(req.arg(0))) + { + const bool implicit = req.arg(1, "exp") == "imp"; + return new ISO_9796_DS3(h.release(), implicit); + } + } + } +#endif + +#if defined(BOTAN_HAS_EMSA_X931) + if(req.algo_name() == "EMSA_X931" || + req.algo_name() == "EMSA2" || + req.algo_name() == "X9.31") + { + if(req.arg_count() == 1) + { + if(auto hash = HashFunction::create(req.arg(0))) + { + return new EMSA_X931(hash.release()); + } + } + } +#endif + +#if defined(BOTAN_HAS_EMSA_RAW) + if(req.algo_name() == "Raw") + { + if(req.arg_count() == 0) + { + return new EMSA_Raw; + } + else + { + auto hash = HashFunction::create(req.arg(0)); + if(hash) + return new EMSA_Raw(hash->output_length()); + } + } +#endif + + throw Algorithm_Not_Found(algo_spec); + } + +std::string hash_for_emsa(const std::string& algo_spec) + { + SCAN_Name emsa_name(algo_spec); + + if(emsa_name.arg_count() > 0) + { + const std::string pos_hash = emsa_name.arg(0); + return pos_hash; + } + + return "SHA-512"; // safe default if nothing we understand + } + +} + + diff --git a/src/libs/3rdparty/botan/src/lib/pk_pad/emsa.h b/src/libs/3rdparty/botan/src/lib/pk_pad/emsa.h new file mode 100644 index 0000000000..fe0785294f --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pk_pad/emsa.h @@ -0,0 +1,104 @@ +/* +* EMSA Classes +* (C) 1999-2007 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_PUBKEY_EMSA_H_ +#define BOTAN_PUBKEY_EMSA_H_ + +#include +#include + +namespace Botan { + +class Private_Key; +class RandomNumberGenerator; + +/** +* EMSA, from IEEE 1363s Encoding Method for Signatures, Appendix +* +* Any way of encoding/padding signatures +*/ +class BOTAN_PUBLIC_API(2,0) EMSA + { + public: + virtual ~EMSA() = default; + + /** + * Add more data to the signature computation + * @param input some data + * @param length length of input in bytes + */ + virtual void update(const uint8_t input[], size_t length) = 0; + + /** + * @return raw hash + */ + virtual secure_vector raw_data() = 0; + + /** + * Return the encoding of a message + * @param msg the result of raw_data() + * @param output_bits the desired output bit size + * @param rng a random number generator + * @return encoded signature + */ + virtual secure_vector encoding_of(const secure_vector& msg, + size_t output_bits, + RandomNumberGenerator& rng) = 0; + + /** + * Verify the encoding + * @param coded the received (coded) message representative + * @param raw the computed (local, uncoded) message representative + * @param key_bits the size of the key in bits + * @return true if coded is a valid encoding of raw, otherwise false + */ + virtual bool verify(const secure_vector& coded, + const secure_vector& raw, + size_t key_bits) = 0; + + /** + * Prepare sig_algo for use in choose_sig_format for x509 certs + * + * @param key used for checking compatibility with the encoding scheme + * @param cert_hash_name is checked to equal the hash for the encoding + * @return algorithm identifier to signatures created using this key, + * padding method and hash. + */ + virtual AlgorithmIdentifier config_for_x509(const Private_Key& key, + const std::string& cert_hash_name) const; + + /** + * @return a new object representing the same encoding method as *this + */ + virtual EMSA* clone() = 0; + + /** + * @return the SCAN name of the encoding/padding scheme + */ + virtual std::string name() const = 0; + }; + +/** +* Factory method for EMSA (message-encoding methods for signatures +* with appendix) objects +* @param algo_spec the name of the EMSA to create +* @return pointer to newly allocated object of that type +*/ +BOTAN_PUBLIC_API(2,0) EMSA* get_emsa(const std::string& algo_spec); + +/** +* Returns the hash function used in the given EMSA scheme +* If the hash function is not specified or not understood, +* returns "SHA-512" +* @param algo_spec the name of the EMSA +* @return hash function used in the given EMSA scheme +*/ +BOTAN_PUBLIC_API(2,0) std::string hash_for_emsa(const std::string& algo_spec); + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/pk_pad/emsa1/emsa1.cpp b/src/libs/3rdparty/botan/src/lib/pk_pad/emsa1/emsa1.cpp new file mode 100644 index 0000000000..66d8ec8520 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pk_pad/emsa1/emsa1.cpp @@ -0,0 +1,133 @@ +/* +* EMSA1 +* (C) 1999-2007 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include +#include + +namespace Botan { + +namespace { + +secure_vector emsa1_encoding(const secure_vector& msg, + size_t output_bits) + { + if(8*msg.size() <= output_bits) + return msg; + + size_t shift = 8*msg.size() - output_bits; + + size_t byte_shift = shift / 8, bit_shift = shift % 8; + secure_vector digest(msg.size() - byte_shift); + + for(size_t j = 0; j != msg.size() - byte_shift; ++j) + digest[j] = msg[j]; + + if(bit_shift) + { + uint8_t carry = 0; + for(size_t j = 0; j != digest.size(); ++j) + { + uint8_t temp = digest[j]; + digest[j] = (temp >> bit_shift) | carry; + carry = (temp << (8 - bit_shift)); + } + } + return digest; + } + +} + +std::string EMSA1::name() const + { + return "EMSA1(" + m_hash->name() + ")"; + } + +EMSA* EMSA1::clone() + { + return new EMSA1(m_hash->clone()); + } + +void EMSA1::update(const uint8_t input[], size_t length) + { + m_hash->update(input, length); + } + +secure_vector EMSA1::raw_data() + { + return m_hash->final(); + } + +secure_vector EMSA1::encoding_of(const secure_vector& msg, + size_t output_bits, + RandomNumberGenerator&) + { + if(msg.size() != hash_output_length()) + throw Encoding_Error("EMSA1::encoding_of: Invalid size for input"); + return emsa1_encoding(msg, output_bits); + } + +bool EMSA1::verify(const secure_vector& input, + const secure_vector& raw, + size_t key_bits) + { + if(raw.size() != m_hash->output_length()) + return false; + + // Call emsa1_encoding to handle any required bit shifting + const secure_vector our_coding = emsa1_encoding(raw, key_bits); + + if(our_coding.size() < input.size()) + return false; + + const size_t offset = our_coding.size() - input.size(); // must be >= 0 per check above + + // If our encoding is longer, all the bytes in it must be zero + for(size_t i = 0; i != offset; ++i) + if(our_coding[i] != 0) + return false; + + return constant_time_compare(input.data(), &our_coding[offset], input.size()); + } + +AlgorithmIdentifier EMSA1::config_for_x509(const Private_Key& key, + const std::string& cert_hash_name) const + { + if(cert_hash_name != m_hash->name()) + throw Invalid_Argument("Hash function from opts and hash_fn argument" + " need to be identical"); + // check that the signature algorithm and the padding scheme fit + if(!sig_algo_and_pad_ok(key.algo_name(), "EMSA1")) + { + throw Invalid_Argument("Encoding scheme with canonical name EMSA1" + " not supported for signature algorithm " + key.algo_name()); + } + + AlgorithmIdentifier sig_algo; + sig_algo.oid = OIDS::lookup( key.algo_name() + "/" + name() ); + + std::string algo_name = key.algo_name(); + if(algo_name == "DSA" || + algo_name == "ECDSA" || + algo_name == "ECGDSA" || + algo_name == "ECKCDSA" || + algo_name == "GOST-34.10") + { + // for DSA, ECDSA, GOST parameters "SHALL" be empty + sig_algo.parameters = {}; + } + else + { + sig_algo.parameters = key.algorithm_identifier().parameters; + } + + return sig_algo; + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/pk_pad/emsa1/emsa1.h b/src/libs/3rdparty/botan/src/lib/pk_pad/emsa1/emsa1.h new file mode 100644 index 0000000000..7b4d027da5 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pk_pad/emsa1/emsa1.h @@ -0,0 +1,53 @@ +/* +* EMSA1 +* (C) 1999-2007 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_EMSA1_H_ +#define BOTAN_EMSA1_H_ + +#include +#include + +namespace Botan { + +/** +* EMSA1 from IEEE 1363 +* Essentially, sign the hash directly +*/ +class BOTAN_PUBLIC_API(2,0) EMSA1 final : public EMSA + { + public: + /** + * @param hash the hash function to use + */ + explicit EMSA1(HashFunction* hash) : m_hash(hash) {} + + EMSA* clone() override; + + std::string name() const override; + + AlgorithmIdentifier config_for_x509(const Private_Key& key, + const std::string& cert_hash_name) const override; + private: + size_t hash_output_length() const { return m_hash->output_length(); } + + void update(const uint8_t[], size_t) override; + secure_vector raw_data() override; + + secure_vector encoding_of(const secure_vector& msg, + size_t output_bits, + RandomNumberGenerator& rng) override; + + bool verify(const secure_vector& coded, + const secure_vector& raw, + size_t key_bits) override; + + std::unique_ptr m_hash; + }; + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/pk_pad/emsa1/info.txt b/src/libs/3rdparty/botan/src/lib/pk_pad/emsa1/info.txt new file mode 100644 index 0000000000..5b5bf1f6b0 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pk_pad/emsa1/info.txt @@ -0,0 +1,3 @@ + +EMSA1 -> 20131128 + diff --git a/src/libs/3rdparty/botan/src/lib/pk_pad/emsa_pkcs1/emsa_pkcs1.cpp b/src/libs/3rdparty/botan/src/lib/pk_pad/emsa_pkcs1/emsa_pkcs1.cpp new file mode 100644 index 0000000000..ddc1e6b279 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pk_pad/emsa_pkcs1/emsa_pkcs1.cpp @@ -0,0 +1,170 @@ +/* +* PKCS #1 v1.5 signature padding +* (C) 1999-2008 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include +#include +#include + +namespace Botan { + +namespace { + +secure_vector emsa3_encoding(const secure_vector& msg, + size_t output_bits, + const uint8_t hash_id[], + size_t hash_id_length) + { + size_t output_length = output_bits / 8; + if(output_length < hash_id_length + msg.size() + 10) + throw Encoding_Error("emsa3_encoding: Output length is too small"); + + secure_vector T(output_length); + const size_t P_LENGTH = output_length - msg.size() - hash_id_length - 2; + + T[0] = 0x01; + set_mem(&T[1], P_LENGTH, 0xFF); + T[P_LENGTH+1] = 0x00; + + if(hash_id_length > 0) + { + BOTAN_ASSERT_NONNULL(hash_id); + buffer_insert(T, P_LENGTH+2, hash_id, hash_id_length); + } + + buffer_insert(T, output_length-msg.size(), msg.data(), msg.size()); + return T; + } + +} + +void EMSA_PKCS1v15::update(const uint8_t input[], size_t length) + { + m_hash->update(input, length); + } + +secure_vector EMSA_PKCS1v15::raw_data() + { + return m_hash->final(); + } + +secure_vector +EMSA_PKCS1v15::encoding_of(const secure_vector& msg, + size_t output_bits, + RandomNumberGenerator&) + { + if(msg.size() != m_hash->output_length()) + throw Encoding_Error("EMSA_PKCS1v15::encoding_of: Bad input length"); + + return emsa3_encoding(msg, output_bits, + m_hash_id.data(), m_hash_id.size()); + } + +bool EMSA_PKCS1v15::verify(const secure_vector& coded, + const secure_vector& raw, + size_t key_bits) + { + if(raw.size() != m_hash->output_length()) + return false; + + try + { + return (coded == emsa3_encoding(raw, key_bits, + m_hash_id.data(), m_hash_id.size())); + } + catch(...) + { + return false; + } + } + +AlgorithmIdentifier EMSA_PKCS1v15::config_for_x509(const Private_Key& key, + const std::string& cert_hash_name) const + { + if(cert_hash_name != m_hash->name()) + throw Invalid_Argument("Hash function from opts and hash_fn argument" + " need to be identical"); + // check that the signature algorithm and the padding scheme fit + if(!sig_algo_and_pad_ok(key.algo_name(), "EMSA3")) + { + throw Invalid_Argument("Encoding scheme with canonical name EMSA3" + " not supported for signature algorithm " + key.algo_name()); + } + + + AlgorithmIdentifier sig_algo; + sig_algo.oid = OIDS::lookup( key.algo_name() + "/" + name() ); + // for RSA PKCSv1.5 parameters "SHALL" be NULL as configured by + // RSA_PublicKey::algorithm_identifier() + sig_algo.parameters = key.algorithm_identifier().parameters; + return sig_algo; + } + +EMSA_PKCS1v15::EMSA_PKCS1v15(HashFunction* hash) : m_hash(hash) + { + m_hash_id = pkcs_hash_id(m_hash->name()); + } + +EMSA_PKCS1v15_Raw::EMSA_PKCS1v15_Raw(const std::string& hash_algo) + { + if(!hash_algo.empty()) + { + m_hash_id = pkcs_hash_id(hash_algo); + std::unique_ptr hash(HashFunction::create_or_throw(hash_algo)); + m_hash_name = hash->name(); + m_hash_output_len = hash->output_length(); + } + else + { + m_hash_output_len = 0; + } + } + +void EMSA_PKCS1v15_Raw::update(const uint8_t input[], size_t length) + { + m_message += std::make_pair(input, length); + } + +secure_vector EMSA_PKCS1v15_Raw::raw_data() + { + secure_vector ret; + std::swap(ret, m_message); + + if(m_hash_output_len > 0 && ret.size() != m_hash_output_len) + throw Encoding_Error("EMSA_PKCS1v15_Raw::encoding_of: Bad input length"); + + return ret; + } + +secure_vector +EMSA_PKCS1v15_Raw::encoding_of(const secure_vector& msg, + size_t output_bits, + RandomNumberGenerator&) + { + return emsa3_encoding(msg, output_bits, m_hash_id.data(), m_hash_id.size()); + } + +bool EMSA_PKCS1v15_Raw::verify(const secure_vector& coded, + const secure_vector& raw, + size_t key_bits) + { + if(m_hash_output_len > 0 && raw.size() != m_hash_output_len) + return false; + + try + { + return (coded == emsa3_encoding(raw, key_bits, m_hash_id.data(), m_hash_id.size())); + } + catch(...) + { + return false; + } + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/pk_pad/emsa_pkcs1/emsa_pkcs1.h b/src/libs/3rdparty/botan/src/lib/pk_pad/emsa_pkcs1/emsa_pkcs1.h new file mode 100644 index 0000000000..31032320e6 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pk_pad/emsa_pkcs1/emsa_pkcs1.h @@ -0,0 +1,92 @@ +/* +* PKCS #1 v1.5 signature padding +* (C) 1999-2008 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_EMSA_PKCS1_H_ +#define BOTAN_EMSA_PKCS1_H_ + +#include +#include + +namespace Botan { + +/** +* PKCS #1 v1.5 signature padding +* aka PKCS #1 block type 1 +* aka EMSA3 from IEEE 1363 +*/ +class BOTAN_PUBLIC_API(2,0) EMSA_PKCS1v15 final : public EMSA + { + public: + /** + * @param hash the hash function to use + */ + explicit EMSA_PKCS1v15(HashFunction* hash); + + EMSA* clone() override { return new EMSA_PKCS1v15(m_hash->clone()); } + + void update(const uint8_t[], size_t) override; + + secure_vector raw_data() override; + + secure_vector encoding_of(const secure_vector&, size_t, + RandomNumberGenerator& rng) override; + + bool verify(const secure_vector&, const secure_vector&, + size_t) override; + + std::string name() const override + { return "EMSA3(" + m_hash->name() + ")"; } + + AlgorithmIdentifier config_for_x509(const Private_Key& key, + const std::string& cert_hash_name) const override; + private: + std::unique_ptr m_hash; + std::vector m_hash_id; + }; + +/** +* EMSA_PKCS1v15_Raw which is EMSA_PKCS1v15 without a hash or digest id +* (which according to QCA docs is "identical to PKCS#11's CKM_RSA_PKCS +* mechanism", something I have not confirmed) +*/ +class BOTAN_PUBLIC_API(2,0) EMSA_PKCS1v15_Raw final : public EMSA + { + public: + EMSA* clone() override { return new EMSA_PKCS1v15_Raw(); } + + void update(const uint8_t[], size_t) override; + + secure_vector raw_data() override; + + secure_vector encoding_of(const secure_vector&, size_t, + RandomNumberGenerator& rng) override; + + bool verify(const secure_vector&, const secure_vector&, + size_t) override; + + /** + * @param hash_algo if non-empty, the digest id for that hash is + * included in the signature. + */ + EMSA_PKCS1v15_Raw(const std::string& hash_algo = ""); + + std::string name() const override + { + if(m_hash_name.empty()) return "EMSA3(Raw)"; + else return "EMSA3(Raw," + m_hash_name + ")"; + } + + private: + size_t m_hash_output_len = 0; + std::string m_hash_name; + std::vector m_hash_id; + secure_vector m_message; + }; + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/pk_pad/emsa_pkcs1/info.txt b/src/libs/3rdparty/botan/src/lib/pk_pad/emsa_pkcs1/info.txt new file mode 100644 index 0000000000..b70f4e2445 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pk_pad/emsa_pkcs1/info.txt @@ -0,0 +1,7 @@ + +EMSA_PKCS1 -> 20140118 + + + +hash_id + diff --git a/src/libs/3rdparty/botan/src/lib/pk_pad/emsa_pssr/info.txt b/src/libs/3rdparty/botan/src/lib/pk_pad/emsa_pssr/info.txt new file mode 100644 index 0000000000..f514936c37 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pk_pad/emsa_pssr/info.txt @@ -0,0 +1,7 @@ + +EMSA_PSSR -> 20131128 + + + +mgf1 + 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 new file mode 100644 index 0000000000..97b229be35 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pk_pad/emsa_pssr/pssr.cpp @@ -0,0 +1,258 @@ +/* +* PSSR +* (C) 1999-2007,2017 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Botan { + +namespace { + +/* +* PSSR Encode Operation +*/ +secure_vector pss_encode(HashFunction& hash, + const secure_vector& msg, + const secure_vector& salt, + size_t output_bits) + { + const size_t HASH_SIZE = hash.output_length(); + const size_t SALT_SIZE = salt.size(); + + if(msg.size() != HASH_SIZE) + throw Encoding_Error("Cannot encode PSS string, input length invalid for hash"); + if(output_bits < 8*HASH_SIZE + 8*SALT_SIZE + 9) + throw Encoding_Error("Cannot encode PSS string, output length too small"); + + const size_t output_length = (output_bits + 7) / 8; + + for(size_t i = 0; i != 8; ++i) + hash.update(0); + hash.update(msg); + hash.update(salt); + secure_vector H = hash.final(); + + secure_vector EM(output_length); + + EM[output_length - HASH_SIZE - SALT_SIZE - 2] = 0x01; + buffer_insert(EM, output_length - 1 - HASH_SIZE - SALT_SIZE, salt); + mgf1_mask(hash, H.data(), HASH_SIZE, EM.data(), output_length - HASH_SIZE - 1); + EM[0] &= 0xFF >> (8 * ((output_bits + 7) / 8) - output_bits); + buffer_insert(EM, output_length - 1 - HASH_SIZE, H); + EM[output_length-1] = 0xBC; + return EM; + } + +bool pss_verify(HashFunction& hash, + const secure_vector& const_coded, + const secure_vector& raw, + size_t key_bits) + { + const size_t HASH_SIZE = hash.output_length(); + const size_t KEY_BYTES = (key_bits + 7) / 8; + + if(key_bits < 8*HASH_SIZE + 9) + return false; + + if(raw.size() != HASH_SIZE) + return false; + + if(const_coded.size() > KEY_BYTES || const_coded.size() <= 1) + return false; + + if(const_coded[const_coded.size()-1] != 0xBC) + return false; + + secure_vector coded = const_coded; + if(coded.size() < KEY_BYTES) + { + secure_vector temp(KEY_BYTES); + buffer_insert(temp, KEY_BYTES - coded.size(), coded); + coded = temp; + } + + const size_t TOP_BITS = 8 * ((key_bits + 7) / 8) - key_bits; + if(TOP_BITS > 8 - high_bit(coded[0])) + return false; + + uint8_t* DB = coded.data(); + const size_t DB_size = coded.size() - HASH_SIZE - 1; + + const uint8_t* H = &coded[DB_size]; + const size_t H_size = HASH_SIZE; + + mgf1_mask(hash, H, H_size, DB, DB_size); + DB[0] &= 0xFF >> TOP_BITS; + + size_t salt_offset = 0; + for(size_t j = 0; j != DB_size; ++j) + { + if(DB[j] == 0x01) + { salt_offset = j + 1; break; } + if(DB[j]) + return false; + } + if(salt_offset == 0) + return false; + + const size_t salt_size = DB_size - salt_offset; + + for(size_t j = 0; j != 8; ++j) + hash.update(0); + hash.update(raw); + hash.update(&DB[salt_offset], salt_size); + + secure_vector H2 = hash.final(); + + return constant_time_compare(H, H2.data(), HASH_SIZE); + } + +} + +PSSR::PSSR(HashFunction* h) : + m_hash(h), m_SALT_SIZE(m_hash->output_length()) + { + } + +PSSR::PSSR(HashFunction* h, size_t salt_size) : + m_hash(h), m_SALT_SIZE(salt_size) + { + } + +/* +* PSSR Update Operation +*/ +void PSSR::update(const uint8_t input[], size_t length) + { + m_hash->update(input, length); + } + +/* +* Return the raw (unencoded) data +*/ +secure_vector PSSR::raw_data() + { + return m_hash->final(); + } + +secure_vector PSSR::encoding_of(const secure_vector& msg, + size_t output_bits, + RandomNumberGenerator& rng) + { + secure_vector salt = rng.random_vec(m_SALT_SIZE); + return pss_encode(*m_hash, msg, salt, output_bits); + } + +/* +* PSSR Decode/Verify Operation +*/ +bool PSSR::verify(const secure_vector& coded, + const secure_vector& raw, + size_t key_bits) + { + return pss_verify(*m_hash, coded, raw, key_bits); + } + +std::string PSSR::name() const + { + return "EMSA4(" + m_hash->name() + ",MGF1," + std::to_string(m_SALT_SIZE) + ")"; + } + +AlgorithmIdentifier PSSR::config_for_x509(const Private_Key& key, + const std::string& cert_hash_name) const + { + if(cert_hash_name != m_hash->name()) + throw Invalid_Argument("Hash function from opts and hash_fn argument" + " need to be identical"); + // check that the signature algorithm and the padding scheme fit + if(!sig_algo_and_pad_ok(key.algo_name(), "EMSA4")) + { + throw Invalid_Argument("Encoding scheme with canonical name EMSA4" + " not supported for signature algorithm " + key.algo_name()); + } + + AlgorithmIdentifier sig_algo; + // hardcoded as RSA is the only valid algorithm for EMSA4 at the moment + sig_algo.oid = OIDS::lookup( "RSA/EMSA4" ); + + const AlgorithmIdentifier hash_id(cert_hash_name, AlgorithmIdentifier::USE_NULL_PARAM); + const AlgorithmIdentifier mgf_id("MGF1", hash_id.BER_encode()); + + DER_Encoder(sig_algo.parameters) + .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(3), CONTEXT_SPECIFIC).encode(size_t(1)).end_cons() // trailer field + .end_cons(); + + return sig_algo; + } + +PSSR_Raw::PSSR_Raw(HashFunction* h) : + m_hash(h), m_SALT_SIZE(m_hash->output_length()) + { + } + +PSSR_Raw::PSSR_Raw(HashFunction* h, size_t salt_size) : + m_hash(h), m_SALT_SIZE(salt_size) + { + } + +/* +* PSSR_Raw Update Operation +*/ +void PSSR_Raw::update(const uint8_t input[], size_t length) + { + m_msg.insert(m_msg.end(), input, input + length); + } + +/* +* Return the raw (unencoded) data +*/ +secure_vector PSSR_Raw::raw_data() + { + secure_vector ret; + std::swap(ret, m_msg); + + if(ret.size() != m_hash->output_length()) + throw Encoding_Error("PSSR_Raw Bad input length, did not match hash"); + + return ret; + } + +secure_vector PSSR_Raw::encoding_of(const secure_vector& msg, + size_t output_bits, + RandomNumberGenerator& rng) + { + secure_vector salt = rng.random_vec(m_SALT_SIZE); + return pss_encode(*m_hash, msg, salt, output_bits); + } + +/* +* PSSR_Raw Decode/Verify Operation +*/ +bool PSSR_Raw::verify(const secure_vector& coded, + const secure_vector& raw, + size_t key_bits) + { + return pss_verify(*m_hash, coded, raw, key_bits); + } + +std::string PSSR_Raw::name() const + { + 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 new file mode 100644 index 0000000000..3b902dd6a8 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pk_pad/emsa_pssr/pssr.h @@ -0,0 +1,99 @@ +/* +* PSSR +* (C) 1999-2007 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_PSSR_H_ +#define BOTAN_PSSR_H_ + +#include +#include + +namespace Botan { + +/** +* PSSR (called EMSA4 in IEEE 1363 and in old versions of the library) +*/ +class BOTAN_PUBLIC_API(2,0) PSSR final : public EMSA + { + public: + + /** + * @param hash the hash function to use + */ + explicit PSSR(HashFunction* hash); + + /** + * @param hash the hash function to use + * @param salt_size the size of the salt to use in bytes + */ + PSSR(HashFunction* hash, size_t salt_size); + + EMSA* clone() override { return new PSSR(m_hash->clone(), m_SALT_SIZE); } + + std::string name() const override; + + AlgorithmIdentifier config_for_x509(const Private_Key& key, + const std::string& cert_hash_name) const override; + private: + void update(const uint8_t input[], size_t length) override; + + secure_vector raw_data() override; + + secure_vector encoding_of(const secure_vector& msg, + size_t output_bits, + RandomNumberGenerator& rng) override; + + bool verify(const secure_vector& coded, + const secure_vector& raw, + size_t key_bits) override; + + std::unique_ptr m_hash; + size_t m_SALT_SIZE; + }; + +/** +* PSSR_Raw +* This accepts a pre-hashed buffer +*/ +class BOTAN_PUBLIC_API(2,3) PSSR_Raw final : public EMSA + { + public: + + /** + * @param hash the hash function to use + */ + explicit PSSR_Raw(HashFunction* hash); + + /** + * @param hash the hash function to use + * @param salt_size the size of the salt to use in bytes + */ + PSSR_Raw(HashFunction* hash, size_t salt_size); + + EMSA* clone() override { return new PSSR_Raw(m_hash->clone(), m_SALT_SIZE); } + + std::string name() const override; + private: + void update(const uint8_t input[], size_t length) override; + + secure_vector raw_data() override; + + secure_vector encoding_of(const secure_vector& msg, + size_t output_bits, + RandomNumberGenerator& rng) override; + + bool verify(const secure_vector& coded, + const secure_vector& raw, + size_t key_bits) override; + + std::unique_ptr m_hash; + size_t m_SALT_SIZE; + secure_vector m_msg; + }; + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/pk_pad/hash_id/hash_id.cpp b/src/libs/3rdparty/botan/src/lib/pk_pad/hash_id/hash_id.cpp new file mode 100644 index 0000000000..ec317f9692 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pk_pad/hash_id/hash_id.cpp @@ -0,0 +1,163 @@ +/* +* Hash Function Identification +* (C) 1999-2008 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include + +namespace Botan { + +namespace { + +const uint8_t MD5_PKCS_ID[] = { +0x30, 0x20, 0x30, 0x0C, 0x06, 0x08, 0x2A, 0x86, 0x48, 0x86, +0xF7, 0x0D, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10 }; + +const uint8_t RIPEMD_160_PKCS_ID[] = { +0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x24, 0x03, 0x02, +0x01, 0x05, 0x00, 0x04, 0x14 }; + +const uint8_t SHA_160_PKCS_ID[] = { +0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x0E, 0x03, 0x02, +0x1A, 0x05, 0x00, 0x04, 0x14 }; + +const uint8_t SHA_224_PKCS_ID[] = { +0x30, 0x2D, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, +0x65, 0x03, 0x04, 0x02, 0x04, 0x05, 0x00, 0x04, 0x1C }; + +const uint8_t SHA_256_PKCS_ID[] = { +0x30, 0x31, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, +0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20 }; + +const uint8_t SHA_384_PKCS_ID[] = { +0x30, 0x41, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, +0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30 }; + +const uint8_t SHA_512_PKCS_ID[] = { +0x30, 0x51, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, +0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40 }; + +const uint8_t SHA_512_256_PKCS_ID[] = { +0x30, 0x31, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, +0x65, 0x03, 0x04, 0x02, 0x06, 0x05, 0x00, 0x04, 0x20 }; + +const uint8_t SHA3_224_PKCS_ID[] = { +0x30, 0x2D, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, +0x03, 0x04, 0x02, 0x07, 0x05, 0x00, 0x04, 0x1C }; + +const uint8_t SHA3_256_PKCS_ID[] = { +0x30, 0x31, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, +0x03, 0x04, 0x02, 0x08, 0x05, 0x00, 0x04, 0x20 }; + +const uint8_t SHA3_384_PKCS_ID[] = { +0x30, 0x41, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, +0x03, 0x04, 0x02, 0x09, 0x05, 0x00, 0x04, 0x30 }; + +const uint8_t SHA3_512_PKCS_ID[] = { +0x30, 0x51, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, +0x03, 0x04, 0x02, 0x0A, 0x05, 0x00, 0x04, 0x40 }; + +const uint8_t SM3_PKCS_ID[] = { +0x30, 0x30, 0x30, 0x0C, 0x06, 0x08, 0x2A, 0x81, 0x1C, 0xCF, +0x55, 0x01, 0x83, 0x11, 0x05, 0x00, 0x04, 0x20, +}; + +const uint8_t TIGER_PKCS_ID[] = { +0x30, 0x29, 0x30, 0x0D, 0x06, 0x09, 0x2B, 0x06, 0x01, 0x04, +0x01, 0xDA, 0x47, 0x0C, 0x02, 0x05, 0x00, 0x04, 0x18 }; + +} + +/* +* HashID as specified by PKCS +*/ +std::vector pkcs_hash_id(const std::string& name) + { + // Special case for SSL/TLS RSA signatures + if(name == "Parallel(MD5,SHA-160)") + return std::vector(); + + // If you add a value to this function, also update test_hash_id.cpp + + if(name == "MD5") + return std::vector(MD5_PKCS_ID, + MD5_PKCS_ID + sizeof(MD5_PKCS_ID)); + + if(name == "RIPEMD-160") + return std::vector(RIPEMD_160_PKCS_ID, + RIPEMD_160_PKCS_ID + sizeof(RIPEMD_160_PKCS_ID)); + + if(name == "SHA-160" || name == "SHA-1" || name == "SHA1") + return std::vector(SHA_160_PKCS_ID, + SHA_160_PKCS_ID + sizeof(SHA_160_PKCS_ID)); + + if(name == "SHA-224") + return std::vector(SHA_224_PKCS_ID, + SHA_224_PKCS_ID + sizeof(SHA_224_PKCS_ID)); + + if(name == "SHA-256") + return std::vector(SHA_256_PKCS_ID, + SHA_256_PKCS_ID + sizeof(SHA_256_PKCS_ID)); + + if(name == "SHA-384") + return std::vector(SHA_384_PKCS_ID, + SHA_384_PKCS_ID + sizeof(SHA_384_PKCS_ID)); + + if(name == "SHA-512") + return std::vector(SHA_512_PKCS_ID, + SHA_512_PKCS_ID + sizeof(SHA_512_PKCS_ID)); + + if(name == "SHA-512-256") + return std::vector(SHA_512_256_PKCS_ID, + SHA_512_256_PKCS_ID + sizeof(SHA_512_256_PKCS_ID)); + + if(name == "SHA-3(224)") + return std::vector(SHA3_224_PKCS_ID, + SHA3_224_PKCS_ID + sizeof(SHA3_224_PKCS_ID)); + + if(name == "SHA-3(256)") + return std::vector(SHA3_256_PKCS_ID, + SHA3_256_PKCS_ID + sizeof(SHA3_256_PKCS_ID)); + + if(name == "SHA-3(384)") + return std::vector(SHA3_384_PKCS_ID, + SHA3_384_PKCS_ID + sizeof(SHA3_384_PKCS_ID)); + + if(name == "SHA-3(512)") + return std::vector(SHA3_512_PKCS_ID, + SHA3_512_PKCS_ID + sizeof(SHA3_512_PKCS_ID)); + + if(name == "SM3") + return std::vector(SM3_PKCS_ID, SM3_PKCS_ID + sizeof(SM3_PKCS_ID)); + + if(name == "Tiger(24,3)") + return std::vector(TIGER_PKCS_ID, + TIGER_PKCS_ID + sizeof(TIGER_PKCS_ID)); + + throw Invalid_Argument("No PKCS #1 identifier for " + name); + } + +/* +* HashID as specified by IEEE 1363/X9.31 +*/ +uint8_t ieee1363_hash_id(const std::string& name) + { + if(name == "SHA-160" || name == "SHA-1" || name == "SHA1") + return 0x33; + + if(name == "SHA-224") return 0x38; + if(name == "SHA-256") return 0x34; + if(name == "SHA-384") return 0x36; + if(name == "SHA-512") return 0x35; + + if(name == "RIPEMD-160") return 0x31; + + if(name == "Whirlpool") return 0x37; + + return 0; + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/pk_pad/hash_id/hash_id.h b/src/libs/3rdparty/botan/src/lib/pk_pad/hash_id/hash_id.h new file mode 100644 index 0000000000..75c86c0c65 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pk_pad/hash_id/hash_id.h @@ -0,0 +1,34 @@ +/* +* Hash Function Identification +* (C) 1999-2007 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_HASHID_H_ +#define BOTAN_HASHID_H_ + +#include +#include + +namespace Botan { + +/** +* Return the PKCS #1 hash identifier +* @see RFC 3447 section 9.2 +* @param hash_name the name of the hash function +* @return uint8_t sequence identifying the hash +* @throw Invalid_Argument if the hash has no known PKCS #1 hash id +*/ +BOTAN_PUBLIC_API(2,0) std::vector pkcs_hash_id(const std::string& hash_name); + +/** +* Return the IEEE 1363 hash identifier +* @param hash_name the name of the hash function +* @return uint8_t code identifying the hash, or 0 if not known +*/ +BOTAN_PUBLIC_API(2,0) uint8_t ieee1363_hash_id(const std::string& hash_name); + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/pk_pad/hash_id/info.txt b/src/libs/3rdparty/botan/src/lib/pk_pad/hash_id/info.txt new file mode 100644 index 0000000000..8cd930a9fe --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pk_pad/hash_id/info.txt @@ -0,0 +1,3 @@ + +HASH_ID -> 20131128 + diff --git a/src/libs/3rdparty/botan/src/lib/pk_pad/info.txt b/src/libs/3rdparty/botan/src/lib/pk_pad/info.txt new file mode 100644 index 0000000000..afadf56554 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pk_pad/info.txt @@ -0,0 +1,20 @@ + +PK_PADDING -> 20131128 + + +load_on auto + + +asn1 +rng +pubkey + + + +padding.h + + + +eme.h +emsa.h + diff --git a/src/libs/3rdparty/botan/src/lib/pk_pad/mgf1/info.txt b/src/libs/3rdparty/botan/src/lib/pk_pad/mgf1/info.txt new file mode 100644 index 0000000000..f17c72fda4 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pk_pad/mgf1/info.txt @@ -0,0 +1,3 @@ + +MGF1 -> 20140118 + 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 new file mode 100644 index 0000000000..dbfac5110d --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pk_pad/mgf1/mgf1.cpp @@ -0,0 +1,35 @@ +/* +* MGF1 +* (C) 1999-2007 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include + +namespace Botan { + +void mgf1_mask(HashFunction& hash, + const uint8_t in[], size_t in_len, + uint8_t out[], size_t out_len) + { + uint32_t counter = 0; + + while(out_len) + { + hash.update(in, in_len); + hash.update_be(counter); + secure_vector buffer = hash.final(); + + size_t xored = std::min(buffer.size(), out_len); + xor_buf(out, buffer.data(), xored); + out += xored; + out_len -= xored; + + ++counter; + } + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/pk_pad/mgf1/mgf1.h b/src/libs/3rdparty/botan/src/lib/pk_pad/mgf1/mgf1.h new file mode 100644 index 0000000000..9eb652a825 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pk_pad/mgf1/mgf1.h @@ -0,0 +1,31 @@ +/* +* MGF1 +* (C) 1999-2007,2014 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_MGF1_H_ +#define BOTAN_MGF1_H_ + +#include + +namespace Botan { + +class HashFunction; + +/** +* MGF1 from PKCS #1 v2.0 +* @param hash hash function to use +* @param in input buffer +* @param in_len size of the input buffer in bytes +* @param out output buffer +* @param out_len size of the output buffer in bytes +*/ +void BOTAN_PUBLIC_API(2,0) mgf1_mask(HashFunction& hash, + const uint8_t in[], size_t in_len, + uint8_t out[], size_t out_len); + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/pk_pad/padding.cpp b/src/libs/3rdparty/botan/src/lib/pk_pad/padding.cpp new file mode 100644 index 0000000000..134bb41017 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pk_pad/padding.cpp @@ -0,0 +1,42 @@ +/* +* Sets of allowed padding schemes for public key types +* +* This file was automatically generated by ./src/scripts/oids.py on 2017-12-20 +* +* All manual edits to this file will be lost. Edit the script +* then regenerate this source file. +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include +#include + +namespace Botan { + +const std::map> allowed_signature_paddings = + { + { "DSA", {"EMSA1"} }, + { "ECDSA", {"EMSA1"} }, + { "ECGDSA", {"EMSA1"} }, + { "ECKCDSA", {"EMSA1"} }, + { "GOST-34.10", {"EMSA1"} }, + { "RSA", {"EMSA4", "EMSA3"} }, + }; + +const std::vector get_sig_paddings(const std::string algo) + { + if(allowed_signature_paddings.count(algo) > 0) + return allowed_signature_paddings.at(algo); + return {}; + } + +bool sig_algo_and_pad_ok(const std::string algo, const std::string padding) + { + std::vector pads = get_sig_paddings(algo); + return std::find(pads.begin(), pads.end(), padding) != pads.end(); + } +} diff --git a/src/libs/3rdparty/botan/src/lib/pk_pad/padding.h b/src/libs/3rdparty/botan/src/lib/pk_pad/padding.h new file mode 100644 index 0000000000..ed05ec3819 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pk_pad/padding.h @@ -0,0 +1,36 @@ +/* +* (C) 2017 Fabian Weissberg, Rohde & Schwarz Cybersecurity +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_PADDING_H_ +#define BOTAN_PADDING_H_ + +#include +#include +#include + +namespace Botan { + +/** +* Returns the allowed padding schemes when using the given +* algorithm (key type) for creating digital signatures. +* +* @param algo the algorithm for which to look up supported padding schemes +* @return a vector of supported padding schemes +*/ +BOTAN_TEST_API const std::vector get_sig_paddings(const std::string algo); + +/** +* Returns true iff the given padding scheme is valid for the given +* signature algorithm (key type). +* +* @param algo the signature algorithm to be used +* @param padding the padding scheme to be used +*/ +bool sig_algo_and_pad_ok(const std::string algo, const std::string padding); + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/blinding.cpp b/src/libs/3rdparty/botan/src/lib/pubkey/blinding.cpp new file mode 100644 index 0000000000..ecd420780c --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pubkey/blinding.cpp @@ -0,0 +1,66 @@ +/* +* Blinding for public key operations +* (C) 1999-2010,2015 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include + +namespace Botan { + +Blinder::Blinder(const BigInt& modulus, + RandomNumberGenerator& rng, + std::function fwd, + std::function inv) : + m_reducer(modulus), + m_rng(rng), + m_fwd_fn(fwd), + m_inv_fn(inv), + m_modulus_bits(modulus.bits()), + m_e{}, + m_d{}, + m_counter{} + { + const BigInt k = blinding_nonce(); + m_e = m_fwd_fn(k); + m_d = m_inv_fn(k); + } + +BigInt Blinder::blinding_nonce() const + { + return BigInt(m_rng, m_modulus_bits - 1); + } + +BigInt Blinder::blind(const BigInt& i) const + { + if(!m_reducer.initialized()) + throw Exception("Blinder not initialized, cannot blind"); + + ++m_counter; + + if((BOTAN_BLINDING_REINIT_INTERVAL > 0) && (m_counter > BOTAN_BLINDING_REINIT_INTERVAL)) + { + const BigInt k = blinding_nonce(); + m_e = m_fwd_fn(k); + m_d = m_inv_fn(k); + m_counter = 0; + } + else + { + m_e = m_reducer.square(m_e); + m_d = m_reducer.square(m_d); + } + + return m_reducer.multiply(i, m_e); + } + +BigInt Blinder::unblind(const BigInt& i) const + { + if(!m_reducer.initialized()) + throw Exception("Blinder not initialized, cannot unblind"); + + return m_reducer.multiply(i, m_d); + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/blinding.h b/src/libs/3rdparty/botan/src/lib/pubkey/blinding.h new file mode 100644 index 0000000000..1bdd235f0f --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pubkey/blinding.h @@ -0,0 +1,78 @@ +/* +* Blinding for public key operations +* (C) 1999-2010,2015 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_BLINDER_H_ +#define BOTAN_BLINDER_H_ + +#include +#include +#include + +namespace Botan { + +class RandomNumberGenerator; + +/** +* Blinding Function Object. +*/ +class BOTAN_PUBLIC_API(2,0) Blinder final + { + public: + /** + * Blind a value. + * The blinding nonce k is freshly generated after + * BOTAN_BLINDING_REINIT_INTERVAL calls to blind(). + * BOTAN_BLINDING_REINIT_INTERVAL = 0 means a fresh + * nonce is only generated once. On every other call, + * an updated nonce is used for blinding: k' = k*k mod n. + * @param x value to blind + * @return blinded value + */ + BigInt blind(const BigInt& x) const; + + /** + * Unblind a value. + * @param x value to unblind + * @return unblinded value + */ + BigInt unblind(const BigInt& x) const; + + /** + * @param modulus the modulus + * @param rng the RNG to use for generating the nonce + * @param fwd_func a function that calculates the modular + * exponentiation of the public exponent and the given value (the nonce) + * @param inv_func a function that calculates the modular inverse + * of the given value (the nonce) + */ + Blinder(const BigInt& modulus, + RandomNumberGenerator& rng, + std::function fwd_func, + std::function inv_func); + + Blinder(const Blinder&) = delete; + + Blinder& operator=(const Blinder&) = delete; + + RandomNumberGenerator& rng() const { return m_rng; } + + private: + BigInt blinding_nonce() const; + + Modular_Reducer m_reducer; + RandomNumberGenerator& m_rng; + std::function m_fwd_fn; + std::function m_inv_fn; + size_t m_modulus_bits = 0; + + mutable BigInt m_e, m_d; + mutable size_t m_counter = 0; + }; + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/dh/dh.cpp b/src/libs/3rdparty/botan/src/lib/pubkey/dh/dh.cpp new file mode 100644 index 0000000000..ae6e9c589b --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pubkey/dh/dh.cpp @@ -0,0 +1,130 @@ +/* +* Diffie-Hellman +* (C) 1999-2007,2016 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include + +namespace Botan { + +/* +* DH_PublicKey Constructor +*/ +DH_PublicKey::DH_PublicKey(const DL_Group& grp, const BigInt& y1) + { + m_group = grp; + m_y = y1; + } + +/* +* Return the public value for key agreement +*/ +std::vector DH_PublicKey::public_value() const + { + return unlock(BigInt::encode_1363(m_y, group_p().bytes())); + } + +/* +* Create a DH private key +*/ +DH_PrivateKey::DH_PrivateKey(RandomNumberGenerator& rng, + const DL_Group& grp, + const BigInt& x_arg) + { + m_group = grp; + + if(x_arg == 0) + { + const size_t exp_bits = grp.exponent_bits(); + m_x.randomize(rng, exp_bits); + m_y = m_group.power_g_p(m_x, exp_bits); + } + else + { + m_x = x_arg; + + if(m_y == 0) + m_y = m_group.power_g_p(m_x, grp.p_bits()); + } + } + +/* +* Load a DH private key +*/ +DH_PrivateKey::DH_PrivateKey(const AlgorithmIdentifier& alg_id, + const secure_vector& key_bits) : + DL_Scheme_PrivateKey(alg_id, key_bits, DL_Group::ANSI_X9_42) + { + if(m_y.is_zero()) + { + m_y = m_group.power_g_p(m_x, m_group.p_bits()); + } + } + +/* +* Return the public value for key agreement +*/ +std::vector DH_PrivateKey::public_value() const + { + return DH_PublicKey::public_value(); + } + +namespace { + +/** +* DH operation +*/ +class DH_KA_Operation final : public PK_Ops::Key_Agreement_with_KDF + { + public: + + DH_KA_Operation(const DH_PrivateKey& key, const std::string& kdf, RandomNumberGenerator& rng) : + PK_Ops::Key_Agreement_with_KDF(kdf), + m_p(key.group_p()), + m_powermod_x_p(key.get_x(), m_p), + m_blinder(m_p, + rng, + [](const BigInt& k) { return k; }, + [this](const BigInt& k) { return m_powermod_x_p(inverse_mod(k, m_p)); }) + {} + + secure_vector raw_agree(const uint8_t w[], size_t w_len) override; + private: + const BigInt& m_p; + + Fixed_Exponent_Power_Mod m_powermod_x_p; + Blinder m_blinder; + }; + +secure_vector DH_KA_Operation::raw_agree(const uint8_t w[], size_t w_len) + { + BigInt v = BigInt::decode(w, w_len); + + if(v <= 1 || v >= m_p - 1) + throw Invalid_Argument("DH agreement - invalid key provided"); + + v = m_blinder.blind(v); + v = m_powermod_x_p(v); + v = m_blinder.unblind(v); + + return BigInt::encode_1363(v, m_p.bytes()); + } + +} + +std::unique_ptr +DH_PrivateKey::create_key_agreement_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) const + { + if(provider == "base" || provider.empty()) + return std::unique_ptr(new DH_KA_Operation(*this, params, rng)); + throw Provider_Not_Found(algo_name(), provider); + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/dh/dh.h b/src/libs/3rdparty/botan/src/lib/pubkey/dh/dh.h new file mode 100644 index 0000000000..e3aa0d2c5b --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pubkey/dh/dh.h @@ -0,0 +1,81 @@ +/* +* Diffie-Hellman +* (C) 1999-2007 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_DIFFIE_HELLMAN_H_ +#define BOTAN_DIFFIE_HELLMAN_H_ + +#include + +namespace Botan { + +/** +* This class represents Diffie-Hellman public keys. +*/ +class BOTAN_PUBLIC_API(2,0) DH_PublicKey : public virtual DL_Scheme_PublicKey + { + public: + std::string algo_name() const override { return "DH"; } + + std::vector public_value() const; + + DL_Group::Format group_format() const override { return DL_Group::ANSI_X9_42; } + + /** + * Create a public key. + * @param alg_id the X.509 algorithm identifier + * @param key_bits DER encoded public key bits + */ + DH_PublicKey(const AlgorithmIdentifier& alg_id, + const std::vector& key_bits) : + DL_Scheme_PublicKey(alg_id, key_bits, DL_Group::ANSI_X9_42) {} + + /** + * Construct a public key with the specified parameters. + * @param grp the DL group to use in the key + * @param y the public value y + */ + DH_PublicKey(const DL_Group& grp, const BigInt& y); + protected: + DH_PublicKey() = default; + }; + +/** +* This class represents Diffie-Hellman private keys. +*/ +class BOTAN_PUBLIC_API(2,0) DH_PrivateKey final : public DH_PublicKey, + public PK_Key_Agreement_Key, + public virtual DL_Scheme_PrivateKey + { + public: + std::vector public_value() const override; + + /** + * Load a private key. + * @param alg_id the X.509 algorithm identifier + * @param key_bits PKCS #8 structure + */ + DH_PrivateKey(const AlgorithmIdentifier& alg_id, + const secure_vector& key_bits); + + /** + * Create a private key. + * @param rng random number generator to use + * @param grp the group to be used in the key + * @param x the key's secret value (or if zero, generate a new key) + */ + DH_PrivateKey(RandomNumberGenerator& rng, const DL_Group& grp, + const BigInt& x = 0); + + std::unique_ptr + create_key_agreement_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) const override; + }; + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/dh/info.txt b/src/libs/3rdparty/botan/src/lib/pubkey/dh/info.txt new file mode 100644 index 0000000000..1b9ba24948 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pubkey/dh/info.txt @@ -0,0 +1,13 @@ + +DIFFIE_HELLMAN -> 20131128 + + + +dh.h + + + +dl_algo +dl_group +numbertheory + diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/dl_algo/dl_algo.cpp b/src/libs/3rdparty/botan/src/lib/pubkey/dl_algo/dl_algo.cpp new file mode 100644 index 0000000000..15b0b175e4 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pubkey/dl_algo/dl_algo.cpp @@ -0,0 +1,84 @@ +/* +* DL Scheme +* (C) 1999-2007 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include + +namespace Botan { + +size_t DL_Scheme_PublicKey::key_length() const + { + return m_group.p_bits(); + } + +size_t DL_Scheme_PublicKey::estimated_strength() const + { + return m_group.estimated_strength(); + } + +AlgorithmIdentifier DL_Scheme_PublicKey::algorithm_identifier() const + { + return AlgorithmIdentifier(get_oid(), + m_group.DER_encode(group_format())); + } + +std::vector DL_Scheme_PublicKey::public_key_bits() const + { + std::vector output; + DER_Encoder(output).encode(m_y); + return output; + } + +DL_Scheme_PublicKey::DL_Scheme_PublicKey(const DL_Group& group, const BigInt& y) : + m_y(y), + m_group(group) + { + } + +DL_Scheme_PublicKey::DL_Scheme_PublicKey(const AlgorithmIdentifier& alg_id, + const std::vector& key_bits, + DL_Group::Format format) : + m_group(alg_id.get_parameters(), format) + { + BER_Decoder(key_bits).decode(m_y); + } + +secure_vector DL_Scheme_PrivateKey::private_key_bits() const + { + return DER_Encoder().encode(m_x).get_contents(); + } + +DL_Scheme_PrivateKey::DL_Scheme_PrivateKey(const AlgorithmIdentifier& alg_id, + const secure_vector& key_bits, + DL_Group::Format format) + { + m_group.BER_decode(alg_id.get_parameters(), format); + + BER_Decoder(key_bits).decode(m_x); + } + +/* +* Check Public DL Parameters +*/ +bool DL_Scheme_PublicKey::check_key(RandomNumberGenerator& rng, + bool strong) const + { + return m_group.verify_group(rng, strong) && m_group.verify_public_element(m_y); + } + +/* +* Check DL Scheme Private Parameters +*/ +bool DL_Scheme_PrivateKey::check_key(RandomNumberGenerator& rng, + bool strong) const + { + return m_group.verify_group(rng, strong) && m_group.verify_element_pair(m_y, m_x); + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/dl_algo/dl_algo.h b/src/libs/3rdparty/botan/src/lib/pubkey/dl_algo/dl_algo.h new file mode 100644 index 0000000000..af01bc217a --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pubkey/dl_algo/dl_algo.h @@ -0,0 +1,140 @@ +/* +* DL Scheme +* (C) 1999-2007 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_DL_ALGO_H_ +#define BOTAN_DL_ALGO_H_ + +#include +#include + +namespace Botan { + +/** +* This class represents discrete logarithm (DL) public keys. +*/ +class BOTAN_PUBLIC_API(2,0) DL_Scheme_PublicKey : public virtual Public_Key + { + public: + bool check_key(RandomNumberGenerator& rng, bool) const override; + + AlgorithmIdentifier algorithm_identifier() const override; + + std::vector public_key_bits() const override; + + /** + * Get the DL domain parameters of this key. + * @return DL domain parameters of this key + */ + const DL_Group& get_domain() const { return m_group; } + + /** + * Get the DL domain parameters of this key. + * @return DL domain parameters of this key + */ + const DL_Group& get_group() const { return m_group; } + + /** + * Get the public value y with y = g^x mod p where x is the secret key. + */ + const BigInt& get_y() const { return m_y; } + + /** + * Get the prime p of the underlying DL group. + * @return prime p + */ + const BigInt& group_p() const { return m_group.get_p(); } + + /** + * Get the prime q of the underlying DL group. + * @return prime q + */ + const BigInt& group_q() const { return m_group.get_q(); } + + /** + * Get the generator g of the underlying DL group. + * @return generator g + */ + const BigInt& group_g() const { return m_group.get_g(); } + + /** + * Get the underlying groups encoding format. + * @return encoding format + */ + virtual DL_Group::Format group_format() const = 0; + + size_t key_length() const override; + size_t estimated_strength() const override; + + DL_Scheme_PublicKey& operator=(const DL_Scheme_PublicKey& other) = default; + + protected: + DL_Scheme_PublicKey() = default; + + /** + * Create a public key. + * @param alg_id the X.509 algorithm identifier + * @param key_bits DER encoded public key bits + * @param group_format the underlying groups encoding format + */ + DL_Scheme_PublicKey(const AlgorithmIdentifier& alg_id, + const std::vector& key_bits, + DL_Group::Format group_format); + + DL_Scheme_PublicKey(const DL_Group& group, const BigInt& y); + + /** + * The DL public key + */ + BigInt m_y; + + /** + * The DL group + */ + DL_Group m_group; + }; + +/** +* This class represents discrete logarithm (DL) private keys. +*/ +class BOTAN_PUBLIC_API(2,0) DL_Scheme_PrivateKey : public virtual DL_Scheme_PublicKey, + public virtual Private_Key + { + public: + bool check_key(RandomNumberGenerator& rng, bool) const override; + + /** + * Get the secret key x. + * @return secret key + */ + const BigInt& get_x() const { return m_x; } + + secure_vector private_key_bits() const override; + + DL_Scheme_PrivateKey& operator=(const DL_Scheme_PrivateKey& other) = default; + + protected: + /** + * Create a private key. + * @param alg_id the X.509 algorithm identifier + * @param key_bits DER encoded private key bits + * @param group_format the underlying groups encoding format + */ + DL_Scheme_PrivateKey(const AlgorithmIdentifier& alg_id, + const secure_vector& key_bits, + DL_Group::Format group_format); + + DL_Scheme_PrivateKey() = default; + + /** + * The DL private key + */ + BigInt m_x; + }; + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/dl_algo/info.txt b/src/libs/3rdparty/botan/src/lib/pubkey/dl_algo/info.txt new file mode 100644 index 0000000000..44e649cd67 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pubkey/dl_algo/info.txt @@ -0,0 +1,10 @@ + +DL_PUBLIC_KEY_FAMILY -> 20131128 + + + +asn1 +dl_group +numbertheory +rng + 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 new file mode 100644 index 0000000000..abc14ec0c7 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pubkey/dl_group/dl_group.cpp @@ -0,0 +1,610 @@ +/* +* Discrete Logarithm Parameters +* (C) 1999-2008,2015,2018 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Botan { + +class DL_Group_Data final + { + public: + DL_Group_Data(const BigInt& p, const BigInt& q, const BigInt& g) : + m_p(p), m_q(q), m_g(g), + m_mod_p(p), + m_mod_q(q), + m_monty_params(std::make_shared(m_p, m_mod_p)), + m_monty(monty_precompute(m_monty_params, m_g, /*window bits=*/4)), + m_p_bits(p.bits()), + m_q_bits(q.bits()), + m_estimated_strength(dl_work_factor(m_p_bits)), + m_exponent_bits(dl_exponent_size(m_p_bits)) + { + } + + ~DL_Group_Data() = default; + + DL_Group_Data(const DL_Group_Data& other) = delete; + DL_Group_Data& operator=(const DL_Group_Data& other) = delete; + + const BigInt& p() const { return m_p; } + const BigInt& q() const { return m_q; } + const BigInt& g() const { return m_g; } + + BigInt mod_p(const BigInt& x) const { return m_mod_p.reduce(x); } + + BigInt multiply_mod_p(const BigInt& x, const BigInt& y) const + { + return m_mod_p.multiply(x, y); + } + + BigInt mod_q(const BigInt& x) const { return m_mod_q.reduce(x); } + + BigInt multiply_mod_q(const BigInt& x, const BigInt& y) const + { + return m_mod_q.multiply(x, y); + } + + BigInt square_mod_q(const BigInt& x) const + { + return m_mod_q.square(x); + } + + std::shared_ptr monty_params_p() const + { return m_monty_params; } + + 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 estimated_strength() const { return m_estimated_strength; } + + size_t exponent_bits() const { return m_exponent_bits; } + + BigInt power_g_p(const BigInt& k, size_t max_k_bits) const + { + return monty_execute(*m_monty, k, max_k_bits); + } + + bool q_is_set() const { return m_q_bits > 0; } + + void assert_q_is_set(const std::string& function) const + { + if(q_is_set() == false) + throw Invalid_State("DL_Group::" + function + " q is not set for this group"); + } + + private: + BigInt m_p; + BigInt m_q; + BigInt m_g; + Modular_Reducer m_mod_p; + Modular_Reducer m_mod_q; + std::shared_ptr m_monty_params; + std::shared_ptr m_monty; + size_t m_p_bits; + size_t m_q_bits; + size_t m_estimated_strength; + size_t m_exponent_bits; + }; + +//static +std::shared_ptr DL_Group::BER_decode_DL_group(const uint8_t data[], size_t data_len, DL_Group::Format format) + { + BigInt p, q, g; + + BER_Decoder decoder(data, data_len); + BER_Decoder ber = decoder.start_cons(SEQUENCE); + + if(format == DL_Group::ANSI_X9_57) + { + ber.decode(p) + .decode(q) + .decode(g) + .verify_end(); + } + else if(format == DL_Group::ANSI_X9_42) + { + ber.decode(p) + .decode(g) + .decode(q) + .discard_remaining(); + } + else if(format == DL_Group::PKCS_3) + { + // q is left as zero + ber.decode(p) + .decode(g) + .discard_remaining(); + } + else + throw Invalid_Argument("Unknown DL_Group encoding " + std::to_string(format)); + + return std::make_shared(p, q, g); + } + +//static +std::shared_ptr +DL_Group::load_DL_group_info(const char* p_str, + const char* q_str, + const char* g_str) + { + const BigInt p(p_str); + const BigInt q(q_str); + const BigInt g(g_str); + + return std::make_shared(p, q, g); + } + +//static +std::shared_ptr +DL_Group::load_DL_group_info(const char* p_str, + const char* g_str) + { + const BigInt p(p_str); + const BigInt q = (p - 1) / 2; + const BigInt g(g_str); + + return std::make_shared(p, q, g); + } + +namespace { + +DL_Group::Format pem_label_to_dl_format(const std::string& label) + { + if(label == "DH PARAMETERS") + return DL_Group::PKCS_3; + else if(label == "DSA PARAMETERS") + return DL_Group::ANSI_X9_57; + else if(label == "X942 DH PARAMETERS" || label == "X9.42 DH PARAMETERS") + return DL_Group::ANSI_X9_42; + else + throw Decoding_Error("DL_Group: Invalid PEM label " + label); + } + +} + +/* +* DL_Group Constructor +*/ +DL_Group::DL_Group(const std::string& str) + { + // Either a name or a PEM block, try name first + m_data = DL_group_info(str); + + if(m_data == nullptr) + { + try + { + std::string label; + const std::vector ber = unlock(PEM_Code::decode(str, label)); + Format format = pem_label_to_dl_format(label); + + m_data = BER_decode_DL_group(ber.data(), ber.size(), format); + } + catch(...) {} + } + + if(m_data == nullptr) + throw Invalid_Argument("DL_Group: Unknown group " + str); + } + +namespace { + +/* +* Create generator of the q-sized subgroup (DSA style generator) +*/ +BigInt make_dsa_generator(const BigInt& p, const BigInt& q) + { + const BigInt e = (p - 1) / q; + + if(e == 0 || (p - 1) % q > 0) + throw Invalid_Argument("make_dsa_generator q does not divide p-1"); + + for(size_t i = 0; i != PRIME_TABLE_SIZE; ++i) + { + // TODO precompute! + BigInt g = power_mod(PRIMES[i], e, p); + if(g > 1) + return g; + } + + throw Internal_Error("DL_Group: Couldn't create a suitable generator"); + } + +} + +/* +* DL_Group Constructor +*/ +DL_Group::DL_Group(RandomNumberGenerator& rng, + PrimeType type, size_t pbits, size_t qbits) + { + if(pbits < 1024) + throw Invalid_Argument("DL_Group: prime size " + std::to_string(pbits) + " is too small"); + + if(type == Strong) + { + if(qbits != 0 && qbits != pbits - 1) + throw Invalid_Argument("Cannot create strong-prime DL_Group with specified q bits"); + + const BigInt p = random_safe_prime(rng, pbits); + const BigInt q = (p - 1) / 2; + + /* + Always choose a generator that is quadratic reside mod p, + this forces g to be a generator of the subgroup of size q. + */ + BigInt g = 2; + if(jacobi(g, p) != 1) + { + // prime table does not contain 2 + for(size_t i = 0; i < PRIME_TABLE_SIZE; ++i) + { + g = PRIMES[i]; + if(jacobi(g, p) == 1) + break; + } + } + + m_data = std::make_shared(p, q, g); + } + else if(type == Prime_Subgroup) + { + if(qbits == 0) + qbits = dl_exponent_size(pbits); + + const BigInt q = random_prime(rng, qbits); + Modular_Reducer mod_2q(2*q); + BigInt X; + BigInt p; + while(p.bits() != pbits || !is_prime(p, rng, 128, true)) + { + X.randomize(rng, pbits); + p = X - mod_2q.reduce(X) + 1; + } + + const BigInt g = make_dsa_generator(p, q); + m_data = std::make_shared(p, q, g); + } + else if(type == DSA_Kosherizer) + { + if(qbits == 0) + qbits = ((pbits <= 1024) ? 160 : 256); + + BigInt p, q; + generate_dsa_primes(rng, p, q, pbits, qbits); + const BigInt g = make_dsa_generator(p, q); + m_data = std::make_shared(p, q, g); + } + else + { + throw Invalid_Argument("DL_Group unknown PrimeType"); + } + } + +/* +* DL_Group Constructor +*/ +DL_Group::DL_Group(RandomNumberGenerator& rng, + const std::vector& seed, + size_t pbits, size_t qbits) + { + BigInt p, q; + + if(!generate_dsa_primes(rng, p, q, pbits, qbits, seed)) + throw Invalid_Argument("DL_Group: The seed given does not generate a DSA group"); + + BigInt g = make_dsa_generator(p, q); + + m_data = std::make_shared(p, q, g); + } + +/* +* DL_Group Constructor +*/ +DL_Group::DL_Group(const BigInt& p, const BigInt& g) + { + m_data = std::make_shared(p, 0, g); + } + +/* +* DL_Group Constructor +*/ +DL_Group::DL_Group(const BigInt& p, const BigInt& q, const BigInt& g) + { + m_data = std::make_shared(p, q, g); + } + +const DL_Group_Data& DL_Group::data() const + { + if(m_data) + return *m_data; + + throw Invalid_State("DL_Group uninitialized"); + } + +bool DL_Group::verify_public_element(const BigInt& y) const + { + const BigInt& p = get_p(); + const BigInt& q = get_q(); + + if(y <= 1 || y >= p) + return false; + + if(q.is_zero() == false) + { + if(power_mod(y, q, p) != 1) + return false; + } + + return true; + } + +bool DL_Group::verify_element_pair(const BigInt& y, const BigInt& x) const + { + const BigInt& p = get_p(); + + if(y <= 1 || y >= p || x <= 1 || x >= p) + return false; + + if(y != power_g_p(x)) + return false; + + return true; + } + +/* +* Verify the parameters +*/ +bool DL_Group::verify_group(RandomNumberGenerator& rng, + bool strong) const + { + const BigInt& p = get_p(); + const BigInt& q = get_q(); + const BigInt& g = get_g(); + + if(g < 2 || p < 3 || q < 0) + return false; + + const size_t prob = (strong) ? 128 : 10; + + if(q != 0) + { + if((p - 1) % q != 0) + { + return false; + } + if(this->power_g_p(q) != 1) + { + return false; + } + if(!is_prime(q, rng, prob)) + { + return false; + } + } + + if(!is_prime(p, rng, prob)) + { + return false; + } + return true; + } + +/* +* Return the prime +*/ +const BigInt& DL_Group::get_p() const + { + return data().p(); + } + +/* +* Return the generator +*/ +const BigInt& DL_Group::get_g() const + { + return data().g(); + } + +/* +* Return the subgroup +*/ +const BigInt& DL_Group::get_q() const + { + return data().q(); + } + +std::shared_ptr DL_Group::monty_params_p() const + { + return data().monty_params_p(); + } + +size_t DL_Group::p_bits() const + { + return data().p_bits(); + } + +size_t DL_Group::p_bytes() const + { + return data().p_bytes(); + } + +size_t DL_Group::q_bits() const + { + data().assert_q_is_set("q_bits"); + return data().q_bits(); + } + +size_t DL_Group::estimated_strength() const + { + return data().estimated_strength(); + } + +size_t DL_Group::exponent_bits() const + { + return data().exponent_bits(); + } + +BigInt DL_Group::inverse_mod_p(const BigInt& x) const + { + // precompute?? + return inverse_mod(x, get_p()); + } + +BigInt DL_Group::mod_p(const BigInt& x) const + { + return data().mod_p(x); + } + +BigInt DL_Group::multiply_mod_p(const BigInt& x, const BigInt& y) const + { + return data().multiply_mod_p(x, y); + } + +BigInt DL_Group::inverse_mod_q(const BigInt& x) const + { + data().assert_q_is_set("inverse_mod_q"); + // precompute?? + return inverse_mod(x, get_q()); + } + +BigInt DL_Group::mod_q(const BigInt& x) const + { + data().assert_q_is_set("mod_q"); + return data().mod_q(x); + } + +BigInt DL_Group::multiply_mod_q(const BigInt& x, const BigInt& y) const + { + data().assert_q_is_set("multiply_mod_q"); + return data().multiply_mod_q(x, y); + } + +BigInt DL_Group::multiply_mod_q(const BigInt& x, const BigInt& y, const BigInt& z) const + { + data().assert_q_is_set("multiply_mod_q"); + return data().multiply_mod_q(data().multiply_mod_q(x, y), z); + } + +BigInt DL_Group::square_mod_q(const BigInt& x) const + { + data().assert_q_is_set("square_mod_q"); + return data().square_mod_q(x); + } + +BigInt DL_Group::multi_exponentiate(const BigInt& x, const BigInt& y, const BigInt& z) const + { + return monty_multi_exp(data().monty_params_p(), get_g(), x, y, z); + } + +BigInt DL_Group::power_g_p(const BigInt& x) const + { + return data().power_g_p(x, x.bits()); + } + +BigInt DL_Group::power_g_p(const BigInt& x, size_t max_x_bits) const + { + return data().power_g_p(x, max_x_bits); + } + +/* +* DER encode the parameters +*/ +std::vector DL_Group::DER_encode(Format format) const + { + if(get_q().is_zero() && (format == ANSI_X9_57 || format == ANSI_X9_42)) + throw Encoding_Error("Cannot encode DL_Group in ANSI formats when q param is missing"); + + std::vector output; + DER_Encoder der(output); + + if(format == ANSI_X9_57) + { + der.start_cons(SEQUENCE) + .encode(get_p()) + .encode(get_q()) + .encode(get_g()) + .end_cons(); + } + else if(format == ANSI_X9_42) + { + der.start_cons(SEQUENCE) + .encode(get_p()) + .encode(get_g()) + .encode(get_q()) + .end_cons(); + } + else if(format == PKCS_3) + { + der.start_cons(SEQUENCE) + .encode(get_p()) + .encode(get_g()) + .end_cons(); + } + else + throw Invalid_Argument("Unknown DL_Group encoding " + std::to_string(format)); + + return output; + } + +/* +* PEM encode the parameters +*/ +std::string DL_Group::PEM_encode(Format format) const + { + const std::vector encoding = DER_encode(format); + + if(format == PKCS_3) + return PEM_Code::encode(encoding, "DH PARAMETERS"); + else if(format == ANSI_X9_57) + return PEM_Code::encode(encoding, "DSA PARAMETERS"); + else if(format == ANSI_X9_42) + return PEM_Code::encode(encoding, "X9.42 DH PARAMETERS"); + else + throw Invalid_Argument("Unknown DL_Group encoding " + std::to_string(format)); + } + +DL_Group::DL_Group(const uint8_t ber[], size_t ber_len, Format format) + { + m_data = BER_decode_DL_group(ber, ber_len, format); + } + +void DL_Group::BER_decode(const std::vector& ber, Format format) + { + m_data = BER_decode_DL_group(ber.data(), ber.size(), format); + } + +/* +* Decode PEM encoded parameters +*/ +void DL_Group::PEM_decode(const std::string& pem) + { + std::string label; + const std::vector ber = unlock(PEM_Code::decode(pem, label)); + Format format = pem_label_to_dl_format(label); + + m_data = BER_decode_DL_group(ber.data(), ber.size(), format); + } + +//static +std::string DL_Group::PEM_for_named_group(const std::string& name) + { + DL_Group group(name); + DL_Group::Format format = group.get_q().is_zero() ? DL_Group::PKCS_3 : DL_Group::ANSI_X9_42; + return group.PEM_encode(format); + } + +} 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 new file mode 100644 index 0000000000..6bc9187613 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pubkey/dl_group/dl_group.h @@ -0,0 +1,332 @@ +/* +* Discrete Logarithm Group +* (C) 1999-2008,2018 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_DL_PARAM_H_ +#define BOTAN_DL_PARAM_H_ + +#include + +namespace Botan { + +class Montgomery_Params; +class DL_Group_Data; + +/** +* This class represents discrete logarithm groups. It holds a prime +* modulus p, a generator g, and (optionally) a prime q which is a +* factor of (p-1). In most cases g generates the order-q subgroup. +*/ +class BOTAN_PUBLIC_API(2,0) DL_Group final + { + public: + /** + * Determine the prime creation for DL groups. + */ + enum PrimeType { Strong, Prime_Subgroup, DSA_Kosherizer }; + + /** + * The DL group encoding format variants. + */ + enum Format { + ANSI_X9_42, + ANSI_X9_57, + PKCS_3, + + DSA_PARAMETERS = ANSI_X9_57, + DH_PARAMETERS = ANSI_X9_42, + ANSI_X9_42_DH_PARAMETERS = ANSI_X9_42, + PKCS3_DH_PARAMETERS = PKCS_3 + }; + + /** + * Construct a DL group with uninitialized internal value. + * Use this constructor is you wish to set the groups values + * from a DER or PEM encoded group. + */ + DL_Group() = default; + + /** + * Construct a DL group that is registered in the configuration. + * @param name the name that is configured in the global configuration + * for the desired group. If no configuration file is specified, + * the default values from the file policy.cpp will be used. For instance, + * use "modp/ietf/3072". + */ + DL_Group(const std::string& name); + + /** + * Create a new group randomly. + * @param rng the random number generator to use + * @param type specifies how the creation of primes p and q shall + * be performed. If type=Strong, then p will be determined as a + * safe prime, and q will be chosen as (p-1)/2. If + * type=Prime_Subgroup and qbits = 0, then the size of q will be + * determined according to the estimated difficulty of the DL + * problem. If type=DSA_Kosherizer, DSA primes will be created. + * @param pbits the number of bits of p + * @param qbits the number of bits of q. Leave it as 0 to have + * the value determined according to pbits. + */ + DL_Group(RandomNumberGenerator& rng, PrimeType type, + size_t pbits, size_t qbits = 0); + + /** + * Create a DSA group with a given seed. + * @param rng the random number generator to use + * @param seed the seed to use to create the random primes + * @param pbits the desired bit size of the prime p + * @param qbits the desired bit size of the prime q. + */ + DL_Group(RandomNumberGenerator& rng, + const std::vector& seed, + size_t pbits = 1024, size_t qbits = 0); + + /** + * Create a DL group. + * @param p the prime p + * @param g the base g + */ + DL_Group(const BigInt& p, const BigInt& g); + + /** + * Create a DL group. + * @param p the prime p + * @param q the prime q + * @param g the base g + */ + DL_Group(const BigInt& p, const BigInt& q, const BigInt& g); + + /** + * Decode a BER-encoded DL group param + */ + DL_Group(const uint8_t ber[], size_t ber_len, Format format); + + /** + * Decode a BER-encoded DL group param + */ + template + DL_Group(const std::vector& ber, Format format) : + DL_Group(ber.data(), ber.size(), format) {} + + /** + * Get the prime p. + * @return prime p + */ + const BigInt& get_p() const; + + /** + * Get the prime q, returns zero if q is not used + * @return prime q + */ + const BigInt& get_q() const; + + /** + * Get the base g. + * @return base g + */ + const BigInt& get_g() const; + + /** + * Perform validity checks on the group. + * @param rng the rng to use + * @param strong whether to perform stronger by lengthier tests + * @return true if the object is consistent, false otherwise + */ + bool verify_group(RandomNumberGenerator& rng, bool strong = true) const; + + /** + * Verify a public element, ie check if y = g^x for some x. + * + * This is not a perfect test. It verifies that 1 < y < p and (if q is set) + * that y is in the subgroup of size q. + */ + bool verify_public_element(const BigInt& y) const; + + /** + * Verify a pair of elements y = g^x + * + * This verifies that 1 < x,y < p and that y=g^x mod p + */ + bool verify_element_pair(const BigInt& y, const BigInt& x) const; + + /** + * Encode this group into a string using PEM encoding. + * @param format the encoding format + * @return string holding the PEM encoded group + */ + std::string PEM_encode(Format format) const; + + /** + * Encode this group into a string using DER encoding. + * @param format the encoding format + * @return string holding the DER encoded group + */ + std::vector DER_encode(Format format) const; + + /** + * Reduce an integer modulo p + * @return x % p + */ + BigInt mod_p(const BigInt& x) const; + + /** + * Multiply and reduce an integer modulo p + * @return (x*y) % p + */ + BigInt multiply_mod_p(const BigInt& x, const BigInt& y) const; + + /** + * Return the inverse of x mod p + */ + BigInt inverse_mod_p(const BigInt& x) const; + + /** + * Reduce an integer modulo q + * Throws if q is unset on this DL_Group + * @return x % q + */ + BigInt mod_q(const BigInt& x) const; + + /** + * Multiply and reduce an integer modulo q + * Throws if q is unset on this DL_Group + * @return (x*y) % q + */ + BigInt multiply_mod_q(const BigInt& x, const BigInt& y) const; + + /** + * Multiply and reduce an integer modulo q + * Throws if q is unset on this DL_Group + * @return (x*y*z) % q + */ + BigInt multiply_mod_q(const BigInt& x, const BigInt& y, const BigInt& z) const; + + /** + * Square and reduce an integer modulo q + * Throws if q is unset on this DL_Group + * @return (x*x) % q + */ + BigInt square_mod_q(const BigInt& x) const; + + /** + * Return the inverse of x mod q + * Throws if q is unset on this DL_Group + */ + BigInt inverse_mod_q(const BigInt& x) const; + + /** + * Modular exponentiation + * + * @warning this function leaks the size of x via the number of + * loop iterations. Use the version taking the maximum size to + * avoid this. + * + * @return (g^x) % p + */ + BigInt power_g_p(const BigInt& x) const; + + /** + * Modular exponentiation + * @param x the exponent + * @param max_x_bits x is assumed to be at most this many bits long. + * + * @return (g^x) % p + */ + BigInt power_g_p(const BigInt& x, size_t max_x_bits) const; + + /** + * Multi-exponentiate + * Return (g^x * y^z) % p + */ + BigInt multi_exponentiate(const BigInt& x, const BigInt& y, const BigInt& z) const; + + /** + * Return parameters for Montgomery reduction/exponentiation mod p + */ + std::shared_ptr monty_params_p() const; + + /** + * Return the size of p in bits + * Same as get_p().bits() + */ + size_t p_bits() const; + + /** + * Return the size of p in bytes + * Same as get_p().bytes() + */ + size_t p_bytes() const; + + /** + * Return the size of q in bits + * Same as get_q().bits() + * Throws if q is unset + */ + size_t q_bits() const; + + /** + * Return size in bits of a secret exponent + * + * This attempts to balance between the attack costs of NFS + * (which depends on the size of the modulus) and Pollard's rho + * (which depends on the size of the exponent). + * + * It may vary over time for a particular group, if the attack + * costs change. + */ + size_t exponent_bits() const; + + /** + * Return an estimate of the strength of this group against + * discrete logarithm attacks (eg NFS). Warning: since this only + * takes into account known attacks it is by necessity an + * overestimate of the actual strength. + */ + size_t estimated_strength() const; + + /** + * Decode a DER/BER encoded group into this instance. + * @param ber a vector containing the DER/BER encoded group + * @param format the format of the encoded group + */ + void BER_decode(const std::vector& ber, Format format); + + /** + * Decode a PEM encoded group into this instance. + * @param pem the PEM encoding of the group + */ + void PEM_decode(const std::string& pem); + + /** + * Return PEM representation of named DL group + */ + static std::string BOTAN_DEPRECATED("Use DL_Group(name).PEM_encode()") + PEM_for_named_group(const std::string& name); + + /* + * For internal use only + */ + static std::shared_ptr DL_group_info(const std::string& name); + + private: + static std::shared_ptr load_DL_group_info(const char* p_str, + const char* q_str, + const char* g_str); + + static std::shared_ptr load_DL_group_info(const char* p_str, + const char* g_str); + + static std::shared_ptr + BER_decode_DL_group(const uint8_t data[], size_t data_len, DL_Group::Format format); + + const DL_Group_Data& data() const; + std::shared_ptr m_data; + }; + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/dl_group/dl_named.cpp b/src/libs/3rdparty/botan/src/lib/pubkey/dl_group/dl_named.cpp new file mode 100644 index 0000000000..4d7b71bc1d --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pubkey/dl_group/dl_named.cpp @@ -0,0 +1,175 @@ +/* +* List of discrete log groups +* (C) 2013 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include + +namespace Botan { + +//static +std::shared_ptr DL_Group::DL_group_info(const std::string& name) + { + /* TLS FFDHE groups */ + + if(name == "ffdhe/ietf/2048") + { + return load_DL_group_info("0xFFFFFFFFFFFFFFFFADF85458A2BB4A9AAFDC5620273D3CF1D8B9C583CE2D3695A9E13641146433FBCC939DCE249B3EF97D2FE363630C75D8F681B202AEC4617AD3DF1ED5D5FD65612433F51F5F066ED0856365553DED1AF3B557135E7F57C935984F0C70E0E68B77E2A689DAF3EFE8721DF158A136ADE73530ACCA4F483A797ABC0AB182B324FB61D108A94BB2C8E3FBB96ADAB760D7F4681D4F42A3DE394DF4AE56EDE76372BB190B07A7C8EE0A6D709E02FCE1CDF7E2ECC03404CD28342F619172FE9CE98583FF8E4F1232EEF28183C3FE3B1B4C6FAD733BB5FCBC2EC22005C58EF1837D1683B2C6F34A26C1B2EFFA886B423861285C97FFFFFFFFFFFFFFFF", + "0x2"); + } + + if(name == "ffdhe/ietf/3072") + { + return load_DL_group_info("0xFFFFFFFFFFFFFFFFADF85458A2BB4A9AAFDC5620273D3CF1D8B9C583CE2D3695A9E13641146433FBCC939DCE249B3EF97D2FE363630C75D8F681B202AEC4617AD3DF1ED5D5FD65612433F51F5F066ED0856365553DED1AF3B557135E7F57C935984F0C70E0E68B77E2A689DAF3EFE8721DF158A136ADE73530ACCA4F483A797ABC0AB182B324FB61D108A94BB2C8E3FBB96ADAB760D7F4681D4F42A3DE394DF4AE56EDE76372BB190B07A7C8EE0A6D709E02FCE1CDF7E2ECC03404CD28342F619172FE9CE98583FF8E4F1232EEF28183C3FE3B1B4C6FAD733BB5FCBC2EC22005C58EF1837D1683B2C6F34A26C1B2EFFA886B4238611FCFDCDE355B3B6519035BBC34F4DEF99C023861B46FC9D6E6C9077AD91D2691F7F7EE598CB0FAC186D91CAEFE130985139270B4130C93BC437944F4FD4452E2D74DD364F2E21E71F54BFF5CAE82AB9C9DF69EE86D2BC522363A0DABC521979B0DEADA1DBF9A42D5C4484E0ABCD06BFA53DDEF3C1B20EE3FD59D7C25E41D2B66C62E37FFFFFFFFFFFFFFFF", + "0x2"); + } + + if(name == "ffdhe/ietf/4096") + { + return load_DL_group_info("0xFFFFFFFFFFFFFFFFADF85458A2BB4A9AAFDC5620273D3CF1D8B9C583CE2D3695A9E13641146433FBCC939DCE249B3EF97D2FE363630C75D8F681B202AEC4617AD3DF1ED5D5FD65612433F51F5F066ED0856365553DED1AF3B557135E7F57C935984F0C70E0E68B77E2A689DAF3EFE8721DF158A136ADE73530ACCA4F483A797ABC0AB182B324FB61D108A94BB2C8E3FBB96ADAB760D7F4681D4F42A3DE394DF4AE56EDE76372BB190B07A7C8EE0A6D709E02FCE1CDF7E2ECC03404CD28342F619172FE9CE98583FF8E4F1232EEF28183C3FE3B1B4C6FAD733BB5FCBC2EC22005C58EF1837D1683B2C6F34A26C1B2EFFA886B4238611FCFDCDE355B3B6519035BBC34F4DEF99C023861B46FC9D6E6C9077AD91D2691F7F7EE598CB0FAC186D91CAEFE130985139270B4130C93BC437944F4FD4452E2D74DD364F2E21E71F54BFF5CAE82AB9C9DF69EE86D2BC522363A0DABC521979B0DEADA1DBF9A42D5C4484E0ABCD06BFA53DDEF3C1B20EE3FD59D7C25E41D2B669E1EF16E6F52C3164DF4FB7930E9E4E58857B6AC7D5F42D69F6D187763CF1D5503400487F55BA57E31CC7A7135C886EFB4318AED6A1E012D9E6832A907600A918130C46DC778F971AD0038092999A333CB8B7A1A1DB93D7140003C2A4ECEA9F98D0ACC0A8291CDCEC97DCF8EC9B55A7F88A46B4DB5A851F44182E1C68A007E5E655F6AFFFFFFFFFFFFFFFF", + "0x2"); + } + + if(name == "ffdhe/ietf/6144") + { + return load_DL_group_info("0xFFFFFFFFFFFFFFFFADF85458A2BB4A9AAFDC5620273D3CF1D8B9C583CE2D3695A9E13641146433FBCC939DCE249B3EF97D2FE363630C75D8F681B202AEC4617AD3DF1ED5D5FD65612433F51F5F066ED0856365553DED1AF3B557135E7F57C935984F0C70E0E68B77E2A689DAF3EFE8721DF158A136ADE73530ACCA4F483A797ABC0AB182B324FB61D108A94BB2C8E3FBB96ADAB760D7F4681D4F42A3DE394DF4AE56EDE76372BB190B07A7C8EE0A6D709E02FCE1CDF7E2ECC03404CD28342F619172FE9CE98583FF8E4F1232EEF28183C3FE3B1B4C6FAD733BB5FCBC2EC22005C58EF1837D1683B2C6F34A26C1B2EFFA886B4238611FCFDCDE355B3B6519035BBC34F4DEF99C023861B46FC9D6E6C9077AD91D2691F7F7EE598CB0FAC186D91CAEFE130985139270B4130C93BC437944F4FD4452E2D74DD364F2E21E71F54BFF5CAE82AB9C9DF69EE86D2BC522363A0DABC521979B0DEADA1DBF9A42D5C4484E0ABCD06BFA53DDEF3C1B20EE3FD59D7C25E41D2B669E1EF16E6F52C3164DF4FB7930E9E4E58857B6AC7D5F42D69F6D187763CF1D5503400487F55BA57E31CC7A7135C886EFB4318AED6A1E012D9E6832A907600A918130C46DC778F971AD0038092999A333CB8B7A1A1DB93D7140003C2A4ECEA9F98D0ACC0A8291CDCEC97DCF8EC9B55A7F88A46B4DB5A851F44182E1C68A007E5E0DD9020BFD64B645036C7A4E677D2C38532A3A23BA4442CAF53EA63BB454329B7624C8917BDD64B1C0FD4CB38E8C334C701C3ACDAD0657FCCFEC719B1F5C3E4E46041F388147FB4CFDB477A52471F7A9A96910B855322EDB6340D8A00EF092350511E30ABEC1FFF9E3A26E7FB29F8C183023C3587E38DA0077D9B4763E4E4B94B2BBC194C6651E77CAF992EEAAC0232A281BF6B3A739C1226116820AE8DB5847A67CBEF9C9091B462D538CD72B03746AE77F5E62292C311562A846505DC82DB854338AE49F5235C95B91178CCF2DD5CACEF403EC9D1810C6272B045B3B71F9DC6B80D63FDD4A8E9ADB1E6962A69526D43161C1A41D570D7938DAD4A40E329CD0E40E65FFFFFFFFFFFFFFFF", + "0x2"); + } + + if(name == "ffdhe/ietf/8192") + { + return load_DL_group_info("0xFFFFFFFFFFFFFFFFADF85458A2BB4A9AAFDC5620273D3CF1D8B9C583CE2D3695A9E13641146433FBCC939DCE249B3EF97D2FE363630C75D8F681B202AEC4617AD3DF1ED5D5FD65612433F51F5F066ED0856365553DED1AF3B557135E7F57C935984F0C70E0E68B77E2A689DAF3EFE8721DF158A136ADE73530ACCA4F483A797ABC0AB182B324FB61D108A94BB2C8E3FBB96ADAB760D7F4681D4F42A3DE394DF4AE56EDE76372BB190B07A7C8EE0A6D709E02FCE1CDF7E2ECC03404CD28342F619172FE9CE98583FF8E4F1232EEF28183C3FE3B1B4C6FAD733BB5FCBC2EC22005C58EF1837D1683B2C6F34A26C1B2EFFA886B4238611FCFDCDE355B3B6519035BBC34F4DEF99C023861B46FC9D6E6C9077AD91D2691F7F7EE598CB0FAC186D91CAEFE130985139270B4130C93BC437944F4FD4452E2D74DD364F2E21E71F54BFF5CAE82AB9C9DF69EE86D2BC522363A0DABC521979B0DEADA1DBF9A42D5C4484E0ABCD06BFA53DDEF3C1B20EE3FD59D7C25E41D2B669E1EF16E6F52C3164DF4FB7930E9E4E58857B6AC7D5F42D69F6D187763CF1D5503400487F55BA57E31CC7A7135C886EFB4318AED6A1E012D9E6832A907600A918130C46DC778F971AD0038092999A333CB8B7A1A1DB93D7140003C2A4ECEA9F98D0ACC0A8291CDCEC97DCF8EC9B55A7F88A46B4DB5A851F44182E1C68A007E5E0DD9020BFD64B645036C7A4E677D2C38532A3A23BA4442CAF53EA63BB454329B7624C8917BDD64B1C0FD4CB38E8C334C701C3ACDAD0657FCCFEC719B1F5C3E4E46041F388147FB4CFDB477A52471F7A9A96910B855322EDB6340D8A00EF092350511E30ABEC1FFF9E3A26E7FB29F8C183023C3587E38DA0077D9B4763E4E4B94B2BBC194C6651E77CAF992EEAAC0232A281BF6B3A739C1226116820AE8DB5847A67CBEF9C9091B462D538CD72B03746AE77F5E62292C311562A846505DC82DB854338AE49F5235C95B91178CCF2DD5CACEF403EC9D1810C6272B045B3B71F9DC6B80D63FDD4A8E9ADB1E6962A69526D43161C1A41D570D7938DAD4A40E329CCFF46AAA36AD004CF600C8381E425A31D951AE64FDB23FCEC9509D43687FEB69EDD1CC5E0B8CC3BDF64B10EF86B63142A3AB8829555B2F747C932665CB2C0F1CC01BD70229388839D2AF05E454504AC78B7582822846C0BA35C35F5C59160CC046FD8251541FC68C9C86B022BB7099876A460E7451A8A93109703FEE1C217E6C3826E52C51AA691E0E423CFC99E9E31650C1217B624816CDAD9A95F9D5B8019488D9C0A0A1FE3075A577E23183F81D4A3F2FA4571EFC8CE0BA8A4FE8B6855DFE72B0A66EDED2FBABFBE58A30FAFABE1C5D71A87E2F741EF8C1FE86FEA6BBFDE530677F0D97D11D49F7A8443D0822E506A9F4614E011E2A94838FF88CD68C8BB7C5C6424CFFFFFFFFFFFFFFFF", + "0x2"); + } + + /* IETF IPsec groups */ + + if(name == "modp/ietf/1024") + { + return load_DL_group_info("0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF", + "0x2"); + } + + if(name == "modp/ietf/1536") + { + return load_DL_group_info("0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA237327FFFFFFFFFFFFFFFF", + "0x2"); + } + + if(name == "modp/ietf/2048") + { + return load_DL_group_info("0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF", + "0x2"); + } + + if(name == "modp/ietf/3072") + { + return load_DL_group_info("0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF", + "0x2"); + } + + if(name == "modp/ietf/4096") + { + return load_DL_group_info("0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199FFFFFFFFFFFFFFFF", + "0x2"); + } + + if(name == "modp/ietf/6144") + { + return load_DL_group_info("0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C93402849236C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BDF8FF9406AD9E530EE5DB382F413001AEB06A53ED9027D831179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1BDB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF5983CA01C64B92ECF032EA15D1721D03F482D7CE6E74FEF6D55E702F46980C82B5A84031900B1C9E59E7C97FBEC7E8F323A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AACC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE32806A1D58BB7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55CDA56C9EC2EF29632387FE8D76E3C0468043E8F663F4860EE12BF2D5B0B7474D6E694F91E6DCC4024FFFFFFFFFFFFFFFF", + "0x2"); + } + + if(name == "modp/ietf/8192") + { + return load_DL_group_info("0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C93402849236C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BDF8FF9406AD9E530EE5DB382F413001AEB06A53ED9027D831179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1BDB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF5983CA01C64B92ECF032EA15D1721D03F482D7CE6E74FEF6D55E702F46980C82B5A84031900B1C9E59E7C97FBEC7E8F323A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AACC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE32806A1D58BB7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55CDA56C9EC2EF29632387FE8D76E3C0468043E8F663F4860EE12BF2D5B0B7474D6E694F91E6DBE115974A3926F12FEE5E438777CB6A932DF8CD8BEC4D073B931BA3BC832B68D9DD300741FA7BF8AFC47ED2576F6936BA424663AAB639C5AE4F5683423B4742BF1C978238F16CBE39D652DE3FDB8BEFC848AD922222E04A4037C0713EB57A81A23F0C73473FC646CEA306B4BCBC8862F8385DDFA9D4B7FA2C087E879683303ED5BDD3A062B3CF5B3A278A66D2A13F83F44F82DDF310EE074AB6A364597E899A0255DC164F31CC50846851DF9AB48195DED7EA1B1D510BD7EE74D73FAF36BC31ECFA268359046F4EB879F924009438B481C6CD7889A002ED5EE382BC9190DA6FC026E479558E4475677E9AA9E3050E2765694DFC81F56E880B96E7160C980DD98EDD3DFFFFFFFFFFFFFFFFF", + "0x2"); + } + + /* SRP groups + + SRP groups have a p st (p-1)/2 is prime, but g is not a generator + of subgroup of size q, so set q == 0 to bypass generator check + + Missing q doesn't matter for SRP, and nothing but SRP should be + using these parameters. + */ + + if(name == "modp/srp/1024") + { + return load_DL_group_info("0xEEAF0AB9ADB38DD69C33F80AFA8FC5E86072618775FF3C0B9EA2314C9C256576D674DF7496EA81D3383B4813D692C6E0E0D5D8E250B98BE48E495C1D6089DAD15DC7D7B46154D6B6CE8EF4AD69B15D4982559B297BCF1885C529F566660E57EC68EDBC3C05726CC02FD4CBF4976EAA9AFD5138FE8376435B9FC61D2FC0EB06E3", + "0", + "0x2"); + } + + if(name == "modp/srp/1536") + { + return load_DL_group_info("0x9DEF3CAFB939277AB1F12A8617A47BBBDBA51DF499AC4C80BEEEA9614B19CC4D5F4F5F556E27CBDE51C6A94BE4607A291558903BA0D0F84380B655BB9A22E8DCDF028A7CEC67F0D08134B1C8B97989149B609E0BE3BAB63D47548381DBC5B1FC764E3F4B53DD9DA1158BFD3E2B9C8CF56EDF019539349627DB2FD53D24B7C48665772E437D6C7F8CE442734AF7CCB7AE837C264AE3A9BEB87F8A2FE9B8B5292E5A021FFF5E91479E8CE7A28C2442C6F315180F93499A234DCF76E3FED135F9BB", + "0", + "0x2"); + } + + if(name == "modp/srp/2048") + { + return load_DL_group_info("0xAC6BDB41324A9A9BF166DE5E1389582FAF72B6651987EE07FC3192943DB56050A37329CBB4A099ED8193E0757767A13DD52312AB4B03310DCD7F48A9DA04FD50E8083969EDB767B0CF6095179A163AB3661A05FBD5FAAAE82918A9962F0B93B855F97993EC975EEAA80D740ADBF4FF747359D041D5C33EA71D281E446B14773BCA97B43A23FB801676BD207A436C6481F1D2B9078717461A5B9D32E688F87748544523B524B0D57D5EA77A2775D2ECFA032CFBDBF52FB3786160279004E57AE6AF874E7303CE53299CCC041C7BC308D82A5698F3A8D0C38271AE35F8E9DBFBB694B5C803D89F7AE435DE236D525F54759B65E372FCD68EF20FA7111F9E4AFF73", + "0", + "0x2"); + } + + if(name == "modp/srp/3072") + { + return load_DL_group_info("0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF", + "0", + "0x5"); + } + + if(name == "modp/srp/4096") + { + return load_DL_group_info("0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199FFFFFFFFFFFFFFFF", + "0", + "0x5"); + } + + if(name == "modp/srp/6144") + { + return load_DL_group_info("0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C93402849236C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BDF8FF9406AD9E530EE5DB382F413001AEB06A53ED9027D831179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1BDB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF5983CA01C64B92ECF032EA15D1721D03F482D7CE6E74FEF6D55E702F46980C82B5A84031900B1C9E59E7C97FBEC7E8F323A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AACC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE32806A1D58BB7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55CDA56C9EC2EF29632387FE8D76E3C0468043E8F663F4860EE12BF2D5B0B7474D6E694F91E6DCC4024FFFFFFFFFFFFFFFF", + "0", + "0x5"); + } + + if(name == "modp/srp/8192") + { + return load_DL_group_info("0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C93402849236C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BDF8FF9406AD9E530EE5DB382F413001AEB06A53ED9027D831179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1BDB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF5983CA01C64B92ECF032EA15D1721D03F482D7CE6E74FEF6D55E702F46980C82B5A84031900B1C9E59E7C97FBEC7E8F323A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AACC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE32806A1D58BB7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55CDA56C9EC2EF29632387FE8D76E3C0468043E8F663F4860EE12BF2D5B0B7474D6E694F91E6DBE115974A3926F12FEE5E438777CB6A932DF8CD8BEC4D073B931BA3BC832B68D9DD300741FA7BF8AFC47ED2576F6936BA424663AAB639C5AE4F5683423B4742BF1C978238F16CBE39D652DE3FDB8BEFC848AD922222E04A4037C0713EB57A81A23F0C73473FC646CEA306B4BCBC8862F8385DDFA9D4B7FA2C087E879683303ED5BDD3A062B3CF5B3A278A66D2A13F83F44F82DDF310EE074AB6A364597E899A0255DC164F31CC50846851DF9AB48195DED7EA1B1D510BD7EE74D73FAF36BC31ECFA268359046F4EB879F924009438B481C6CD7889A002ED5EE382BC9190DA6FC026E479558E4475677E9AA9E3050E2765694DFC81F56E880B96E7160C980DD98EDD3DFFFFFFFFFFFFFFFFF", + "0", + "0x13"); + } + + /* DSA groups */ + + if(name == "dsa/jce/1024") + { + return load_DL_group_info("0xFD7F53811D75122952DF4A9C2EECE4E7F611B7523CEF4400C31E3F80B6512669455D402251FB593D8D58FABFC5F5BA30F6CB9B556CD7813B801D346FF26660B76B9950A5A49F9FE8047B1022C24FBBA9D7FEB7C61BF83B57E7C6A8A6150F04FB83F6D3C51EC3023554135A169132F675F3AE2B61D72AEFF22203199DD14801C7", + "0x9760508F15230BCCB292B982A2EB840BF0581CF5", + "0x469603512E30278CD3947595DB22EEC9826A6322ADC97344F41D740C325724C8F9EFBAA7D4D803FF8C609DCD100EBC5BDFCFAD7C6A425FAEA786EA2050EBE98351EA1FDA1FDF24D6947AA6B9AA23766953802F4D7D4A8ECBA06D19768A2491FFB16D0EF9C43A99B5F71672FF6F0A24B444D0736D04D38A1A1322DAF6CDD88C9D"); + } + + if(name == "dsa/botan/2048") + { + return load_DL_group_info("0x91C48A4FDFBCF7C02AE95E7DA126122B5DD2864F559B87E8E74A286D52F59BD1DE68DFD645D0E00C60C080031891980374EEB594A532BFD67B9A09EAC4B8663A07910E68F39465FB7040D25DF13932EBAC4347A530ECBA61C854F9B880D3C0C3660080587C45566DADE26BD5A394BE093B4C0F24B5AFFEF8EC6C5B3E57FB89025A9BC16769932131E16D3C94EFCAB18D0DF061203CC53E6103BC72D5594BFD40CA65380F44A9A851DCB075495FC033A8A58071A1BD78FE052F66555648EB4B719D2AFE8B4880F8DAD6F15818BA178F89274C870BE9B96EB08C46C40040CC2EFE1DFB1B1868DD319DE3C34A32A63AB6EB1224209A419680CC7902D1728D4DF9E1", + "0x8CD7D450F86F0AD94EEE4CE469A8756D1EBD1058241943EAFFB0B354585E924D", + "0xD9F5E0761B4DBD1833D6AB1A961A0996C5F22303F72D84C140F67C431D94AB5715BEA81A0C98D39CE4BCF78D6B9EBC895D34FE89D94091D5848615EF15F5E86F11D96F6C969E203DDFA58356420A49CB444B595B901A933CFE0767B594F18A07B7F91DECDBA446B88990F78F2FF91F2FE7CD43FD2E46D18EADA1F7BB6602C617F6EF3A4B284F2FD9BA10A36042DE8FA87A2CA36597FEC81157A1485E44041DF02830111CB880BBE6ED494814886F965CDC3135F5CCF1383728BF65B806F9692C0B10D6C4C09C75A6CA3B4013CB16AB2C105F6BE23AEA9000EAB2178985F972C98057E1C86E44E7218688EA4AE0F3636DCCA745C9DCD4E6AFFB67CCBC13D6131"); + } + + if(name == "dsa/botan/3072") + { + return load_DL_group_info("0xE4B50880759663585E142460CA2D9DFF132F8AE4C840DDA3A2666889124FE5638B84E8A29B7AF3FA1209BE6BFC4B5072ED3B2B7387BAF3F857F478A80228EF3600B76B3DCFB61D20D34465B2506D2CAF87DF6E7DC0CE91BD2D167A46F6ADCC31C531E4F9C7ABBDB92ADDF35B0A806C66292A5F5E17E964DD099903733AC428AB35D80EA6F685BFBA8BE4068E5418AE5ECAD9E8FF073DE2B63E4E7EAD35C8A9B70B5BD47CFB88D373B66F37931939B0AB71BD5595809086DA0155337D185A0E4FB36A519B1B6202B8591E6002449CF1CD3A66384F6D2073B1CD73BECA93BAF1E1A6117D0238F222AE1ED7FED185A890E7F67FAB8FEB9753CC134A5183DFE87AE2595F7B5C2D9FBB42249FDD59513E1D3396B3EB2FD86684F285A8448FE757A029881C40760B94EF919BDF9740C38389599EC51A6E9BB519A8E068491E9CE0A2FCFE3CB60D66CF0DFAD20A8EC684048684A61444575BD1724D7352B44A760077B3BD6BD385CE5B0A7250CC0BF768DA82923806EB9CFBB138843731B618208C759B", + "0xB3EBD364EC69EF8CF3BAF643B75734B16339B2E49E5CDE1B59C1E9FB40EE0C5B", + "0x2BED21EEF83964A230AE89BBA71D9F7C39C52FC8229B4E3BC7E5944D329DA10F010EAC9E7BAF6C009FC4EB2960723E2B56DF4663E4C3AC800E9258DE2F7649D206782893F865EFCA498D2EEF30074EA5E8A7AB262712A4D94A2F3B0B9A92EE400FB38A3CC59A5DC7E436D5C004B22E35028381B51C93407EB32D4AE0FD42CB45E12D0ECEE8A26238EDE2082A7B1522113C66CEF8D745C6CF3CB945F84D2F4DE16D44A71DE198270E13F03553C88B8D323AD0B948A1BF2103A949979B6ED16FB5F3C953D95B7C8E88CA67DCF5A636FB9CA39D924215F7A884ED6C7EE3C96D8D9715427974B7C4351282E13D3773F7D28B452F10892A13C7587328DEA4827B6B369B2A8DC172ADC583F51F2A6598C5483E5BC467B02F91D059C402D18E2C2680F776AA06F49280A2C72C17CC42D5B6E740C5C4B1AB3C51C2ED092BE2A2D8B053AE5773D1425ED2B08F06E2DD50592DF1A478C15591CDFD11564FF88FF38B721D42392FDA473212DCFD8D2D88A976A00AFFE6FFFB430A359E64CA2B351CA2412394"); + } + + return std::shared_ptr(); + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/dl_group/info.txt b/src/libs/3rdparty/botan/src/lib/pubkey/dl_group/info.txt new file mode 100644 index 0000000000..a73edb18c1 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pubkey/dl_group/info.txt @@ -0,0 +1,10 @@ + +DL_GROUP -> 20131128 + + + +asn1 +bigint +numbertheory +pem + diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/dsa/dsa.cpp b/src/libs/3rdparty/botan/src/lib/pubkey/dsa/dsa.cpp new file mode 100644 index 0000000000..35240292c1 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pubkey/dsa/dsa.cpp @@ -0,0 +1,218 @@ +/* +* DSA +* (C) 1999-2010,2014,2016 Jack Lloyd +* (C) 2016 René Korthaus +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include +#include + +#if defined(BOTAN_HAS_RFC6979_GENERATOR) + #include + #include +#endif + +namespace Botan { + +/* +* DSA_PublicKey Constructor +*/ +DSA_PublicKey::DSA_PublicKey(const DL_Group& grp, const BigInt& y1) + { + m_group = grp; + m_y = y1; + } + +/* +* Create a DSA private key +*/ +DSA_PrivateKey::DSA_PrivateKey(RandomNumberGenerator& rng, + const DL_Group& grp, + const BigInt& x_arg) + { + m_group = grp; + + if(x_arg == 0) + m_x = BigInt::random_integer(rng, 2, group_q()); + else + m_x = x_arg; + + m_y = m_group.power_g_p(m_x, m_group.q_bits()); + } + +DSA_PrivateKey::DSA_PrivateKey(const AlgorithmIdentifier& alg_id, + const secure_vector& key_bits) : + DL_Scheme_PrivateKey(alg_id, key_bits, DL_Group::ANSI_X9_57) + { + m_y = m_group.power_g_p(m_x, m_group.q_bits()); + } + +/* +* Check Private DSA Parameters +*/ +bool DSA_PrivateKey::check_key(RandomNumberGenerator& rng, bool strong) const + { + if(!DL_Scheme_PrivateKey::check_key(rng, strong) || m_x >= group_q()) + return false; + + if(!strong) + return true; + + return KeyPair::signature_consistency_check(rng, *this, "EMSA1(SHA-256)"); + } + +namespace { + +/** +* Object that can create a DSA signature +*/ +class DSA_Signature_Operation final : public PK_Ops::Signature_with_EMSA + { + public: + DSA_Signature_Operation(const DSA_PrivateKey& dsa, + const std::string& emsa, + RandomNumberGenerator& rng) : + PK_Ops::Signature_with_EMSA(emsa), + m_group(dsa.get_group()), + m_x(dsa.get_x()) + { +#if defined(BOTAN_HAS_RFC6979_GENERATOR) + m_rfc6979_hash = hash_for_emsa(emsa); +#endif + + m_b = BigInt::random_integer(rng, 2, dsa.group_q()); + m_b_inv = m_group.inverse_mod_q(m_b); + } + + size_t max_input_bits() const override { return m_group.get_q().bits(); } + + secure_vector raw_sign(const uint8_t msg[], size_t msg_len, + RandomNumberGenerator& rng) override; + private: + const DL_Group m_group; + const BigInt& m_x; +#if defined(BOTAN_HAS_RFC6979_GENERATOR) + std::string m_rfc6979_hash; +#endif + + BigInt m_b, m_b_inv; + }; + +secure_vector +DSA_Signature_Operation::raw_sign(const uint8_t msg[], size_t msg_len, + RandomNumberGenerator& rng) + { + const BigInt& q = m_group.get_q(); + + BigInt m(msg, msg_len, m_group.q_bits()); + + while(m >= q) + m -= q; + +#if defined(BOTAN_HAS_RFC6979_GENERATOR) + BOTAN_UNUSED(rng); + const BigInt k = generate_rfc6979_nonce(m_x, q, m, m_rfc6979_hash); +#else + const BigInt k = BigInt::random_integer(rng, 1, q); +#endif + + const BigInt k_inv = m_group.inverse_mod_q(k); + + const BigInt r = m_group.mod_q(m_group.power_g_p(k, m_group.q_bits())); + + /* + * Blind the input message and compute x*r+m as (x*r*b + m*b)/b + */ + m_b = m_group.square_mod_q(m_b); + m_b_inv = m_group.square_mod_q(m_b_inv); + + m = m_group.multiply_mod_q(m_b, m); + const BigInt xr = m_group.multiply_mod_q(m_b, m_x, r); + + const BigInt s = m_group.multiply_mod_q(m_b_inv, k_inv, m_group.mod_q(xr+m)); + + // With overwhelming probability, a bug rather than actual zero r/s + if(r.is_zero() || s.is_zero()) + throw Internal_Error("Computed zero r/s during DSA signature"); + + return BigInt::encode_fixed_length_int_pair(r, s, q.bytes()); + } + +/** +* Object that can verify a DSA signature +*/ +class DSA_Verification_Operation final : public PK_Ops::Verification_with_EMSA + { + public: + DSA_Verification_Operation(const DSA_PublicKey& dsa, + const std::string& emsa) : + PK_Ops::Verification_with_EMSA(emsa), + m_group(dsa.get_group()), + m_y(dsa.get_y()) + { + } + + size_t max_input_bits() const override { return m_group.get_q().bits(); } + + bool with_recovery() const override { return false; } + + bool verify(const uint8_t msg[], size_t msg_len, + const uint8_t sig[], size_t sig_len) override; + private: + const DL_Group m_group; + const BigInt& m_y; + }; + +bool DSA_Verification_Operation::verify(const uint8_t msg[], size_t msg_len, + const uint8_t sig[], size_t sig_len) + { + const BigInt& q = m_group.get_q(); + const size_t q_bytes = q.bytes(); + + if(sig_len != 2*q_bytes || msg_len > q_bytes) + return false; + + BigInt r(sig, q_bytes); + BigInt s(sig + q_bytes, q_bytes); + BigInt i(msg, msg_len, q.bits()); + + if(r <= 0 || r >= q || s <= 0 || s >= q) + return false; + + s = inverse_mod(s, q); + + const BigInt sr = m_group.multiply_mod_q(s, r); + const BigInt si = m_group.multiply_mod_q(s, i); + + s = m_group.multi_exponentiate(si, m_y, sr); + + return (m_group.mod_q(s) == r); + } + +} + +std::unique_ptr +DSA_PublicKey::create_verification_op(const std::string& params, + const std::string& provider) const + { + if(provider == "base" || provider.empty()) + return std::unique_ptr(new DSA_Verification_Operation(*this, params)); + throw Provider_Not_Found(algo_name(), provider); + } + +std::unique_ptr +DSA_PrivateKey::create_signature_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) const + { + if(provider == "base" || provider.empty()) + return std::unique_ptr(new DSA_Signature_Operation(*this, params, rng)); + throw Provider_Not_Found(algo_name(), provider); + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/dsa/dsa.h b/src/libs/3rdparty/botan/src/lib/pubkey/dsa/dsa.h new file mode 100644 index 0000000000..b219a1cf37 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pubkey/dsa/dsa.h @@ -0,0 +1,87 @@ +/* +* DSA +* (C) 1999-2010 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_DSA_H_ +#define BOTAN_DSA_H_ + +#include + +namespace Botan { + +/** +* DSA Public Key +*/ +class BOTAN_PUBLIC_API(2,0) DSA_PublicKey : public virtual DL_Scheme_PublicKey + { + public: + std::string algo_name() const override { return "DSA"; } + + DL_Group::Format group_format() const override { return DL_Group::ANSI_X9_57; } + size_t message_parts() const override { return 2; } + size_t message_part_size() const override { return group_q().bytes(); } + + /** + * Load a public key. + * @param alg_id the X.509 algorithm identifier + * @param key_bits DER encoded public key bits + */ + DSA_PublicKey(const AlgorithmIdentifier& alg_id, + const std::vector& key_bits) : + DL_Scheme_PublicKey(alg_id, key_bits, DL_Group::ANSI_X9_57) + { + } + + /** + * Create a public key. + * @param group the underlying DL group + * @param y the public value y = g^x mod p + */ + DSA_PublicKey(const DL_Group& group, const BigInt& y); + + std::unique_ptr + create_verification_op(const std::string& params, + const std::string& provider) const override; + protected: + DSA_PublicKey() = default; + }; + +/** +* DSA Private Key +*/ +class BOTAN_PUBLIC_API(2,0) DSA_PrivateKey final : public DSA_PublicKey, + public virtual DL_Scheme_PrivateKey + { + public: + /** + * Load a private key. + * @param alg_id the X.509 algorithm identifier + * @param key_bits DER encoded key bits in ANSI X9.57 format + */ + DSA_PrivateKey(const AlgorithmIdentifier& alg_id, + const secure_vector& key_bits); + + /** + * Create a private key. + * @param rng the RNG to use + * @param group the underlying DL group + * @param private_key the private key (if zero, a new random key is generated) + */ + DSA_PrivateKey(RandomNumberGenerator& rng, + const DL_Group& group, + const BigInt& private_key = 0); + + bool check_key(RandomNumberGenerator& rng, bool strong) const override; + + std::unique_ptr + create_signature_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) const override; + }; + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/dsa/info.txt b/src/libs/3rdparty/botan/src/lib/pubkey/dsa/info.txt new file mode 100644 index 0000000000..a9f288edea --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pubkey/dsa/info.txt @@ -0,0 +1,12 @@ + +DSA -> 20131128 + + + +dl_algo +dl_group +keypair +numbertheory +emsa1 +sha2_32 + diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/ec_group/curve_gfp.cpp b/src/libs/3rdparty/botan/src/lib/pubkey/ec_group/curve_gfp.cpp new file mode 100644 index 0000000000..bd68a3ed7d --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pubkey/ec_group/curve_gfp.cpp @@ -0,0 +1,576 @@ +/* +* Elliptic curves over GF(p) Montgomery Representation +* (C) 2014,2015,2018 Jack Lloyd +* 2016 Matthias Gierlings +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include +#include +#include + +namespace Botan { + +namespace { + +class CurveGFp_Montgomery final : public CurveGFp_Repr + { + public: + CurveGFp_Montgomery(const BigInt& p, const BigInt& a, const BigInt& b) : + m_p(p), m_a(a), m_b(b), + m_p_words(m_p.sig_words()), + m_p_dash(monty_inverse(m_p.word_at(0))) + { + Modular_Reducer mod_p(m_p); + + m_r.set_bit(m_p_words * BOTAN_MP_WORD_BITS); + m_r = mod_p.reduce(m_r); + + m_r2 = mod_p.square(m_r); + m_r3 = mod_p.multiply(m_r, m_r2); + m_a_r = mod_p.multiply(m_r, m_a); + m_b_r = mod_p.multiply(m_r, m_b); + + m_a_is_zero = m_a.is_zero(); + m_a_is_minus_3 = (m_a + 3 == m_p); + } + + bool a_is_zero() const override { return m_a_is_zero; } + bool a_is_minus_3() const override { return m_a_is_minus_3; } + + const BigInt& get_a() const override { return m_a; } + + const BigInt& get_b() const override { return m_b; } + + const BigInt& get_p() const override { return m_p; } + + const BigInt& get_a_rep() const override { return m_a_r; } + + const BigInt& get_b_rep() const override { return m_b_r; } + + const BigInt& get_1_rep() const override { return m_r; } + + bool is_one(const BigInt& x) const override { return x == m_r; } + + size_t get_p_words() const override { return m_p_words; } + + size_t get_ws_size() const override { return 2*m_p_words + 4; } + + void redc_mod_p(BigInt& z, secure_vector& ws) const override; + + BigInt invert_element(const BigInt& x, secure_vector& ws) const override; + + void to_curve_rep(BigInt& x, secure_vector& ws) const override; + + void from_curve_rep(BigInt& x, secure_vector& ws) const override; + + void curve_mul_words(BigInt& z, + const word x_words[], + const size_t x_size, + const BigInt& y, + secure_vector& ws) const override; + + void curve_sqr_words(BigInt& z, + const word x_words[], + size_t x_size, + secure_vector& ws) const override; + + private: + BigInt m_p; + BigInt m_a, m_b; + BigInt m_a_r, m_b_r; + size_t m_p_words; // cache of m_p.sig_words() + + // Montgomery parameters + BigInt m_r, m_r2, m_r3; + word m_p_dash; + + bool m_a_is_zero; + bool m_a_is_minus_3; + }; + +void CurveGFp_Montgomery::redc_mod_p(BigInt& z, secure_vector& ws) const + { + z.reduce_below(m_p, ws); + } + +BigInt CurveGFp_Montgomery::invert_element(const BigInt& x, secure_vector& ws) const + { + // Should we use Montgomery inverse instead? + const BigInt inv = inverse_mod(x, m_p); + BigInt res; + curve_mul(res, inv, m_r3, ws); + return res; + } + +void CurveGFp_Montgomery::to_curve_rep(BigInt& x, secure_vector& ws) const + { + const BigInt tx = x; + curve_mul(x, tx, m_r2, ws); + } + +void CurveGFp_Montgomery::from_curve_rep(BigInt& z, secure_vector& ws) const + { + if(ws.size() < get_ws_size()) + ws.resize(get_ws_size()); + + const size_t output_size = 2*m_p_words + 2; + if(z.size() < output_size) + z.grow_to(output_size); + + bigint_monty_redc(z.mutable_data(), + m_p.data(), m_p_words, m_p_dash, + ws.data(), ws.size()); + } + +void CurveGFp_Montgomery::curve_mul_words(BigInt& z, + const word x_w[], + size_t x_size, + const BigInt& y, + secure_vector& ws) const + { + BOTAN_DEBUG_ASSERT(y.sig_words() <= m_p_words); + + if(ws.size() < get_ws_size()) + ws.resize(get_ws_size()); + + const size_t output_size = 2*m_p_words + 2; + if(z.size() < output_size) + z.grow_to(output_size); + + bigint_mul(z.mutable_data(), z.size(), + x_w, x_size, std::min(m_p_words, x_size), + y.data(), y.size(), std::min(m_p_words, y.size()), + ws.data(), ws.size()); + + bigint_monty_redc(z.mutable_data(), + m_p.data(), m_p_words, m_p_dash, + ws.data(), ws.size()); + } + +void CurveGFp_Montgomery::curve_sqr_words(BigInt& z, + const word x[], + size_t x_size, + secure_vector& ws) const + { + if(ws.size() < get_ws_size()) + ws.resize(get_ws_size()); + + const size_t output_size = 2*m_p_words + 2; + if(z.size() < output_size) + z.grow_to(output_size); + + bigint_sqr(z.mutable_data(), z.size(), + x, x_size, std::min(m_p_words, x_size), + ws.data(), ws.size()); + + bigint_monty_redc(z.mutable_data(), + m_p.data(), m_p_words, m_p_dash, + ws.data(), ws.size()); + } + +class CurveGFp_NIST : public CurveGFp_Repr + { + public: + CurveGFp_NIST(size_t p_bits, const BigInt& a, const BigInt& b) : + m_1(1), m_a(a), m_b(b), m_p_words((p_bits + BOTAN_MP_WORD_BITS - 1) / BOTAN_MP_WORD_BITS) + { + // All Solinas prime curves are assumed a == -3 + } + + bool a_is_zero() const override { return false; } + bool a_is_minus_3() const override { return true; } + + const BigInt& get_a() const override { return m_a; } + + const BigInt& get_b() const override { return m_b; } + + const BigInt& get_1_rep() const override { return m_1; } + + size_t get_p_words() const override { return m_p_words; } + + size_t get_ws_size() const override { return 2*m_p_words + 4; } + + const BigInt& get_a_rep() const override { return m_a; } + + const BigInt& get_b_rep() const override { return m_b; } + + bool is_one(const BigInt& x) const override { return x == 1; } + + void to_curve_rep(BigInt& x, secure_vector& ws) const override + { redc_mod_p(x, ws); } + + void from_curve_rep(BigInt& x, secure_vector& ws) const override + { redc_mod_p(x, ws); } + + BigInt invert_element(const BigInt& x, secure_vector& ws) const override; + + void curve_mul_words(BigInt& z, + const word x_words[], + const size_t x_size, + const BigInt& y, + secure_vector& ws) const override; + + void curve_mul_tmp(BigInt& x, const BigInt& y, BigInt& tmp, secure_vector& ws) const + { + curve_mul(tmp, x, y, ws); + x.swap(tmp); + } + + void curve_sqr_tmp(BigInt& x, BigInt& tmp, secure_vector& ws) const + { + curve_sqr(tmp, x, ws); + x.swap(tmp); + } + + void curve_sqr_words(BigInt& z, + const word x_words[], + size_t x_size, + secure_vector& ws) const override; + private: + // Curve parameters + BigInt m_1; + BigInt m_a, m_b; + size_t m_p_words; // cache of m_p.sig_words() + }; + +BigInt CurveGFp_NIST::invert_element(const BigInt& x, secure_vector& ws) const + { + BOTAN_UNUSED(ws); + return inverse_mod(x, get_p()); + } + +void CurveGFp_NIST::curve_mul_words(BigInt& z, + const word x_w[], + size_t x_size, + const BigInt& y, + secure_vector& ws) const + { + BOTAN_DEBUG_ASSERT(y.sig_words() <= m_p_words); + + if(ws.size() < get_ws_size()) + ws.resize(get_ws_size()); + + const size_t output_size = 2*m_p_words + 2; + if(z.size() < output_size) + z.grow_to(output_size); + + bigint_mul(z.mutable_data(), z.size(), + x_w, x_size, std::min(m_p_words, x_size), + y.data(), y.size(), std::min(m_p_words, y.size()), + ws.data(), ws.size()); + + this->redc_mod_p(z, ws); + } + +void CurveGFp_NIST::curve_sqr_words(BigInt& z, const word x[], size_t x_size, + secure_vector& ws) const + { + if(ws.size() < get_ws_size()) + ws.resize(get_ws_size()); + + const size_t output_size = 2*m_p_words + 2; + if(z.size() < output_size) + z.grow_to(output_size); + + bigint_sqr(z.mutable_data(), output_size, + x, x_size, std::min(m_p_words, x_size), + ws.data(), ws.size()); + + this->redc_mod_p(z, ws); + } + +#if defined(BOTAN_HAS_NIST_PRIME_REDUCERS_W32) + +/** +* The NIST P-192 curve +*/ +class CurveGFp_P192 final : public CurveGFp_NIST + { + public: + CurveGFp_P192(const BigInt& a, const BigInt& b) : CurveGFp_NIST(192, a, b) {} + const BigInt& get_p() const override { return prime_p192(); } + private: + void redc_mod_p(BigInt& x, secure_vector& ws) const override { redc_p192(x, ws); } + }; + +/** +* The NIST P-224 curve +*/ +class CurveGFp_P224 final : public CurveGFp_NIST + { + public: + CurveGFp_P224(const BigInt& a, const BigInt& b) : CurveGFp_NIST(224, a, b) {} + const BigInt& get_p() const override { return prime_p224(); } + private: + void redc_mod_p(BigInt& x, secure_vector& ws) const override { redc_p224(x, ws); } + }; + +/** +* The NIST P-256 curve +*/ +class CurveGFp_P256 final : public CurveGFp_NIST + { + public: + CurveGFp_P256(const BigInt& a, const BigInt& b) : CurveGFp_NIST(256, a, b) {} + const BigInt& get_p() const override { return prime_p256(); } + private: + void redc_mod_p(BigInt& x, secure_vector& ws) const override { redc_p256(x, ws); } + BigInt invert_element(const BigInt& x, secure_vector& ws) const override; + }; + +BigInt CurveGFp_P256::invert_element(const BigInt& x, secure_vector& ws) const + { + BigInt r, p2, p4, p8, p16, p32, tmp; + + curve_sqr(r, x, ws); + + curve_mul(p2, r, x, ws); + curve_sqr(r, p2, ws); + curve_sqr_tmp(r, tmp, ws); + + curve_mul(p4, r, p2, ws); + + curve_sqr(r, p4, ws); + for(size_t i = 0; i != 3; ++i) + curve_sqr_tmp(r, tmp, ws); + curve_mul(p8, r, p4, ws);; + + curve_sqr(r, p8, ws); + for(size_t i = 0; i != 7; ++i) + curve_sqr_tmp(r, tmp, ws); + curve_mul(p16, r, p8, ws); + + curve_sqr(r, p16, ws); + for(size_t i = 0; i != 15; ++i) + curve_sqr_tmp(r, tmp, ws); + curve_mul(p32, r, p16, ws); + + curve_sqr(r, p32, ws); + for(size_t i = 0; i != 31; ++i) + curve_sqr_tmp(r, tmp, ws); + curve_mul_tmp(r, x, tmp, ws); + + for(size_t i = 0; i != 32*4; ++i) + curve_sqr_tmp(r, tmp, ws); + curve_mul_tmp(r, p32, tmp, ws); + + for(size_t i = 0; i != 32; ++i) + curve_sqr_tmp(r, tmp, ws); + curve_mul_tmp(r, p32, tmp, ws); + + for(size_t i = 0; i != 16; ++i) + curve_sqr_tmp(r, tmp, ws); + curve_mul_tmp(r, p16, tmp, ws); + for(size_t i = 0; i != 8; ++i) + curve_sqr_tmp(r, tmp, ws); + curve_mul_tmp(r, p8, tmp, ws); + + for(size_t i = 0; i != 4; ++i) + curve_sqr_tmp(r, tmp, ws); + curve_mul_tmp(r, p4, tmp, ws); + + for(size_t i = 0; i != 2; ++i) + curve_sqr_tmp(r, tmp, ws); + curve_mul_tmp(r, p2, tmp, ws); + + for(size_t i = 0; i != 2; ++i) + curve_sqr_tmp(r, tmp, ws); + curve_mul_tmp(r, x, tmp, ws); + + return r; + } + +/** +* The NIST P-384 curve +*/ +class CurveGFp_P384 final : public CurveGFp_NIST + { + public: + CurveGFp_P384(const BigInt& a, const BigInt& b) : CurveGFp_NIST(384, a, b) {} + const BigInt& get_p() const override { return prime_p384(); } + private: + void redc_mod_p(BigInt& x, secure_vector& ws) const override { redc_p384(x, ws); } + BigInt invert_element(const BigInt& x, secure_vector& ws) const override; + }; + +BigInt CurveGFp_P384::invert_element(const BigInt& x, secure_vector& ws) const + { + BigInt r, x2, x3, x15, x30, tmp, rl; + + r = x; + curve_sqr_tmp(r, tmp, ws); + curve_mul_tmp(r, x, tmp, ws); + x2 = r; + + curve_sqr_tmp(r, tmp, ws); + curve_mul_tmp(r, x, tmp, ws); + + x3 = r; + + for(size_t i = 0; i != 3; ++i) + curve_sqr_tmp(r, tmp, ws); + curve_mul_tmp(r, x3, tmp, ws); + + rl = r; + for(size_t i = 0; i != 6; ++i) + curve_sqr_tmp(r, tmp, ws); + curve_mul_tmp(r, rl, tmp, ws); + + for(size_t i = 0; i != 3; ++i) + curve_sqr_tmp(r, tmp, ws); + curve_mul_tmp(r, x3, tmp, ws); + + x15 = r; + for(size_t i = 0; i != 15; ++i) + curve_sqr_tmp(r, tmp, ws); + curve_mul_tmp(r, x15, tmp, ws); + + x30 = r; + for(size_t i = 0; i != 30; ++i) + curve_sqr_tmp(r, tmp, ws); + curve_mul_tmp(r, x30, tmp, ws); + + rl = r; + for(size_t i = 0; i != 60; ++i) + curve_sqr_tmp(r, tmp, ws); + curve_mul_tmp(r, rl, tmp, ws); + + rl = r; + for(size_t i = 0; i != 120; ++i) + curve_sqr_tmp(r, tmp, ws); + curve_mul_tmp(r, rl, tmp, ws); + + for(size_t i = 0; i != 15; ++i) + curve_sqr_tmp(r, tmp, ws); + curve_mul_tmp(r, x15, tmp, ws); + + for(size_t i = 0; i != 31; ++i) + curve_sqr_tmp(r, tmp, ws); + curve_mul_tmp(r, x30, tmp, ws); + + for(size_t i = 0; i != 2; ++i) + curve_sqr_tmp(r, tmp, ws); + curve_mul_tmp(r, x2, tmp, ws); + + for(size_t i = 0; i != 94; ++i) + curve_sqr_tmp(r, tmp, ws); + curve_mul_tmp(r, x30, tmp, ws); + + for(size_t i = 0; i != 2; ++i) + curve_sqr_tmp(r, tmp, ws); + + curve_mul_tmp(r, x, tmp, ws); + + return r; + } + +#endif + +/** +* The NIST P-521 curve +*/ +class CurveGFp_P521 final : public CurveGFp_NIST + { + public: + CurveGFp_P521(const BigInt& a, const BigInt& b) : CurveGFp_NIST(521, a, b) {} + const BigInt& get_p() const override { return prime_p521(); } + private: + void redc_mod_p(BigInt& x, secure_vector& ws) const override { redc_p521(x, ws); } + BigInt invert_element(const BigInt& x, secure_vector& ws) const override; + }; + +BigInt CurveGFp_P521::invert_element(const BigInt& x, secure_vector& ws) const + { + BigInt r; + BigInt rl; + BigInt a7; + BigInt tmp; + + curve_sqr(r, x, ws); + curve_mul_tmp(r, x, tmp, ws); + + curve_sqr_tmp(r, tmp, ws); + curve_mul_tmp(r, x, tmp, ws); + + rl = r; + + for(size_t i = 0; i != 3; ++i) + curve_sqr_tmp(r, tmp, ws); + curve_mul_tmp(r, rl, tmp, ws); + + curve_sqr_tmp(r, tmp, ws); + curve_mul_tmp(r, x, tmp, ws); + a7 = r; // need this value later + + curve_sqr_tmp(r, tmp, ws); + curve_mul_tmp(r, x, tmp, ws); + + rl = r; + for(size_t i = 0; i != 8; ++i) + curve_sqr_tmp(r, tmp, ws); + curve_mul_tmp(r, rl, tmp, ws); + + rl = r; + for(size_t i = 0; i != 16; ++i) + curve_sqr_tmp(r, tmp, ws); + curve_mul_tmp(r, rl, tmp, ws); + + rl = r; + for(size_t i = 0; i != 32; ++i) + curve_sqr_tmp(r, tmp, ws); + curve_mul_tmp(r, rl, tmp, ws); + + rl = r; + for(size_t i = 0; i != 64; ++i) + curve_sqr_tmp(r, tmp, ws); + curve_mul_tmp(r, rl, tmp, ws); + + rl = r; + for(size_t i = 0; i != 128; ++i) + curve_sqr_tmp(r, tmp, ws); + curve_mul_tmp(r, rl, tmp, ws); + + rl = r; + for(size_t i = 0; i != 256; ++i) + curve_sqr_tmp(r, tmp, ws); + curve_mul_tmp(r, rl, tmp, ws); + + for(size_t i = 0; i != 7; ++i) + curve_sqr_tmp(r, tmp, ws); + curve_mul_tmp(r, a7, tmp, ws); + + for(size_t i = 0; i != 2; ++i) + curve_sqr_tmp(r, tmp, ws); + curve_mul_tmp(r, x, tmp, ws); + + return r; + } + +} + +std::shared_ptr +CurveGFp::choose_repr(const BigInt& p, const BigInt& a, const BigInt& b) + { +#if defined(BOTAN_HAS_NIST_PRIME_REDUCERS_W32) + if(p == prime_p192()) + return std::shared_ptr(new CurveGFp_P192(a, b)); + if(p == prime_p224()) + return std::shared_ptr(new CurveGFp_P224(a, b)); + if(p == prime_p256()) + return std::shared_ptr(new CurveGFp_P256(a, b)); + if(p == prime_p384()) + return std::shared_ptr(new CurveGFp_P384(a, b)); +#endif + + if(p == prime_p521()) + return std::shared_ptr(new CurveGFp_P521(a, b)); + + return std::shared_ptr(new CurveGFp_Montgomery(p, a, b)); + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/ec_group/curve_gfp.h b/src/libs/3rdparty/botan/src/lib/pubkey/ec_group/curve_gfp.h new file mode 100644 index 0000000000..ce3fe4eba8 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pubkey/ec_group/curve_gfp.h @@ -0,0 +1,269 @@ +/* +* Elliptic curves over GF(p) +* +* (C) 2007 Martin Doering, Christoph Ludwig, Falko Strenzke +* 2010-2011,2012,2014 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_GFP_CURVE_H_ +#define BOTAN_GFP_CURVE_H_ + +#include +#include + +namespace Botan { + +class BOTAN_UNSTABLE_API CurveGFp_Repr + { + public: + virtual ~CurveGFp_Repr() = default; + + virtual const BigInt& get_p() const = 0; + virtual const BigInt& get_a() const = 0; + virtual const BigInt& get_b() const = 0; + + virtual size_t get_p_words() const = 0; + + virtual size_t get_ws_size() const = 0; + + virtual bool is_one(const BigInt& x) const = 0; + + virtual bool a_is_zero() const = 0; + + virtual bool a_is_minus_3() const = 0; + + /* + * Returns to_curve_rep(get_a()) + */ + virtual const BigInt& get_a_rep() const = 0; + + /* + * Returns to_curve_rep(get_b()) + */ + virtual const BigInt& get_b_rep() const = 0; + + /* + * Returns to_curve_rep(1) + */ + virtual const BigInt& get_1_rep() const = 0; + + virtual void redc_mod_p(BigInt& z, secure_vector& ws) const = 0; + + virtual BigInt invert_element(const BigInt& x, secure_vector& ws) const = 0; + + virtual void to_curve_rep(BigInt& x, secure_vector& ws) const = 0; + + virtual void from_curve_rep(BigInt& x, secure_vector& ws) const = 0; + + void curve_mul(BigInt& z, const BigInt& x, const BigInt& y, + secure_vector& ws) const + { + BOTAN_DEBUG_ASSERT(x.sig_words() <= m_p_words); + curve_mul_words(z, x.data(), x.size(), y, ws); + } + + virtual void curve_mul_words(BigInt& z, + const word x_words[], + const size_t x_size, + const BigInt& y, + secure_vector& ws) const = 0; + + void curve_sqr(BigInt& z, const BigInt& x, + secure_vector& ws) const + { + BOTAN_DEBUG_ASSERT(x.sig_words() <= m_p_words); + curve_sqr_words(z, x.data(), x.size(), ws); + } + + virtual void curve_sqr_words(BigInt& z, + const word x_words[], + size_t x_size, + secure_vector& ws) const = 0; + }; + +/** +* This class represents an elliptic curve over GF(p) +* +* There should not be any reason for applications to use this type. +* If you need EC primitives use the interfaces EC_Group and PointGFp +* +* It is likely this class will be removed entirely in a future major +* release. +*/ +class BOTAN_UNSTABLE_API CurveGFp final + { + public: + + /** + * Create an uninitialized CurveGFp + */ + CurveGFp() = default; + + /** + * Construct the elliptic curve E: y^2 = x^3 + ax + b over GF(p) + * @param p prime number of the field + * @param a first coefficient + * @param b second coefficient + */ + CurveGFp(const BigInt& p, const BigInt& a, const BigInt& b) : + m_repr(choose_repr(p, a, b)) + { + } + + CurveGFp(const CurveGFp&) = default; + + CurveGFp& operator=(const CurveGFp&) = default; + + /** + * @return curve coefficient a + */ + const BigInt& get_a() const { return m_repr->get_a(); } + + /** + * @return curve coefficient b + */ + const BigInt& get_b() const { return m_repr->get_b(); } + + /** + * Get prime modulus of the field of the curve + * @return prime modulus of the field of the curve + */ + const BigInt& get_p() const { return m_repr->get_p(); } + + size_t get_p_words() const { return m_repr->get_p_words(); } + + size_t get_ws_size() const { return m_repr->get_ws_size(); } + + const BigInt& get_a_rep() const { return m_repr->get_a_rep(); } + + const BigInt& get_b_rep() const { return m_repr->get_b_rep(); } + + const BigInt& get_1_rep() const { return m_repr->get_1_rep(); } + + bool a_is_minus_3() const { return m_repr->a_is_minus_3(); } + bool a_is_zero() const { return m_repr->a_is_zero(); } + + bool is_one(const BigInt& x) const { return m_repr->is_one(x); } + + BigInt invert_element(const BigInt& x, secure_vector& ws) const + { + return m_repr->invert_element(x, ws); + } + + void to_rep(BigInt& x, secure_vector& ws) const + { + m_repr->to_curve_rep(x, ws); + } + + void from_rep(BigInt& x, secure_vector& ws) const + { + m_repr->from_curve_rep(x, ws); + } + + BigInt from_rep(const BigInt& x, secure_vector& ws) const + { + BigInt xt(x); + m_repr->from_curve_rep(xt, ws); + return xt; + } + + // TODO: from_rep taking && ref + + void redc_mod_p(BigInt& z, secure_vector& ws) const + { + m_repr->redc_mod_p(z, ws); + } + + void mul(BigInt& z, const BigInt& x, const BigInt& y, secure_vector& ws) const + { + m_repr->curve_mul(z, x, y, ws); + } + + void mul(BigInt& z, const word x_w[], size_t x_size, + const BigInt& y, secure_vector& ws) const + { + m_repr->curve_mul_words(z, x_w, x_size, y, ws); + } + + void sqr(BigInt& z, const BigInt& x, secure_vector& ws) const + { + m_repr->curve_sqr(z, x, ws); + } + + void sqr(BigInt& z, const word x_w[], size_t x_size, secure_vector& ws) const + { + m_repr->curve_sqr_words(z, x_w, x_size, ws); + } + + BigInt mul(const BigInt& x, const BigInt& y, secure_vector& ws) const + { + return mul_to_tmp(x, y, ws); + } + + BigInt sqr(const BigInt& x, secure_vector& ws) const + { + return sqr_to_tmp(x, ws); + } + + BigInt mul_to_tmp(const BigInt& x, const BigInt& y, secure_vector& ws) const + { + BigInt z; + m_repr->curve_mul(z, x, y, ws); + return z; + } + + BigInt sqr_to_tmp(const BigInt& x, secure_vector& ws) const + { + BigInt z; + m_repr->curve_sqr(z, x, ws); + return z; + } + + void swap(CurveGFp& other) + { + std::swap(m_repr, other.m_repr); + } + + /** + * Equality operator + * @param other a curve + * @return true iff *this is the same as other + */ + inline bool operator==(const CurveGFp& other) const + { + if(m_repr.get() == other.m_repr.get()) + return true; + + return (get_p() == other.get_p()) && + (get_a() == other.get_a()) && + (get_b() == other.get_b()); + } + + private: + static std::shared_ptr + choose_repr(const BigInt& p, const BigInt& a, const BigInt& b); + + std::shared_ptr m_repr; + }; + +inline bool operator!=(const CurveGFp& lhs, const CurveGFp& rhs) + { + return !(lhs == rhs); + } + +} + +namespace std { + +template<> inline +void swap(Botan::CurveGFp& curve1, + Botan::CurveGFp& curve2) BOTAN_NOEXCEPT + { + curve1.swap(curve2); + } + +} // namespace std + +#endif 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 new file mode 100644 index 0000000000..586603507e --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pubkey/ec_group/ec_group.cpp @@ -0,0 +1,765 @@ +/* +* ECC Domain Parameters +* +* (C) 2007 Falko Strenzke, FlexSecure GmbH +* (C) 2008,2018 Jack Lloyd +* (C) 2018 Tobias Niemann +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(BOTAN_HAS_SYSTEM_RNG) + #include +#elif defined(BOTAN_HAS_HMAC_DRBG) && defined(BOTAN_HAS_SHA2_32) + #include +#endif + +namespace Botan { + +class EC_Group_Data final + { + public: + + EC_Group_Data(const BigInt& p, + const BigInt& a, + const BigInt& b, + const BigInt& g_x, + const BigInt& g_y, + const BigInt& order, + const BigInt& cofactor, + const OID& oid) : + m_curve(p, a, b), + m_base_point(m_curve, g_x, g_y), + m_g_x(g_x), + m_g_y(g_y), + m_order(order), + m_cofactor(cofactor), + m_mod_order(order), + m_base_mult(m_base_point, m_mod_order), + m_oid(oid), + m_p_bits(p.bits()), + m_order_bits(order.bits()), + m_a_is_minus_3(a == p - 3), + m_a_is_zero(a.is_zero()) + { + } + + bool match(const BigInt& p, const BigInt& a, const BigInt& b, + const BigInt& g_x, const BigInt& g_y, + const BigInt& order, const BigInt& cofactor) const + { + return (this->p() == p && + this->a() == a && + this->b() == b && + this->order() == order && + this->cofactor() == cofactor && + this->g_x() == g_x && + this->g_y() == g_y); + } + + const OID& oid() const { return m_oid; } + const BigInt& p() const { return m_curve.get_p(); } + const BigInt& a() const { return m_curve.get_a(); } + const BigInt& b() const { return m_curve.get_b(); } + const BigInt& order() const { return m_order; } + const BigInt& cofactor() const { return m_cofactor; } + const BigInt& g_x() const { return m_g_x; } + const BigInt& g_y() const { return m_g_y; } + + size_t p_bits() const { return m_p_bits; } + size_t p_bytes() const { return (m_p_bits + 7) / 8; } + + size_t order_bits() const { return m_order_bits; } + size_t order_bytes() const { return (m_order_bits + 7) / 8; } + + const CurveGFp& curve() const { return m_curve; } + const PointGFp& base_point() const { return m_base_point; } + + bool a_is_minus_3() const { return m_a_is_minus_3; } + bool a_is_zero() const { return m_a_is_zero; } + + BigInt mod_order(const BigInt& x) const { return m_mod_order.reduce(x); } + + BigInt square_mod_order(const BigInt& x) const + { + return m_mod_order.square(x); + } + + BigInt multiply_mod_order(const BigInt& x, const BigInt& y) const + { + return m_mod_order.multiply(x, y); + } + + BigInt multiply_mod_order(const BigInt& x, const BigInt& y, const BigInt& z) const + { + return m_mod_order.multiply(m_mod_order.multiply(x, y), z); + } + + BigInt inverse_mod_order(const BigInt& x) const + { + return inverse_mod(x, m_order); + } + + PointGFp blinded_base_point_multiply(const BigInt& k, + RandomNumberGenerator& rng, + std::vector& ws) const + { + return m_base_mult.mul(k, rng, m_order, ws); + } + + private: + CurveGFp m_curve; + PointGFp m_base_point; + + BigInt m_g_x; + BigInt m_g_y; + BigInt m_order; + BigInt m_cofactor; + Modular_Reducer m_mod_order; + PointGFp_Base_Point_Precompute m_base_mult; + OID m_oid; + size_t m_p_bits; + size_t m_order_bits; + bool m_a_is_minus_3; + bool m_a_is_zero; + }; + +class EC_Group_Data_Map final + { + public: + EC_Group_Data_Map() {} + + size_t clear() + { + lock_guard_type lock(m_mutex); + size_t count = m_registered_curves.size(); + m_registered_curves.clear(); + return count; + } + + std::shared_ptr lookup(const OID& oid) + { + lock_guard_type lock(m_mutex); + + for(auto i : m_registered_curves) + { + if(i->oid() == oid) + return i; + } + + // Not found, check hardcoded data + std::shared_ptr data = EC_Group::EC_group_info(oid); + + if(data) + { + m_registered_curves.push_back(data); + return data; + } + + // Nope, unknown curve + return std::shared_ptr(); + } + + std::shared_ptr lookup_or_create(const BigInt& p, + const BigInt& a, + const BigInt& b, + const BigInt& g_x, + const BigInt& g_y, + const BigInt& order, + const BigInt& cofactor, + const OID& oid) + { + lock_guard_type lock(m_mutex); + + for(auto i : m_registered_curves) + { + if(oid.has_value()) + { + if(i->oid() == oid) + return i; + else if(i->oid().has_value()) + continue; + } + + if(i->match(p, a, b, g_x, g_y, order, cofactor)) + return i; + } + + // Not found - if OID is set try looking up that way + + if(oid.has_value()) + { + // Not located in existing store - try hardcoded data set + std::shared_ptr data = EC_Group::EC_group_info(oid); + + if(data) + { + m_registered_curves.push_back(data); + return data; + } + } + + // Not found or no OID, add data and return + return add_curve(p, a, b, g_x, g_y, order, cofactor, oid); + } + + private: + + std::shared_ptr add_curve(const BigInt& p, + const BigInt& a, + const BigInt& b, + const BigInt& g_x, + const BigInt& g_y, + const BigInt& order, + const BigInt& cofactor, + const OID& oid) + { + std::shared_ptr d = + std::make_shared(p, a, b, g_x, g_y, order, cofactor, oid); + + // This function is always called with the lock held + m_registered_curves.push_back(d); + return d; + } + + mutex_type m_mutex; + std::vector> m_registered_curves; + }; + +//static +EC_Group_Data_Map& EC_Group::ec_group_data() + { + /* + * This exists purely to ensure the allocator is constructed before g_ec_data, + * which ensures that its destructor runs after ~g_ec_data is complete. + */ + + static Allocator_Initializer g_init_allocator; + static EC_Group_Data_Map g_ec_data; + return g_ec_data; + } + +//static +size_t EC_Group::clear_registered_curve_data() + { + return ec_group_data().clear(); + } + +//static +std::shared_ptr +EC_Group::load_EC_group_info(const char* p_str, + const char* a_str, + const char* b_str, + const char* g_x_str, + const char* g_y_str, + const char* order_str, + const OID& oid) + { + const BigInt p(p_str); + const BigInt a(a_str); + const BigInt b(b_str); + const BigInt g_x(g_x_str); + const BigInt g_y(g_y_str); + const BigInt order(order_str); + const BigInt cofactor(1); // implicit + + return std::make_shared(p, a, b, g_x, g_y, order, cofactor, oid); + } + +//static +std::shared_ptr EC_Group::BER_decode_EC_group(const uint8_t bits[], size_t len) + { + BER_Decoder ber(bits, len); + BER_Object obj = ber.get_next_object(); + + if(obj.type() == NULL_TAG) + { + throw Decoding_Error("Cannot handle ImplicitCA ECC parameters"); + } + else if(obj.type() == OBJECT_ID) + { + OID dom_par_oid; + BER_Decoder(bits, len).decode(dom_par_oid); + return ec_group_data().lookup(dom_par_oid); + } + else if(obj.type() == SEQUENCE) + { + BigInt p, a, b, order, cofactor; + std::vector base_pt; + std::vector seed; + + BER_Decoder(bits, len) + .start_cons(SEQUENCE) + .decode_and_check(1, "Unknown ECC param version code") + .start_cons(SEQUENCE) + .decode_and_check(OID("1.2.840.10045.1.1"), + "Only prime ECC fields supported") + .decode(p) + .end_cons() + .start_cons(SEQUENCE) + .decode_octet_string_bigint(a) + .decode_octet_string_bigint(b) + .decode_optional_string(seed, BIT_STRING, BIT_STRING) + .end_cons() + .decode(base_pt, OCTET_STRING) + .decode(order) + .decode(cofactor) + .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)) + throw Decoding_Error("Invalid ECC p parameter"); + + if(a.is_negative() || a >= p) + throw Decoding_Error("Invalid ECC a parameter"); + + if(b <= 0 || b >= p) + throw Decoding_Error("Invalid ECC b parameter"); + + if(order <= 0) + throw Decoding_Error("Invalid ECC order parameter"); + + if(cofactor <= 0 || cofactor >= 16) + throw Decoding_Error("Invalid ECC cofactor parameter"); + + std::pair base_xy = Botan::OS2ECP(base_pt.data(), base_pt.size(), p, a, b); + + return ec_group_data().lookup_or_create(p, a, b, base_xy.first, base_xy.second, order, cofactor, OID()); + } + else + { + throw Decoding_Error("Unexpected tag while decoding ECC domain params"); + } + } + +EC_Group::EC_Group() + { + } + +EC_Group::~EC_Group() + { + // shared_ptr possibly freed here + } + +EC_Group::EC_Group(const OID& domain_oid) + { + this->m_data = ec_group_data().lookup(domain_oid); + if(!this->m_data) + throw Invalid_Argument("Unknown EC_Group " + domain_oid.as_string()); + } + +EC_Group::EC_Group(const std::string& str) + { + if(str == "") + return; // no initialization / uninitialized + + try + { + OID oid = OIDS::lookup(str); + if(oid.empty() == false) + m_data = ec_group_data().lookup(oid); + } + catch(Invalid_OID&) + { + } + + if(m_data == nullptr) + { + if(str.size() > 30 && str.substr(0, 29) == "-----BEGIN EC PARAMETERS-----") + { + // OK try it as PEM ... + secure_vector ber = PEM_Code::decode_check_label(str, "EC PARAMETERS"); + this->m_data = BER_decode_EC_group(ber.data(), ber.size()); + } + } + + if(m_data == nullptr) + throw Invalid_Argument("Unknown ECC group '" + str + "'"); + } + +//static +std::string EC_Group::PEM_for_named_group(const std::string& name) + { + try + { + EC_Group group(name); + return group.PEM_encode(); + } + catch(...) + { + return ""; + } + } + +EC_Group::EC_Group(const BigInt& p, + const BigInt& a, + const BigInt& b, + const BigInt& base_x, + const BigInt& base_y, + const BigInt& order, + const BigInt& cofactor, + const OID& oid) + { + m_data = ec_group_data().lookup_or_create(p, a, b, base_x, base_y, order, cofactor, oid); + } + +EC_Group::EC_Group(const std::vector& ber) + { + m_data = BER_decode_EC_group(ber.data(), ber.size()); + } + +const EC_Group_Data& EC_Group::data() const + { + if(m_data == nullptr) + throw Invalid_State("EC_Group uninitialized"); + return *m_data; + } + +const CurveGFp& EC_Group::get_curve() const + { + return data().curve(); + } + +bool EC_Group::a_is_minus_3() const + { + return data().a_is_minus_3(); + } + +bool EC_Group::a_is_zero() const + { + return data().a_is_zero(); + } + +size_t EC_Group::get_p_bits() const + { + return data().p_bits(); + } + +size_t EC_Group::get_p_bytes() const + { + return data().p_bytes(); + } + +size_t EC_Group::get_order_bits() const + { + return data().order_bits(); + } + +size_t EC_Group::get_order_bytes() const + { + return data().order_bytes(); + } + +const BigInt& EC_Group::get_p() const + { + return data().p(); + } + +const BigInt& EC_Group::get_a() const + { + return data().a(); + } + +const BigInt& EC_Group::get_b() const + { + return data().b(); + } + +const PointGFp& EC_Group::get_base_point() const + { + return data().base_point(); + } + +const BigInt& EC_Group::get_order() const + { + return data().order(); + } + +const BigInt& EC_Group::get_g_x() const + { + return data().g_x(); + } + +const BigInt& EC_Group::get_g_y() const + { + return data().g_y(); + } + +const BigInt& EC_Group::get_cofactor() const + { + return data().cofactor(); + } + +BigInt EC_Group::mod_order(const BigInt& k) const + { + return data().mod_order(k); + } + +BigInt EC_Group::square_mod_order(const BigInt& x) const + { + return data().square_mod_order(x); + } + +BigInt EC_Group::multiply_mod_order(const BigInt& x, const BigInt& y) const + { + return data().multiply_mod_order(x, y); + } + +BigInt EC_Group::multiply_mod_order(const BigInt& x, const BigInt& y, const BigInt& z) const + { + return data().multiply_mod_order(x, y, z); + } + +BigInt EC_Group::inverse_mod_order(const BigInt& x) const + { + return data().inverse_mod_order(x); + } + +const OID& EC_Group::get_curve_oid() const + { + return data().oid(); + } + +PointGFp EC_Group::OS2ECP(const uint8_t bits[], size_t len) const + { + return Botan::OS2ECP(bits, len, data().curve()); + } + +PointGFp EC_Group::point(const BigInt& x, const BigInt& y) const + { + // TODO: randomize the representation? + return PointGFp(data().curve(), x, y); + } + +PointGFp EC_Group::point_multiply(const BigInt& x, const PointGFp& pt, const BigInt& y) const + { + PointGFp_Multi_Point_Precompute xy_mul(get_base_point(), pt); + return xy_mul.multi_exp(x, y); + } + +PointGFp EC_Group::blinded_base_point_multiply(const BigInt& k, + RandomNumberGenerator& rng, + std::vector& ws) const + { + return data().blinded_base_point_multiply(k, rng, ws); + } + +BigInt EC_Group::blinded_base_point_multiply_x(const BigInt& k, + RandomNumberGenerator& rng, + std::vector& ws) const + { + const PointGFp pt = data().blinded_base_point_multiply(k, rng, ws); + + if(pt.is_zero()) + return 0; + return pt.get_affine_x(); + } + +BigInt EC_Group::random_scalar(RandomNumberGenerator& rng) const + { + return BigInt::random_integer(rng, 1, get_order()); + } + +PointGFp EC_Group::blinded_var_point_multiply(const PointGFp& point, + const BigInt& k, + RandomNumberGenerator& rng, + std::vector& ws) const + { + PointGFp_Var_Point_Precompute mul(point, rng, ws); + return mul.mul(k, rng, get_order(), ws); + } + +PointGFp EC_Group::zero_point() const + { + return PointGFp(data().curve()); + } + +std::vector +EC_Group::DER_encode(EC_Group_Encoding form) const + { + std::vector output; + + DER_Encoder der(output); + + if(form == EC_DOMPAR_ENC_EXPLICIT) + { + const size_t ecpVers1 = 1; + const OID curve_type("1.2.840.10045.1.1"); // prime field + + const size_t p_bytes = get_p_bytes(); + + der.start_cons(SEQUENCE) + .encode(ecpVers1) + .start_cons(SEQUENCE) + .encode(curve_type) + .encode(get_p()) + .end_cons() + .start_cons(SEQUENCE) + .encode(BigInt::encode_1363(get_a(), p_bytes), + OCTET_STRING) + .encode(BigInt::encode_1363(get_b(), p_bytes), + OCTET_STRING) + .end_cons() + .encode(get_base_point().encode(PointGFp::UNCOMPRESSED), OCTET_STRING) + .encode(get_order()) + .encode(get_cofactor()) + .end_cons(); + } + else if(form == EC_DOMPAR_ENC_OID) + { + const OID oid = get_curve_oid(); + if(oid.empty()) + { + throw Encoding_Error("Cannot encode EC_Group as OID because OID not set"); + } + der.encode(oid); + } + else if(form == EC_DOMPAR_ENC_IMPLICITCA) + { + der.encode_null(); + } + else + { + throw Internal_Error("EC_Group::DER_encode: Unknown encoding"); + } + + return output; + } + +std::string EC_Group::PEM_encode() const + { + const std::vector der = DER_encode(EC_DOMPAR_ENC_EXPLICIT); + return PEM_Code::encode(der, "EC PARAMETERS"); + } + +bool EC_Group::operator==(const EC_Group& other) const + { + if(m_data == other.m_data) + return true; // same shared rep + + /* + * No point comparing order/cofactor as they are uniquely determined + * by the curve equation (p,a,b) and the base point. + */ + return (get_p() == other.get_p() && + get_a() == other.get_a() && + get_b() == other.get_b() && + get_g_x() == other.get_g_x() && + get_g_y() == other.get_g_y()); + } + +bool EC_Group::verify_public_element(const PointGFp& point) const + { + //check that public point is not at infinity + if(point.is_zero()) + return false; + + //check that public point is on the curve + if(point.on_the_curve() == false) + return false; + + //check that public point has order q + if((point * get_order()).is_zero() == false) + return false; + + if(get_cofactor() > 1) + { + if((point * get_cofactor()).is_zero()) + return false; + } + + return true; + } + +bool EC_Group::verify_group(RandomNumberGenerator& rng, + bool) const + { + const BigInt& p = get_p(); + const BigInt& a = get_a(); + const BigInt& b = get_b(); + const BigInt& order = get_order(); + const PointGFp& base_point = get_base_point(); + + if(a < 0 || a >= p) + return false; + if(b <= 0 || b >= p) + return false; + if(order <= 0) + return false; + + //check if field modulus is prime + if(!is_prime(p, rng, 128)) + { + return false; + } + + //check if order is prime + if(!is_prime(order, rng, 128)) + { + return false; + } + + //compute the discriminant: 4*a^3 + 27*b^2 which must be nonzero + const Modular_Reducer mod_p(p); + + const BigInt discriminant = mod_p.reduce( + mod_p.multiply(4, mod_p.cube(a)) + + mod_p.multiply(27, mod_p.square(b))); + + if(discriminant == 0) + { + return false; + } + + //check for valid cofactor + if(get_cofactor() < 1) + { + return false; + } + + //check if the base point is on the curve + if(!base_point.on_the_curve()) + { + return false; + } + if((base_point * get_cofactor()).is_zero()) + { + return false; + } + //check if order of the base point is correct + if(!(base_point * order).is_zero()) + { + return false; + } + + return true; + } + +} 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 new file mode 100644 index 0000000000..f8c1c1a123 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pubkey/ec_group/ec_group.h @@ -0,0 +1,372 @@ +/* +* ECC Domain Parameters +* +* (C) 2007 Falko Strenzke, FlexSecure GmbH +* 2008-2010 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_ECC_DOMAIN_PARAMETERS_H_ +#define BOTAN_ECC_DOMAIN_PARAMETERS_H_ + +#include +#include +#include +#include + +namespace Botan { + +/** +* This class represents elliptic curce domain parameters +*/ +enum EC_Group_Encoding { + EC_DOMPAR_ENC_EXPLICIT = 0, + EC_DOMPAR_ENC_IMPLICITCA = 1, + EC_DOMPAR_ENC_OID = 2 +}; + +class CurveGFp; + +class EC_Group_Data; +class EC_Group_Data_Map; + +/** +* Class representing an elliptic curve +* +* The internal representation is stored in a shared_ptr, so copying an +* EC_Group is inexpensive. +*/ +class BOTAN_PUBLIC_API(2,0) EC_Group final + { + public: + + /** + * Construct Domain paramers from specified parameters + * @param curve elliptic curve + * @param base_point a base point + * @param order the order of the base point + * @param cofactor the cofactor + */ + BOTAN_DEPRECATED("Use version taking all BigInts") + EC_Group(const CurveGFp& curve, + const PointGFp& base_point, + const BigInt& order, + const BigInt& cofactor) : + EC_Group(curve.get_p(), + curve.get_a(), + curve.get_b(), + base_point.get_affine_x(), + base_point.get_affine_y(), + order, + cofactor) {} + + /** + * Construct Domain paramers from specified parameters + * @param p the elliptic curve p + * @param a the elliptic curve a param + * @param b the elliptic curve b param + * @param base_x the x coordinate of the base point + * @param base_y the y coordinate of the base point + * @param order the order of the base point + * @param cofactor the cofactor + * @param oid an optional OID used to identify this curve + */ + EC_Group(const BigInt& p, + const BigInt& a, + const BigInt& b, + const BigInt& base_x, + const BigInt& base_y, + const BigInt& order, + const BigInt& cofactor, + const OID& oid = OID()); + + /** + * Decode a BER encoded ECC domain parameter set + * @param ber_encoding the bytes of the BER encoding + */ + explicit EC_Group(const std::vector& ber_encoding); + + /** + * Create an EC domain by OID (or throw if unknown) + * @param oid the OID of the EC domain to create + */ + explicit EC_Group(const OID& oid); + + /** + * Create an EC domain from PEM encoding (as from PEM_encode), or + * from an OID name (eg "secp256r1", or "1.2.840.10045.3.1.7") + * @param pem_or_oid PEM-encoded data, or an OID + */ + explicit EC_Group(const std::string& pem_or_oid); + + /** + * Create an uninitialized EC_Group + */ + EC_Group(); + + ~EC_Group(); + + /** + * Create the DER encoding of this domain + * @param form of encoding to use + * @returns bytes encododed as DER + */ + std::vector DER_encode(EC_Group_Encoding form) const; + + /** + * Return the PEM encoding (always in explicit form) + * @return string containing PEM data + */ + std::string PEM_encode() const; + + /** + * Return domain parameter curve + * @result domain parameter curve + */ + BOTAN_DEPRECATED("Avoid CurveGFp") const CurveGFp& get_curve() const; + + /** + * Return if a == -3 mod p + */ + bool a_is_minus_3() const; + + /** + * Return if a == 0 mod p + */ + bool a_is_zero() const; + + /** + * Return the size of p in bits (same as get_p().bits()) + */ + size_t get_p_bits() const; + + /** + * Return the size of p in bits (same as get_p().bytes()) + */ + size_t get_p_bytes() const; + + /** + * Return the size of group order in bits (same as get_order().bits()) + */ + size_t get_order_bits() const; + + /** + * Return the size of p in bytes (same as get_order().bytes()) + */ + size_t get_order_bytes() const; + + /** + * Return the prime modulus of the field + */ + const BigInt& get_p() const; + + /** + * Return the a parameter of the elliptic curve equation + */ + const BigInt& get_a() const; + + /** + * Return the b parameter of the elliptic curve equation + */ + const BigInt& get_b() const; + + /** + * Return group base point + * @result base point + */ + const PointGFp& get_base_point() const; + + /** + * Return the x coordinate of the base point + */ + const BigInt& get_g_x() const; + + /** + * Return the y coordinate of the base point + */ + const BigInt& get_g_y() const; + + /** + * Return the order of the base point + * @result order of the base point + */ + const BigInt& get_order() const; + + /* + * Reduce x modulo the order + */ + BigInt mod_order(const BigInt& x) const; + + /* + * Return inverse of x modulo the order + */ + BigInt inverse_mod_order(const BigInt& x) const; + + /* + * Reduce (x*x) modulo the order + */ + BigInt square_mod_order(const BigInt& x) const; + + /* + * Reduce (x*y) modulo the order + */ + BigInt multiply_mod_order(const BigInt& x, const BigInt& y) const; + + /* + * Reduce (x*y*z) modulo the order + */ + BigInt multiply_mod_order(const BigInt& x, const BigInt& y, const BigInt& z) const; + + /** + * Return the cofactor + * @result the cofactor + */ + const BigInt& get_cofactor() const; + + /** + * Check if y is a plausible point on the curve + * + * In particular, checks that it is a point on the curve, not infinity, + * and that it has order matching the group. + */ + bool verify_public_element(const PointGFp& y) const; + + /** + * Return the OID of these domain parameters + * @result the OID as a string + */ + std::string BOTAN_DEPRECATED("Use get_curve_oid") get_oid() const { return get_curve_oid().as_string(); } + + /** + * Return the OID of these domain parameters + * @result the OID + */ + const OID& get_curve_oid() const; + + /** + * Return a point on this curve with the affine values x, y + */ + PointGFp point(const BigInt& x, const BigInt& y) const; + + /** + * Multi exponentiate. Not constant time. + * @return base_point*x + pt*y + */ + PointGFp point_multiply(const BigInt& x, const PointGFp& pt, const BigInt& y) const; + + /** + * Blinded point multiplication, attempts resistance to side channels + * @param k the scalar + * @param rng a random number generator + * @param ws a temp workspace + * @return base_point*k + */ + PointGFp blinded_base_point_multiply(const BigInt& k, + RandomNumberGenerator& rng, + std::vector& ws) const; + + /** + * Blinded point multiplication, attempts resistance to side channels + * Returns just the x coordinate of the point + * + * @param k the scalar + * @param rng a random number generator + * @param ws a temp workspace + * @return x coordinate of base_point*k + */ + BigInt blinded_base_point_multiply_x(const BigInt& k, + RandomNumberGenerator& rng, + std::vector& ws) const; + + /** + * Blinded point multiplication, attempts resistance to side channels + * @param point input point + * @param k the scalar + * @param rng a random number generator + * @param ws a temp workspace + * @return point*k + */ + PointGFp blinded_var_point_multiply(const PointGFp& point, + const BigInt& k, + RandomNumberGenerator& rng, + std::vector& ws) const; + + /** + * Return a random scalar ie an integer in [1,order) + */ + BigInt random_scalar(RandomNumberGenerator& rng) const; + + /** + * Return the zero (or infinite) point on this curve + */ + PointGFp zero_point() const; + + PointGFp OS2ECP(const uint8_t bits[], size_t len) const; + + template + PointGFp OS2ECP(const std::vector& vec) const + { + return this->OS2ECP(vec.data(), vec.size()); + } + + bool initialized() const { return (m_data != nullptr); } + + /** + * Verify EC_Group domain + * @returns true if group is valid. false otherwise + */ + bool verify_group(RandomNumberGenerator& rng, + bool strong = false) const; + + bool operator==(const EC_Group& other) const; + + /** + * Return PEM representation of named EC group + * Deprecated: Use EC_Group(name).PEM_encode() if this is needed + */ + static std::string BOTAN_DEPRECATED("See header comment") PEM_for_named_group(const std::string& name); + + /** + * Return a set of known named EC groups + */ + static const std::set& known_named_groups(); + + /* + * For internal use only + */ + static std::shared_ptr EC_group_info(const OID& oid); + + static size_t clear_registered_curve_data(); + + private: + static EC_Group_Data_Map& ec_group_data(); + + static std::shared_ptr BER_decode_EC_group(const uint8_t bits[], size_t len); + + static std::shared_ptr + load_EC_group_info(const char* p, + const char* a, + const char* b, + const char* g_x, + const char* g_y, + const char* order, + const OID& oid); + + // Member data + const EC_Group_Data& data() const; + std::shared_ptr m_data; + }; + +inline bool operator!=(const EC_Group& lhs, + const EC_Group& rhs) + { + return !(lhs == rhs); + } + +// For compatibility with 1.8 +typedef EC_Group EC_Domain_Params; + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/ec_group/ec_named.cpp b/src/libs/3rdparty/botan/src/lib/pubkey/ec_group/ec_named.cpp new file mode 100644 index 0000000000..ba91b5eaaf --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pubkey/ec_group/ec_named.cpp @@ -0,0 +1,289 @@ +/* +* List of ECC groups +* (C) 2013,2018 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include + +namespace Botan { + +//static +std::shared_ptr EC_Group::EC_group_info(const OID& oid) + { + // P-256 + if(oid == OID{1,2,840,10045,3,1,7}) + return load_EC_group_info("0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF", + "0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC", + "0x5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B", + "0x6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296", + "0x4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5", + "0xFFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551", + oid); + + // P-384 + if(oid == OID{1,3,132,0,34}) + return load_EC_group_info("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF", + "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC", + "0xB3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF", + "0xAA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7", + "0x3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F", + "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973", + oid); + // P-521 + if(oid == OID{1,3,132,0,35}) + return load_EC_group_info("0x1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", + "0x1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC", + "0x51953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00", + "0xC6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66", + "0x11839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650", + "0x1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409", + oid); + + // brainpool160r1 + if(oid == OID{1,3,36,3,3,2,8,1,1,1}) + return load_EC_group_info("0xE95E4A5F737059DC60DFC7AD95B3D8139515620F", + "0x340E7BE2A280EB74E2BE61BADA745D97E8F7C300", + "0x1E589A8595423412134FAA2DBDEC95C8D8675E58", + "0xBED5AF16EA3F6A4F62938C4631EB5AF7BDBCDBC3", + "0x1667CB477A1A8EC338F94741669C976316DA6321", + "0xE95E4A5F737059DC60DF5991D45029409E60FC09", + oid); + // brainpool192r1 + if(oid == OID{1,3,36,3,3,2,8,1,1,3}) + return load_EC_group_info("0xC302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297", + "0x6A91174076B1E0E19C39C031FE8685C1CAE040E5C69A28EF", + "0x469A28EF7C28CCA3DC721D044F4496BCCA7EF4146FBF25C9", + "0xC0A0647EAAB6A48753B033C56CB0F0900A2F5C4853375FD6", + "0x14B690866ABD5BB88B5F4828C1490002E6773FA2FA299B8F", + "0xC302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1", + oid); + // brainpool224r1 + if(oid == OID{1,3,36,3,3,2,8,1,1,5}) + return load_EC_group_info("0xD7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF", + "0x68A5E62CA9CE6C1C299803A6C1530B514E182AD8B0042A59CAD29F43", + "0x2580F63CCFE44138870713B1A92369E33E2135D266DBB372386C400B", + "0xD9029AD2C7E5CF4340823B2A87DC68C9E4CE3174C1E6EFDEE12C07D", + "0x58AA56F772C0726F24C6B89E4ECDAC24354B9E99CAA3F6D3761402CD", + "0xD7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F", + oid); + // brainpool256r1 + if(oid == OID{1,3,36,3,3,2,8,1,1,7}) + return load_EC_group_info("0xA9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377", + "0x7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9", + "0x26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6", + "0x8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262", + "0x547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997", + "0xA9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7", + oid); + // brainpool320r1 + if(oid == OID{1,3,36,3,3,2,8,1,1,9}) + return load_EC_group_info("0xD35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E27", + "0x3EE30B568FBAB0F883CCEBD46D3F3BB8A2A73513F5EB79DA66190EB085FFA9F492F375A97D860EB4", + "0x520883949DFDBC42D3AD198640688A6FE13F41349554B49ACC31DCCD884539816F5EB4AC8FB1F1A6", + "0x43BD7E9AFB53D8B85289BCC48EE5BFE6F20137D10A087EB6E7871E2A10A599C710AF8D0D39E20611", + "0x14FDD05545EC1CC8AB4093247F77275E0743FFED117182EAA9C77877AAAC6AC7D35245D1692E8EE1", + "0xD35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D482EC7EE8658E98691555B44C59311", + oid); + // brainpool384r1 + if(oid == OID{1,3,36,3,3,2,8,1,1,11}) + return load_EC_group_info("0x8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53", + "0x7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F90F8AA5814A503AD4EB04A8C7DD22CE2826", + "0x4A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62D57CB4390295DBC9943AB78696FA504C11", + "0x1D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10E8E826E03436D646AAEF87B2E247D4AF1E", + "0x8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129280E4646217791811142820341263C5315", + "0x8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565", + oid); + // brainpool512r1 + if(oid == OID{1,3,36,3,3,2,8,1,1,13}) + return load_EC_group_info("0xAADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3", + "0x7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA", + "0x3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723", + "0x81AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D0098EFF3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F822", + "0x7DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F8111B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892", + "0xAADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069", + oid); + // frp256v1 + if(oid == OID{1,2,250,1,223,101,256,1}) + return load_EC_group_info("0xF1FD178C0B3AD58F10126DE8CE42435B3961ADBCABC8CA6DE8FCF353D86E9C03", + "0xF1FD178C0B3AD58F10126DE8CE42435B3961ADBCABC8CA6DE8FCF353D86E9C00", + "0xEE353FCA5428A9300D4ABA754A44C00FDFEC0C9AE4B1A1803075ED967B7BB73F", + "0xB6B3D4C356C139EB31183D4749D423958C27D2DCAF98B70164C97A2DD98F5CFF", + "0x6142E0F7C8B204911F9271F0F3ECEF8C2701C307E8E4C9E183115A1554062CFB", + "0xF1FD178C0B3AD58F10126DE8CE42435B53DC67E140D2BF941FFDD459C6D655E1", + oid); + // gost_256A + if(oid == OID{1,2,643,2,2,35,1}) + return load_EC_group_info("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD97", + "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD94", + "0xA6", + "0x1", + "0x8D91E471E0989CDA27DF505A453F2B7635294F2DDF23E3B122ACC99C9E9F1E14", + "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C611070995AD10045841B09B761B893", + oid); + // secp160k1 + if(oid == OID{1,3,132,0,9}) + return load_EC_group_info("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", + "0x0", + "0x7", + "0x3B4C382CE37AA192A4019E763036F4F5DD4D7EBB", + "0x938CF935318FDCED6BC28286531733C3F03C4FEE", + "0x100000000000000000001B8FA16DFAB9ACA16B6B3", + oid); + // secp160r1 + if(oid == OID{1,3,132,0,8}) + return load_EC_group_info("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF", + "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC", + "0x1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45", + "0x4A96B5688EF573284664698968C38BB913CBFC82", + "0x23A628553168947D59DCC912042351377AC5FB32", + "0x100000000000000000001F4C8F927AED3CA752257", + oid); + // secp160r2 + if(oid == OID{1,3,132,0,30}) + return load_EC_group_info("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", + "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70", + "0xB4E134D3FB59EB8BAB57274904664D5AF50388BA", + "0x52DCB034293A117E1F4FF11B30F7199D3144CE6D", + "0xFEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E", + "0x100000000000000000000351EE786A818F3A1A16B", + oid); + // secp192k1 + if(oid == OID{1,3,132,0,31}) + return load_EC_group_info("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37", + "0x0", + "0x3", + "0xDB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D", + "0x9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D", + "0xFFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D", + oid); + // secp192r1 + if(oid == OID{1,2,840,10045,3,1,1}) + return load_EC_group_info("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", + "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", + "0x64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1", + "0x188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012", + "0x7192B95FFC8DA78631011ED6B24CDD573F977A11E794811", + "0xFFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831", + oid); + // secp224k1 + if(oid == OID{1,3,132,0,32}) + return load_EC_group_info("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D", + "0x0", + "0x5", + "0xA1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C", + "0x7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5", + "0x10000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7", + oid); + // secp224r1 + if(oid == OID{1,3,132,0,33}) + return load_EC_group_info("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", + "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE", + "0xB4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4", + "0xB70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21", + "0xBD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34", + "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D", + oid); + // secp256k1 + if(oid == OID{1,3,132,0,10}) + return load_EC_group_info("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", + "0x0", + "0x7", + "0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", + "0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", + "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", + oid); + + // sm2p256v1 + if(oid == OID{1,2,156,10197,1,301}) + return load_EC_group_info("0xFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF", + "0xFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC", + "0x28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93", + "0x32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7", + "0xBC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0", + "0xFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123", + oid); + // x962_p192v2 + if(oid == OID{1,2,840,10045,3,1,2}) + return load_EC_group_info("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", + "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", + "0xCC22D6DFB95C6B25E49C0D6364A4E5980C393AA21668D953", + "0xEEA2BAE7E1497842F2DE7769CFE9C989C072AD696F48034A", + "0x6574D11D69B6EC7A672BB82A083DF2F2B0847DE970B2DE15", + "0xFFFFFFFFFFFFFFFFFFFFFFFE5FB1A724DC80418648D8DD31", + oid); + // x962_p192v3 + if(oid == OID{1,2,840,10045,3,1,3}) + return load_EC_group_info("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", + "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", + "0x22123DC2395A05CAA7423DAECCC94760A7D462256BD56916", + "0x7D29778100C65A1DA1783716588DCE2B8B4AEE8E228F1896", + "0x38A90F22637337334B49DCB66A6DC8F9978ACA7648A943B0", + "0xFFFFFFFFFFFFFFFFFFFFFFFF7A62D031C83F4294F640EC13", + oid); + // x962_p239v1 + if(oid == OID{1,2,840,10045,3,1,4}) + return load_EC_group_info("0x7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", + "0x7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", + "0x6B016C3BDCF18941D0D654921475CA71A9DB2FB27D1D37796185C2942C0A", + "0xFFA963CDCA8816CCC33B8642BEDF905C3D358573D3F27FBBD3B3CB9AAAF", + "0x7DEBE8E4E90A5DAE6E4054CA530BA04654B36818CE226B39FCCB7B02F1AE", + "0x7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF9E5E9A9F5D9071FBD1522688909D0B", + oid); + // x962_p239v2 + if(oid == OID{1,2,840,10045,3,1,5}) + return load_EC_group_info("0x7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", + "0x7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", + "0x617FAB6832576CBBFED50D99F0249C3FEE58B94BA0038C7AE84C8C832F2C", + "0x38AF09D98727705120C921BB5E9E26296A3CDCF2F35757A0EAFD87B830E7", + "0x5B0125E4DBEA0EC7206DA0FC01D9B081329FB555DE6EF460237DFF8BE4BA", + "0x7FFFFFFFFFFFFFFFFFFFFFFF800000CFA7E8594377D414C03821BC582063", + oid); + // x962_p239v3 + if(oid == OID{1,2,840,10045,3,1,6}) + return load_EC_group_info("0x7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", + "0x7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", + "0x255705FA2A306654B1F4CB03D6A750A30C250102D4988717D9BA15AB6D3E", + "0x6768AE8E18BB92CFCF005C949AA2C6D94853D0E660BBF854B1C9505FE95A", + "0x1607E6898F390C06BC1D552BAD226F3B6FCFE48B6E818499AF18E3ED6CF3", + "0x7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF975DEB41B3A6057C3C432146526551", + oid); + + return std::shared_ptr(); + } + +//static +const std::set& EC_Group::known_named_groups() + { + static const std::set named_groups = { + "secp160k1", + "secp160r1", + "secp160r2", + "secp192k1", + "secp192r1", + "secp224k1", + "secp224r1", + "secp256k1", + "secp256r1", + "secp384r1", + "secp521r1", + "brainpool160r1", + "brainpool192r1", + "brainpool224r1", + "brainpool256r1", + "brainpool320r1", + "brainpool384r1", + "brainpool512r1", + "x962_p192v2", + "x962_p192v3", + "x962_p239v1", + "x962_p239v2", + "x962_p239v3", + "gost_256A", + "frp256v1", + "sm2p256v1" + }; + return named_groups; + } +} diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/ec_group/info.txt b/src/libs/3rdparty/botan/src/lib/pubkey/ec_group/info.txt new file mode 100644 index 0000000000..e382e25a5e --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pubkey/ec_group/info.txt @@ -0,0 +1,20 @@ + +ECC_GROUP -> 20170225 +EC_CURVE_GFP -> 20131128 + + + +asn1 +numbertheory +pem + + + +point_mul.h + + + +curve_gfp.h +ec_group.h +point_gfp.h + diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/ec_group/point_gfp.cpp b/src/libs/3rdparty/botan/src/lib/pubkey/ec_group/point_gfp.cpp new file mode 100644 index 0000000000..77803de78f --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pubkey/ec_group/point_gfp.cpp @@ -0,0 +1,727 @@ +/* +* Point arithmetic on elliptic curves over GF(p) +* +* (C) 2007 Martin Doering, Christoph Ludwig, Falko Strenzke +* 2008-2011,2012,2014,2015 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include + +namespace Botan { + +PointGFp::PointGFp(const CurveGFp& curve) : + m_curve(curve), + m_coord_x(0), + m_coord_y(curve.get_1_rep()), + m_coord_z(0) + { + // Assumes Montgomery rep of zero is zero + } + +PointGFp::PointGFp(const CurveGFp& curve, const BigInt& x, const BigInt& y) : + m_curve(curve), + m_coord_x(x), + m_coord_y(y), + m_coord_z(m_curve.get_1_rep()) + { + if(x <= 0 || x >= curve.get_p()) + throw Invalid_Argument("Invalid PointGFp affine x"); + if(y <= 0 || y >= curve.get_p()) + throw Invalid_Argument("Invalid PointGFp affine y"); + + secure_vector monty_ws(m_curve.get_ws_size()); + m_curve.to_rep(m_coord_x, monty_ws); + m_curve.to_rep(m_coord_y, monty_ws); + } + +void PointGFp::randomize_repr(RandomNumberGenerator& rng) + { + secure_vector ws(m_curve.get_ws_size()); + randomize_repr(rng, ws); + } + +void PointGFp::randomize_repr(RandomNumberGenerator& rng, secure_vector& ws) + { + const BigInt mask = BigInt::random_integer(rng, 2, m_curve.get_p()); + + /* + * No reason to convert this to Montgomery representation first, + * just pretend the random mask was chosen as Redc(mask) and the + * random mask we generated above is in the Montgomery + * representation. + * //m_curve.to_rep(mask, ws); + */ + const BigInt mask2 = m_curve.sqr_to_tmp(mask, ws); + const BigInt mask3 = m_curve.mul_to_tmp(mask2, mask, ws); + + m_coord_x = m_curve.mul_to_tmp(m_coord_x, mask2, ws); + m_coord_y = m_curve.mul_to_tmp(m_coord_y, mask3, ws); + m_coord_z = m_curve.mul_to_tmp(m_coord_z, mask, ws); + } + +namespace { + +inline void resize_ws(std::vector& ws_bn, size_t cap_size) + { + BOTAN_ASSERT(ws_bn.size() >= PointGFp::WORKSPACE_SIZE, + "Expected size for PointGFp workspace"); + + for(size_t i = 0; i != ws_bn.size(); ++i) + if(ws_bn[i].size() < cap_size) + ws_bn[i].get_word_vector().resize(cap_size); + } + +inline bool all_zeros(const word x[], size_t len) + { + word z = 0; + for(size_t i = 0; i != len; ++i) + z |= x[i]; + return (z == 0); + } + +} + +void PointGFp::add_affine(const word x_words[], size_t x_size, + const word y_words[], size_t y_size, + std::vector& ws_bn) + { + if(all_zeros(x_words, x_size) && all_zeros(y_words, y_size)) + return; + + if(is_zero()) + { + m_coord_x.set_words(x_words, x_size); + m_coord_y.set_words(y_words, y_size); + m_coord_z = m_curve.get_1_rep(); + return; + } + + resize_ws(ws_bn, m_curve.get_ws_size()); + + secure_vector& ws = ws_bn[0].get_word_vector(); + secure_vector& sub_ws = ws_bn[1].get_word_vector(); + + BigInt& T0 = ws_bn[2]; + BigInt& T1 = ws_bn[3]; + BigInt& T2 = ws_bn[4]; + BigInt& T3 = ws_bn[5]; + BigInt& T4 = ws_bn[6]; + + /* + https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-1998-cmo-2 + simplified with Z2 = 1 + */ + + const BigInt& p = m_curve.get_p(); + + m_curve.sqr(T3, m_coord_z, ws); // z1^2 + m_curve.mul(T4, x_words, x_size, T3, ws); // x2*z1^2 + + m_curve.mul(T2, m_coord_z, T3, ws); // z1^3 + m_curve.mul(T0, y_words, y_size, T2, ws); // y2*z1^3 + + T4.mod_sub(m_coord_x, p, sub_ws); // x2*z1^2 - x1*z2^2 + + T0.mod_sub(m_coord_y, p, sub_ws); + + if(T4.is_zero()) + { + if(T0.is_zero()) + { + mult2(ws_bn); + return; + } + + // setting to zero: + m_coord_x = 0; + m_coord_y = m_curve.get_1_rep(); + m_coord_z = 0; + return; + } + + m_curve.sqr(T2, T4, ws); + + m_curve.mul(T3, m_coord_x, T2, ws); + + m_curve.mul(T1, T2, T4, ws); + + m_curve.sqr(m_coord_x, T0, ws); + m_coord_x.mod_sub(T1, p, sub_ws); + m_coord_x.mod_sub(T3, p, sub_ws); + m_coord_x.mod_sub(T3, p, sub_ws); + + T3.mod_sub(m_coord_x, p, sub_ws); + + T2 = m_coord_y; + m_curve.mul(T2, T0, T3, ws); + m_curve.mul(T3, m_coord_y, T1, ws); + T2.mod_sub(T3, p, sub_ws); + m_coord_y = T2; + + m_curve.mul(T3, m_coord_z, T4, ws); + m_coord_z = T3; + } + +void PointGFp::add(const word x_words[], size_t x_size, + const word y_words[], size_t y_size, + const word z_words[], size_t z_size, + std::vector& ws_bn) + { + if(all_zeros(x_words, x_size) && all_zeros(z_words, z_size)) + return; + + if(is_zero()) + { + m_coord_x.set_words(x_words, x_size); + m_coord_y.set_words(y_words, y_size); + m_coord_z.set_words(z_words, z_size); + return; + } + + resize_ws(ws_bn, m_curve.get_ws_size()); + + secure_vector& ws = ws_bn[0].get_word_vector(); + secure_vector& sub_ws = ws_bn[1].get_word_vector(); + + BigInt& T0 = ws_bn[2]; + BigInt& T1 = ws_bn[3]; + BigInt& T2 = ws_bn[4]; + BigInt& T3 = ws_bn[5]; + BigInt& T4 = ws_bn[6]; + BigInt& T5 = ws_bn[7]; + + /* + https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-1998-cmo-2 + */ + + const BigInt& p = m_curve.get_p(); + + m_curve.sqr(T0, z_words, z_size, ws); // z2^2 + m_curve.mul(T1, m_coord_x, T0, ws); // x1*z2^2 + m_curve.mul(T3, z_words, z_size, T0, ws); // z2^3 + m_curve.mul(T2, m_coord_y, T3, ws); // y1*z2^3 + + m_curve.sqr(T3, m_coord_z, ws); // z1^2 + m_curve.mul(T4, x_words, x_size, T3, ws); // x2*z1^2 + + m_curve.mul(T5, m_coord_z, T3, ws); // z1^3 + m_curve.mul(T0, y_words, y_size, T5, ws); // y2*z1^3 + + T4.mod_sub(T1, p, sub_ws); // x2*z1^2 - x1*z2^2 + + T0.mod_sub(T2, p, sub_ws); + + if(T4.is_zero()) + { + if(T0.is_zero()) + { + mult2(ws_bn); + return; + } + + // setting to zero: + m_coord_x = 0; + m_coord_y = m_curve.get_1_rep(); + m_coord_z = 0; + return; + } + + m_curve.sqr(T5, T4, ws); + + m_curve.mul(T3, T1, T5, ws); + + m_curve.mul(T1, T5, T4, ws); + + m_curve.sqr(m_coord_x, T0, ws); + m_coord_x.mod_sub(T1, p, sub_ws); + m_coord_x.mod_sub(T3, p, sub_ws); + m_coord_x.mod_sub(T3, p, sub_ws); + + T3.mod_sub(m_coord_x, p, sub_ws); + + m_curve.mul(m_coord_y, T0, T3, ws); + m_curve.mul(T3, T2, T1, ws); + + m_coord_y.mod_sub(T3, p, sub_ws); + + m_curve.mul(T3, z_words, z_size, m_coord_z, ws); + m_curve.mul(m_coord_z, T3, T4, ws); + } + +void PointGFp::mult2i(size_t iterations, std::vector& ws_bn) + { + if(iterations == 0) + return; + + if(m_coord_y.is_zero()) + { + *this = PointGFp(m_curve); // setting myself to zero + return; + } + + /* + TODO we can save 2 squarings per iteration by computing + a*Z^4 using values cached from previous iteration + */ + for(size_t i = 0; i != iterations; ++i) + mult2(ws_bn); + } + +// *this *= 2 +void PointGFp::mult2(std::vector& ws_bn) + { + if(is_zero()) + return; + + if(m_coord_y.is_zero()) + { + *this = PointGFp(m_curve); // setting myself to zero + return; + } + + resize_ws(ws_bn, m_curve.get_ws_size()); + + secure_vector& ws = ws_bn[0].get_word_vector(); + secure_vector& sub_ws = ws_bn[1].get_word_vector(); + + BigInt& T0 = ws_bn[2]; + BigInt& T1 = ws_bn[3]; + BigInt& T2 = ws_bn[4]; + BigInt& T3 = ws_bn[5]; + BigInt& T4 = ws_bn[6]; + + /* + https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-1986-cc + */ + const BigInt& p = m_curve.get_p(); + + m_curve.sqr(T0, m_coord_y, ws); + + m_curve.mul(T1, m_coord_x, T0, ws); + T1 <<= 2; // * 4 + m_curve.redc_mod_p(T1, sub_ws); + + if(m_curve.a_is_zero()) + { + // if a == 0 then 3*x^2 + a*z^4 is just 3*x^2 + m_curve.sqr(T4, m_coord_x, ws); // x^2 + T4 *= 3; // 3*x^2 + m_curve.redc_mod_p(T4, sub_ws); + } + else if(m_curve.a_is_minus_3()) + { + /* + if a == -3 then + 3*x^2 + a*z^4 == 3*x^2 - 3*z^4 == 3*(x^2-z^4) == 3*(x-z^2)*(x+z^2) + */ + m_curve.sqr(T3, m_coord_z, ws); // z^2 + + // (x-z^2) + T2 = m_coord_x; + T2.mod_sub(T3, p, sub_ws); + + // (x+z^2) + T3.mod_add(m_coord_x, p, sub_ws); + + m_curve.mul(T4, T2, T3, ws); // (x-z^2)*(x+z^2) + + T4 *= 3; // 3*(x-z^2)*(x+z^2) + m_curve.redc_mod_p(T4, sub_ws); + } + else + { + m_curve.sqr(T3, m_coord_z, ws); // z^2 + m_curve.sqr(T4, T3, ws); // z^4 + m_curve.mul(T3, m_curve.get_a_rep(), T4, ws); // a*z^4 + + m_curve.sqr(T4, m_coord_x, ws); // x^2 + T4 *= 3; // 3*x^2 + T4.mod_add(T3, p, sub_ws); // 3*x^2 + a*z^4 + } + + m_curve.sqr(T2, T4, ws); + T2.mod_sub(T1, p, sub_ws); + T2.mod_sub(T1, p, sub_ws); + + m_curve.sqr(T3, T0, ws); + T3 <<= 3; + m_curve.redc_mod_p(T3, sub_ws); + + T1.mod_sub(T2, p, sub_ws); + + m_curve.mul(T0, T4, T1, ws); + T0.mod_sub(T3, p, sub_ws); + + m_coord_x = T2; + + m_curve.mul(T2, m_coord_y, m_coord_z, ws); + T2 <<= 1; + m_curve.redc_mod_p(T2, sub_ws); + + m_coord_y = T0; + m_coord_z = T2; + } + +// arithmetic operators +PointGFp& PointGFp::operator+=(const PointGFp& rhs) + { + std::vector ws(PointGFp::WORKSPACE_SIZE); + add(rhs, ws); + return *this; + } + +PointGFp& PointGFp::operator-=(const PointGFp& rhs) + { + PointGFp minus_rhs = PointGFp(rhs).negate(); + + if(is_zero()) + *this = minus_rhs; + else + *this += minus_rhs; + + return *this; + } + +PointGFp& PointGFp::operator*=(const BigInt& scalar) + { + *this = scalar * *this; + return *this; + } + +PointGFp operator*(const BigInt& scalar, const PointGFp& point) + { + BOTAN_DEBUG_ASSERT(point.on_the_curve()); + + const size_t scalar_bits = scalar.bits(); + + std::vector ws(PointGFp::WORKSPACE_SIZE); + + PointGFp R[2] = { point.zero(), point }; + + for(size_t i = scalar_bits; i > 0; i--) + { + const size_t b = scalar.get_bit(i - 1); + R[b ^ 1].add(R[b], ws); + R[b].mult2(ws); + } + + if(scalar.is_negative()) + R[0].negate(); + + BOTAN_DEBUG_ASSERT(R[0].on_the_curve()); + + return R[0]; + } + +//static +void PointGFp::force_all_affine(std::vector& points, + secure_vector& ws) + { + if(points.size() <= 1) + { + for(size_t i = 0; i != points.size(); ++i) + points[i].force_affine(); + return; + } + + /* + For >= 2 points use Montgomery's trick + + See Algorithm 2.26 in "Guide to Elliptic Curve Cryptography" + (Hankerson, Menezes, Vanstone) + + TODO is it really necessary to save all k points in c? + */ + + const CurveGFp& curve = points[0].m_curve; + const BigInt& rep_1 = curve.get_1_rep(); + + if(ws.size() < curve.get_ws_size()) + ws.resize(curve.get_ws_size()); + + std::vector c(points.size()); + c[0] = points[0].m_coord_z; + + for(size_t i = 1; i != points.size(); ++i) + { + curve.mul(c[i], c[i-1], points[i].m_coord_z, ws); + } + + BigInt s_inv = curve.invert_element(c[c.size()-1], ws); + + BigInt z_inv, z2_inv, z3_inv; + + for(size_t i = points.size() - 1; i != 0; i--) + { + PointGFp& point = points[i]; + + curve.mul(z_inv, s_inv, c[i-1], ws); + + s_inv = curve.mul_to_tmp(s_inv, point.m_coord_z, ws); + + curve.sqr(z2_inv, z_inv, ws); + curve.mul(z3_inv, z2_inv, z_inv, ws); + point.m_coord_x = curve.mul_to_tmp(point.m_coord_x, z2_inv, ws); + point.m_coord_y = curve.mul_to_tmp(point.m_coord_y, z3_inv, ws); + point.m_coord_z = rep_1; + } + + curve.sqr(z2_inv, s_inv, ws); + curve.mul(z3_inv, z2_inv, s_inv, ws); + points[0].m_coord_x = curve.mul_to_tmp(points[0].m_coord_x, z2_inv, ws); + points[0].m_coord_y = curve.mul_to_tmp(points[0].m_coord_y, z3_inv, ws); + points[0].m_coord_z = rep_1; + } + +void PointGFp::force_affine() + { + if(is_zero()) + throw Invalid_State("Cannot convert zero ECC point to affine"); + + secure_vector ws; + + const BigInt z_inv = m_curve.invert_element(m_coord_z, ws); + const BigInt z2_inv = m_curve.sqr_to_tmp(z_inv, ws); + const BigInt z3_inv = m_curve.mul_to_tmp(z_inv, z2_inv, ws); + m_coord_x = m_curve.mul_to_tmp(m_coord_x, z2_inv, ws); + m_coord_y = m_curve.mul_to_tmp(m_coord_y, z3_inv, ws); + m_coord_z = m_curve.get_1_rep(); + } + +bool PointGFp::is_affine() const + { + return m_curve.is_one(m_coord_z); + } + +BigInt PointGFp::get_affine_x() const + { + if(is_zero()) + throw Illegal_Transformation("Cannot convert zero point to affine"); + + secure_vector monty_ws; + + if(is_affine()) + return m_curve.from_rep(m_coord_x, monty_ws); + + BigInt z2 = m_curve.sqr_to_tmp(m_coord_z, monty_ws); + z2 = m_curve.invert_element(z2, monty_ws); + + BigInt r; + m_curve.mul(r, m_coord_x, z2, monty_ws); + m_curve.from_rep(r, monty_ws); + return r; + } + +BigInt PointGFp::get_affine_y() const + { + if(is_zero()) + throw Illegal_Transformation("Cannot convert zero point to affine"); + + secure_vector monty_ws; + + if(is_affine()) + return m_curve.from_rep(m_coord_y, monty_ws); + + const BigInt z2 = m_curve.sqr_to_tmp(m_coord_z, monty_ws); + const BigInt z3 = m_curve.mul_to_tmp(m_coord_z, z2, monty_ws); + const BigInt z3_inv = m_curve.invert_element(z3, monty_ws); + + BigInt r; + m_curve.mul(r, m_coord_y, z3_inv, monty_ws); + m_curve.from_rep(r, monty_ws); + return r; + } + +bool PointGFp::on_the_curve() const + { + /* + Is the point still on the curve?? (If everything is correct, the + point is always on its curve; then the function will return true. + If somehow the state is corrupted, which suggests a fault attack + (or internal computational error), then return false. + */ + if(is_zero()) + return true; + + secure_vector monty_ws; + + const BigInt y2 = m_curve.from_rep(m_curve.sqr_to_tmp(m_coord_y, monty_ws), monty_ws); + const BigInt x3 = m_curve.mul_to_tmp(m_coord_x, m_curve.sqr_to_tmp(m_coord_x, monty_ws), monty_ws); + const BigInt ax = m_curve.mul_to_tmp(m_coord_x, m_curve.get_a_rep(), monty_ws); + const BigInt z2 = m_curve.sqr_to_tmp(m_coord_z, monty_ws); + + if(m_coord_z == z2) // Is z equal to 1 (in Montgomery form)? + { + if(y2 != m_curve.from_rep(x3 + ax + m_curve.get_b_rep(), monty_ws)) + return false; + } + + const BigInt z3 = m_curve.mul_to_tmp(m_coord_z, z2, monty_ws); + const BigInt ax_z4 = m_curve.mul_to_tmp(ax, m_curve.sqr_to_tmp(z2, monty_ws), monty_ws); + const BigInt b_z6 = m_curve.mul_to_tmp(m_curve.get_b_rep(), m_curve.sqr_to_tmp(z3, monty_ws), monty_ws); + + if(y2 != m_curve.from_rep(x3 + ax_z4 + b_z6, monty_ws)) + return false; + + return true; + } + +// swaps the states of *this and other, does not throw! +void PointGFp::swap(PointGFp& other) + { + m_curve.swap(other.m_curve); + m_coord_x.swap(other.m_coord_x); + m_coord_y.swap(other.m_coord_y); + m_coord_z.swap(other.m_coord_z); + } + +bool PointGFp::operator==(const PointGFp& other) const + { + if(m_curve != other.m_curve) + return false; + + // If this is zero, only equal if other is also zero + if(is_zero()) + return other.is_zero(); + + return (get_affine_x() == other.get_affine_x() && + get_affine_y() == other.get_affine_y()); + } + +// encoding and decoding +std::vector PointGFp::encode(PointGFp::Compression_Type format) const + { + if(is_zero()) + return std::vector(1); // single 0 byte + + const size_t p_bytes = m_curve.get_p().bytes(); + + const BigInt x = get_affine_x(); + const BigInt y = get_affine_y(); + + std::vector result; + + if(format == PointGFp::UNCOMPRESSED) + { + result.resize(1 + 2*p_bytes); + result[0] = 0x04; + BigInt::encode_1363(&result[1], p_bytes, x); + BigInt::encode_1363(&result[1+p_bytes], p_bytes, y); + } + else if(format == PointGFp::COMPRESSED) + { + result.resize(1 + p_bytes); + result[0] = 0x02 | static_cast(y.get_bit(0)); + BigInt::encode_1363(&result[1], p_bytes, x); + } + else if(format == PointGFp::HYBRID) + { + result.resize(1 + 2*p_bytes); + result[0] = 0x06 | static_cast(y.get_bit(0)); + BigInt::encode_1363(&result[1], p_bytes, x); + BigInt::encode_1363(&result[1+p_bytes], p_bytes, y); + } + else + throw Invalid_Argument("EC2OSP illegal point encoding"); + + return result; + } + +namespace { + +BigInt decompress_point(bool yMod2, + const BigInt& x, + const BigInt& curve_p, + const BigInt& curve_a, + const BigInt& curve_b) + { + BigInt xpow3 = x * x * x; + + BigInt g = curve_a * x; + g += xpow3; + g += curve_b; + g = g % curve_p; + + BigInt z = ressol(g, curve_p); + + if(z < 0) + throw Illegal_Point("error during EC point decompression"); + + if(z.get_bit(0) != yMod2) + z = curve_p - z; + + return z; + } + +} + +PointGFp OS2ECP(const uint8_t data[], size_t data_len, + const CurveGFp& curve) + { + // Should we really be doing this? + if(data_len <= 1) + return PointGFp(curve); // return zero + + std::pair xy = OS2ECP(data, data_len, curve.get_p(), curve.get_a(), curve.get_b()); + + PointGFp point(curve, xy.first, xy.second); + + if(!point.on_the_curve()) + throw Illegal_Point("OS2ECP: Decoded point was not on the curve"); + + return point; + } + +std::pair OS2ECP(const uint8_t data[], size_t data_len, + const BigInt& curve_p, + const BigInt& curve_a, + const BigInt& curve_b) + { + if(data_len <= 1) + throw Decoding_Error("OS2ECP invalid point"); + + const uint8_t pc = data[0]; + + BigInt x, y; + + if(pc == 2 || pc == 3) + { + //compressed form + x = BigInt::decode(&data[1], data_len - 1); + + const bool y_mod_2 = ((pc & 0x01) == 1); + y = decompress_point(y_mod_2, x, curve_p, curve_a, curve_b); + } + else if(pc == 4) + { + const size_t l = (data_len - 1) / 2; + + // uncompressed form + x = BigInt::decode(&data[1], l); + y = BigInt::decode(&data[l+1], l); + } + else if(pc == 6 || pc == 7) + { + const size_t l = (data_len - 1) / 2; + + // hybrid form + x = BigInt::decode(&data[1], l); + y = BigInt::decode(&data[l+1], l); + + const bool y_mod_2 = ((pc & 0x01) == 1); + + if(decompress_point(y_mod_2, x, curve_p, curve_a, curve_b) != y) + throw Illegal_Point("OS2ECP: Decoding error in hybrid format"); + } + else + throw Invalid_Argument("OS2ECP: Unknown format type " + std::to_string(pc)); + + return std::make_pair(x, y); + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/ec_group/point_gfp.h b/src/libs/3rdparty/botan/src/lib/pubkey/ec_group/point_gfp.h new file mode 100644 index 0000000000..fa447bf87a --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pubkey/ec_group/point_gfp.h @@ -0,0 +1,444 @@ +/* +* Point arithmetic on elliptic curves over GF(p) +* +* (C) 2007 Martin Doering, Christoph Ludwig, Falko Strenzke +* 2008-2011,2014,2015 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_POINT_GFP_H_ +#define BOTAN_POINT_GFP_H_ + +#include +#include +#include + +namespace Botan { + +/** +* Exception thrown if you try to convert a zero point to an affine +* coordinate +*/ +class BOTAN_PUBLIC_API(2,0) Illegal_Transformation final : public Exception + { + public: + explicit Illegal_Transformation(const std::string& err = + "Requested transformation is not possible") : + Exception(err) {} + }; + +/** +* Exception thrown if some form of illegal point is decoded +*/ +class BOTAN_PUBLIC_API(2,0) Illegal_Point final : public Exception + { + public: + explicit Illegal_Point(const std::string& err = "Malformed ECP point detected") : + Exception(err) {} + }; + +/** +* This class represents one point on a curve of GF(p) +*/ +class BOTAN_PUBLIC_API(2,0) PointGFp final + { + public: + enum Compression_Type { + UNCOMPRESSED = 0, + COMPRESSED = 1, + HYBRID = 2 + }; + + enum { WORKSPACE_SIZE = 8 }; + + /** + * Construct an uninitialized PointGFp + */ + PointGFp() = default; + + /** + * Construct the zero point + * @param curve The base curve + */ + explicit PointGFp(const CurveGFp& curve); + + /** + * Copy constructor + */ + PointGFp(const PointGFp&) = default; + + /** + * Move Constructor + */ + PointGFp(PointGFp&& other) + { + this->swap(other); + } + + /** + * Standard Assignment + */ + PointGFp& operator=(const PointGFp&) = default; + + /** + * Move Assignment + */ + PointGFp& operator=(PointGFp&& other) + { + if(this != &other) + this->swap(other); + return (*this); + } + + /** + * Construct a point from its affine coordinates + * @param curve the base curve + * @param x affine x coordinate + * @param y affine y coordinate + */ + PointGFp(const CurveGFp& curve, const BigInt& x, const BigInt& y); + + /** + * EC2OSP - elliptic curve to octet string primitive + * @param format which format to encode using + */ + std::vector encode(PointGFp::Compression_Type format) const; + + /** + * += Operator + * @param rhs the PointGFp to add to the local value + * @result resulting PointGFp + */ + PointGFp& operator+=(const PointGFp& rhs); + + /** + * -= Operator + * @param rhs the PointGFp to subtract from the local value + * @result resulting PointGFp + */ + PointGFp& operator-=(const PointGFp& rhs); + + /** + * *= Operator + * @param scalar the PointGFp to multiply with *this + * @result resulting PointGFp + */ + PointGFp& operator*=(const BigInt& scalar); + + /** + * Negate this point + * @return *this + */ + PointGFp& negate() + { + if(!is_zero()) + m_coord_y = m_curve.get_p() - m_coord_y; + return *this; + } + + /** + * get affine x coordinate + * @result affine x coordinate + */ + BigInt get_affine_x() const; + + /** + * get affine y coordinate + * @result affine y coordinate + */ + BigInt get_affine_y() const; + + const BigInt& get_x() const { return m_coord_x; } + const BigInt& get_y() const { return m_coord_y; } + const BigInt& get_z() const { return m_coord_z; } + + void swap_coords(BigInt& new_x, BigInt& new_y, BigInt& new_z) + { + m_coord_x.swap(new_x); + m_coord_y.swap(new_y); + m_coord_z.swap(new_z); + } + + /** + * Force this point to affine coordinates + */ + void force_affine(); + + /** + * Force all points on the list to affine coordinates + */ + static void force_all_affine(std::vector& points, + secure_vector& ws); + + bool is_affine() const; + + /** + * Is this the point at infinity? + * @result true, if this point is at infinity, false otherwise. + */ + bool is_zero() const + { return (m_coord_x.is_zero() && m_coord_z.is_zero()); } + + /** + * Checks whether the point is to be found on the underlying + * curve; used to prevent fault attacks. + * @return if the point is on the curve + */ + bool on_the_curve() const; + + /** + * swaps the states of *this and other, does not throw! + * @param other the object to swap values with + */ + void swap(PointGFp& other); + + /** + * Randomize the point representation + * The actual value (get_affine_x, get_affine_y) does not change + */ + void randomize_repr(RandomNumberGenerator& rng); + + /** + * Randomize the point representation + * The actual value (get_affine_x, get_affine_y) does not change + */ + void randomize_repr(RandomNumberGenerator& rng, secure_vector& ws); + + /** + * Equality operator + */ + bool operator==(const PointGFp& other) const; + + /** + * Point addition + * @param other the point to add to *this + * @param workspace temp space, at least WORKSPACE_SIZE elements + */ + void add(const PointGFp& other, std::vector& workspace) + { + BOTAN_ASSERT_NOMSG(m_curve == other.m_curve); + + const size_t p_words = m_curve.get_p_words(); + + add(other.m_coord_x.data(), std::min(p_words, other.m_coord_x.size()), + other.m_coord_y.data(), std::min(p_words, other.m_coord_y.size()), + other.m_coord_z.data(), std::min(p_words, other.m_coord_z.size()), + workspace); + } + + /** + * Point addition. Array version. + * + * @param x_words the words of the x coordinate of the other point + * @param x_size size of x_words + * @param y_words the words of the y coordinate of the other point + * @param y_size size of y_words + * @param z_words the words of the z coordinate of the other point + * @param z_size size of z_words + * @param workspace temp space, at least WORKSPACE_SIZE elements + */ + void add(const word x_words[], size_t x_size, + const word y_words[], size_t y_size, + const word z_words[], size_t z_size, + std::vector& workspace); + + /** + * Point addition - mixed J+A + * @param other affine point to add - assumed to be affine! + * @param workspace temp space, at least WORKSPACE_SIZE elements + */ + void add_affine(const PointGFp& other, std::vector& workspace) + { + BOTAN_ASSERT_NOMSG(m_curve == other.m_curve); + BOTAN_DEBUG_ASSERT(other.is_affine()); + + const size_t p_words = m_curve.get_p_words(); + add_affine(other.m_coord_x.data(), std::min(p_words, other.m_coord_x.size()), + other.m_coord_y.data(), std::min(p_words, other.m_coord_y.size()), + workspace); + } + + /** + * Point addition - mixed J+A. Array version. + * + * @param x_words the words of the x coordinate of the other point + * @param x_size size of x_words + * @param y_words the words of the y coordinate of the other point + * @param y_size size of y_words + * @param workspace temp space, at least WORKSPACE_SIZE elements + */ + void add_affine(const word x_words[], size_t x_size, + const word y_words[], size_t y_size, + std::vector& workspace); + + /** + * Point doubling + * @param workspace temp space, at least WORKSPACE_SIZE elements + */ + void mult2(std::vector& workspace); + + /** + * Repeated point doubling + * @param i number of doublings to perform + * @param workspace temp space, at least WORKSPACE_SIZE elements + */ + void mult2i(size_t i, std::vector& workspace); + + /** + * Point addition + * @param other the point to add to *this + * @param workspace temp space, at least WORKSPACE_SIZE elements + * @return other plus *this + */ + PointGFp plus(const PointGFp& other, std::vector& workspace) const + { + PointGFp x = (*this); + x.add(other, workspace); + return x; + } + + /** + * Point doubling + * @param workspace temp space, at least WORKSPACE_SIZE elements + * @return *this doubled + */ + PointGFp double_of(std::vector& workspace) const + { + PointGFp x = (*this); + x.mult2(workspace); + return x; + } + + /** + * Return the zero (aka infinite) point associated with this curve + */ + PointGFp zero() const { return PointGFp(m_curve); } + + /** + * Return base curve of this point + * @result the curve over GF(p) of this point + * + * You should not need to use this + */ + const CurveGFp& get_curve() const { return m_curve; } + + private: + CurveGFp m_curve; + BigInt m_coord_x, m_coord_y, m_coord_z; + }; + +/** +* Point multiplication operator +* @param scalar the scalar value +* @param point the point value +* @return scalar*point on the curve +*/ +BOTAN_PUBLIC_API(2,0) PointGFp operator*(const BigInt& scalar, const PointGFp& point); + +/** +* ECC point multiexponentiation - not constant time! +* @param p1 a point +* @param z1 a scalar +* @param p2 a point +* @param z2 a scalar +* @result (p1 * z1 + p2 * z2) +*/ +BOTAN_PUBLIC_API(2,0) PointGFp multi_exponentiate( + const PointGFp& p1, const BigInt& z1, + const PointGFp& p2, const BigInt& z2); + +// relational operators +inline bool operator!=(const PointGFp& lhs, const PointGFp& rhs) + { + return !(rhs == lhs); + } + +// arithmetic operators +inline PointGFp operator-(const PointGFp& lhs) + { + return PointGFp(lhs).negate(); + } + +inline PointGFp operator+(const PointGFp& lhs, const PointGFp& rhs) + { + PointGFp tmp(lhs); + return tmp += rhs; + } + +inline PointGFp operator-(const PointGFp& lhs, const PointGFp& rhs) + { + PointGFp tmp(lhs); + return tmp -= rhs; + } + +inline PointGFp operator*(const PointGFp& point, const BigInt& scalar) + { + return scalar * point; + } + +// encoding and decoding +inline secure_vector BOTAN_DEPRECATED("Use PointGFp::encode") + EC2OSP(const PointGFp& point, uint8_t format) + { + std::vector enc = point.encode(static_cast(format)); + return secure_vector(enc.begin(), enc.end()); + } + +/** +* Perform point decoding +* Use EC_Group::OS2ECP instead +*/ +PointGFp BOTAN_PUBLIC_API(2,0) OS2ECP(const uint8_t data[], size_t data_len, + const CurveGFp& curve); + +/** +* Perform point decoding +* Use EC_Group::OS2ECP instead +* +* @param data the encoded point +* @param data_len length of data in bytes +* @param curve_p the curve equation prime +* @param curve_a the curve equation a parameter +* @param curve_b the curve equation b parameter +*/ +std::pair BOTAN_UNSTABLE_API OS2ECP(const uint8_t data[], size_t data_len, + const BigInt& curve_p, + const BigInt& curve_a, + const BigInt& curve_b); + +template +PointGFp OS2ECP(const std::vector& data, const CurveGFp& curve) + { return OS2ECP(data.data(), data.size(), curve); } + +class PointGFp_Var_Point_Precompute; + +/** +* Deprecated API for point multiplication +* Use EC_Group::blinded_base_point_multiply or EC_Group::blinded_var_point_multiply +*/ +class BOTAN_PUBLIC_API(2,0) BOTAN_DEPRECATED("See comments") Blinded_Point_Multiply final + { + public: + Blinded_Point_Multiply(const PointGFp& base, const BigInt& order, size_t h = 0); + + ~Blinded_Point_Multiply(); + + PointGFp blinded_multiply(const BigInt& scalar, RandomNumberGenerator& rng); + private: + std::vector m_ws; + const BigInt& m_order; + std::unique_ptr m_point_mul; + }; + +} + +namespace std { + +template<> +inline void swap(Botan::PointGFp& x, Botan::PointGFp& y) + { x.swap(y); } + +} + +#endif 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 new file mode 100644 index 0000000000..760f060ced --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pubkey/ec_group/point_mul.cpp @@ -0,0 +1,375 @@ +/* +* (C) 2015,2018 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include +#include + +namespace Botan { + +PointGFp multi_exponentiate(const PointGFp& x, const BigInt& z1, + const PointGFp& y, const BigInt& z2) + { + PointGFp_Multi_Point_Precompute xy_mul(x, y); + return xy_mul.multi_exp(z1, z2); + } + +Blinded_Point_Multiply::Blinded_Point_Multiply(const PointGFp& base, + const BigInt& order, + size_t h) : + m_ws(PointGFp::WORKSPACE_SIZE), + m_order(order) + { + BOTAN_UNUSED(h); + Null_RNG null_rng; + m_point_mul.reset(new PointGFp_Var_Point_Precompute(base, null_rng, m_ws)); + } + +Blinded_Point_Multiply::~Blinded_Point_Multiply() + { + /* for ~unique_ptr */ + } + +PointGFp Blinded_Point_Multiply::blinded_multiply(const BigInt& scalar, + RandomNumberGenerator& rng) + { + return m_point_mul->mul(scalar, rng, m_order, m_ws); + } + +PointGFp_Base_Point_Precompute::PointGFp_Base_Point_Precompute(const PointGFp& base, + const Modular_Reducer& mod_order) : + m_base_point(base), + m_mod_order(mod_order), + m_p_words(base.get_curve().get_p().sig_words()), + m_T_size(base.get_curve().get_p().bits() + PointGFp_SCALAR_BLINDING_BITS + 1) + { + std::vector ws(PointGFp::WORKSPACE_SIZE); + + const size_t p_bits = base.get_curve().get_p().bits(); + + /* + * Some of the curves (eg secp160k1) have an order slightly larger than + * the size of the prime modulus. In all cases they are at most 1 bit + * longer. The +1 compensates for this. + */ + const size_t T_bits = round_up(p_bits + PointGFp_SCALAR_BLINDING_BITS + 1, 2) / 2; + + std::vector T(3*T_bits); + T.resize(3*T_bits); + + T[0] = base; + T[1] = T[0]; + T[1].mult2(ws); + T[2] = T[1]; + T[2].add(T[0], ws); + + for(size_t i = 1; i != T_bits; ++i) + { + T[3*i+0] = T[3*i - 2]; + T[3*i+0].mult2(ws); + T[3*i+1] = T[3*i+0]; + T[3*i+1].mult2(ws); + T[3*i+2] = T[3*i+1]; + T[3*i+2].add(T[3*i+0], ws); + } + + PointGFp::force_all_affine(T, ws[0].get_word_vector()); + + m_W.resize(T.size() * 2 * m_p_words); + + word* p = &m_W[0]; + for(size_t i = 0; i != T.size(); ++i) + { + T[i].get_x().encode_words(p, m_p_words); + p += m_p_words; + T[i].get_y().encode_words(p, m_p_words); + p += m_p_words; + } + } + +PointGFp PointGFp_Base_Point_Precompute::mul(const BigInt& k, + RandomNumberGenerator& rng, + const BigInt& group_order, + std::vector& ws) const + { + if(k.is_negative()) + throw Invalid_Argument("PointGFp_Base_Point_Precompute scalar must be positive"); + + // Choose a small mask m and use k' = k + m*order (Coron's 1st countermeasure) + const BigInt mask(rng, PointGFp_SCALAR_BLINDING_BITS); + + // Instead of reducing k mod group order should we alter the mask size?? + const BigInt scalar = m_mod_order.reduce(k) + group_order * mask; + + const size_t windows = round_up(scalar.bits(), 2) / 2; + + const size_t elem_size = 2*m_p_words; + + BOTAN_ASSERT(windows <= m_W.size() / (3*elem_size), + "Precomputed sufficient values for scalar mult"); + + PointGFp R = m_base_point.zero(); + + if(ws.size() < PointGFp::WORKSPACE_SIZE) + ws.resize(PointGFp::WORKSPACE_SIZE); + + // the precomputed multiples are not secret so use std::vector + std::vector Wt(elem_size); + + for(size_t i = 0; i != windows; ++i) + { + const size_t window = windows - i - 1; + const size_t base_addr = (3*window)*elem_size; + + const word w = scalar.get_substring(2*window, 2); + + const word w_is_1 = CT::is_equal(w, 1); + const word w_is_2 = CT::is_equal(w, 2); + const word w_is_3 = CT::is_equal(w, 3); + + for(size_t j = 0; j != elem_size; ++j) + { + const word w1 = m_W[base_addr + 0*elem_size + j]; + const word w2 = m_W[base_addr + 1*elem_size + j]; + const word w3 = m_W[base_addr + 2*elem_size + j]; + + Wt[j] = CT::select3(w_is_1, w1, w_is_2, w2, w_is_3, w3, 0); + } + + R.add_affine(&Wt[0], m_p_words, &Wt[m_p_words], m_p_words, ws); + + if(i == 0) + { + /* + * Since we start with the top bit of the exponent we know the + * first window must have a non-zero element, and thus R is + * now a point other than the point at infinity. + */ + BOTAN_DEBUG_ASSERT(w != 0); + R.randomize_repr(rng, ws[0].get_word_vector()); + } + } + + BOTAN_DEBUG_ASSERT(R.on_the_curve()); + + return R; + } + +PointGFp_Var_Point_Precompute::PointGFp_Var_Point_Precompute(const PointGFp& point, + RandomNumberGenerator& rng, + std::vector& ws) : + m_curve(point.get_curve()), + m_p_words(m_curve.get_p().sig_words()), + m_window_bits(4) + { + if(ws.size() < PointGFp::WORKSPACE_SIZE) + ws.resize(PointGFp::WORKSPACE_SIZE); + + std::vector U(1U << m_window_bits); + U[0] = point.zero(); + U[1] = point; + + for(size_t i = 2; i < U.size(); i += 2) + { + U[i] = U[i/2].double_of(ws); + U[i+1] = U[i].plus(point, ws); + } + + // Hack to handle Blinded_Point_Multiply + if(rng.is_seeded()) + { + BigInt& mask = ws[0]; + BigInt& mask2 = ws[1]; + BigInt& mask3 = ws[2]; + BigInt& new_x = ws[3]; + BigInt& new_y = ws[4]; + BigInt& new_z = ws[5]; + secure_vector& tmp = ws[6].get_word_vector(); + + const CurveGFp& curve = U[0].get_curve(); + + const size_t p_bits = curve.get_p().bits(); + + // Skipping zero point since it can't be randomized + for(size_t i = 1; i != U.size(); ++i) + { + mask.randomize(rng, p_bits - 1, false); + // Easy way of ensuring mask != 0 + mask.set_bit(0); + + curve.sqr(mask2, mask, tmp); + curve.mul(mask3, mask, mask2, tmp); + + curve.mul(new_x, U[i].get_x(), mask2, tmp); + curve.mul(new_y, U[i].get_y(), mask3, tmp); + curve.mul(new_z, U[i].get_z(), mask, tmp); + + U[i].swap_coords(new_x, new_y, new_z); + } + } + + m_T.resize(U.size() * 3 * m_p_words); + + word* p = &m_T[0]; + for(size_t i = 0; i != U.size(); ++i) + { + U[i].get_x().encode_words(p , m_p_words); + U[i].get_y().encode_words(p + m_p_words, m_p_words); + U[i].get_z().encode_words(p + 2*m_p_words, m_p_words); + p += 3*m_p_words; + } + } + +PointGFp PointGFp_Var_Point_Precompute::mul(const BigInt& k, + RandomNumberGenerator& rng, + const BigInt& group_order, + std::vector& ws) const + { + if(k.is_negative()) + throw Invalid_Argument("PointGFp_Var_Point_Precompute scalar must be positive"); + if(ws.size() < PointGFp::WORKSPACE_SIZE) + ws.resize(PointGFp::WORKSPACE_SIZE); + + // Choose a small mask m and use k' = k + m*order (Coron's 1st countermeasure) + const BigInt mask(rng, PointGFp_SCALAR_BLINDING_BITS, false); + const BigInt scalar = k + group_order * mask; + + const size_t elem_size = 3*m_p_words; + const size_t window_elems = (1ULL << m_window_bits); + + size_t windows = round_up(scalar.bits(), m_window_bits) / m_window_bits; + PointGFp R(m_curve); + secure_vector e(elem_size); + + if(windows > 0) + { + windows--; + + const uint32_t w = scalar.get_substring(windows*m_window_bits, m_window_bits); + + clear_mem(e.data(), e.size()); + for(size_t i = 1; i != window_elems; ++i) + { + const word wmask = CT::is_equal(w, i); + + for(size_t j = 0; j != elem_size; ++j) + { + e[j] |= wmask & m_T[i * elem_size + j]; + } + } + + R.add(&e[0], m_p_words, &e[m_p_words], m_p_words, &e[2*m_p_words], m_p_words, ws); + + /* + Randomize after adding the first nibble as before the addition R + is zero, and we cannot effectively randomize the point + representation of the zero point. + */ + R.randomize_repr(rng, ws[0].get_word_vector()); + } + + while(windows) + { + R.mult2i(m_window_bits, ws); + + const uint32_t w = scalar.get_substring((windows-1)*m_window_bits, m_window_bits); + + clear_mem(e.data(), e.size()); + for(size_t i = 1; i != window_elems; ++i) + { + const word wmask = CT::is_equal(w, i); + + for(size_t j = 0; j != elem_size; ++j) + e[j] |= wmask & m_T[i * elem_size + j]; + } + + R.add(&e[0], m_p_words, &e[m_p_words], m_p_words, &e[2*m_p_words], m_p_words, ws); + + windows--; + } + + BOTAN_DEBUG_ASSERT(R.on_the_curve()); + + return R; + } + + +PointGFp_Multi_Point_Precompute::PointGFp_Multi_Point_Precompute(const PointGFp& x, + const PointGFp& y) + { + std::vector ws(PointGFp::WORKSPACE_SIZE); + + PointGFp x2 = x; + x2.mult2(ws); + + const PointGFp x3(x2.plus(x, ws)); + + PointGFp y2 = y; + y2.mult2(ws); + + const PointGFp y3(y2.plus(y, ws)); + + m_M.reserve(15); + + m_M.push_back(x); + m_M.push_back(x2); + m_M.push_back(x3); + + m_M.push_back(y); + m_M.push_back(y.plus(x, ws)); + m_M.push_back(y.plus(x2, ws)); + m_M.push_back(y.plus(x3, ws)); + + m_M.push_back(y2); + m_M.push_back(y2.plus(x, ws)); + m_M.push_back(y2.plus(x2, ws)); + m_M.push_back(y2.plus(x3, ws)); + + m_M.push_back(y3); + m_M.push_back(y3.plus(x, ws)); + m_M.push_back(y3.plus(x2, ws)); + m_M.push_back(y3.plus(x3, ws)); + + PointGFp::force_all_affine(m_M, ws[0].get_word_vector()); + } + +PointGFp PointGFp_Multi_Point_Precompute::multi_exp(const BigInt& z1, + const BigInt& z2) const + { + std::vector ws(PointGFp::WORKSPACE_SIZE); + + const size_t z_bits = round_up(std::max(z1.bits(), z2.bits()), 2); + + PointGFp H = m_M[0].zero(); + + for(size_t i = 0; i != z_bits; i += 2) + { + if(i > 0) + { + 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 uint8_t z12 = (4*z2_b) + z1_b; + + // This function is not intended to be const time + if(z12) + { + H.add_affine(m_M[z12-1], ws); + } + } + + if(z1.is_negative() != z2.is_negative()) + H.negate(); + + return H; + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/ec_group/point_mul.h b/src/libs/3rdparty/botan/src/lib/pubkey/ec_group/point_mul.h new file mode 100644 index 0000000000..dbaae29950 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pubkey/ec_group/point_mul.h @@ -0,0 +1,84 @@ +/* +* (C) 2018 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_POINT_MUL_H_ +#define BOTAN_POINT_MUL_H_ + +#include + +namespace Botan { + +class Modular_Reducer; + +static const size_t PointGFp_SCALAR_BLINDING_BITS = 80; + +class PointGFp_Base_Point_Precompute final + { + public: + PointGFp_Base_Point_Precompute(const PointGFp& base_point, + const Modular_Reducer& mod_order); + + PointGFp mul(const BigInt& k, + RandomNumberGenerator& rng, + const BigInt& group_order, + std::vector& ws) const; + private: + const PointGFp& m_base_point; + const Modular_Reducer& m_mod_order; + + const size_t m_p_words; + const size_t m_T_size; + + /* + * This is a table of T_size * 3*p_word words + */ + std::vector m_W; + }; + +class PointGFp_Var_Point_Precompute final + { + public: + PointGFp_Var_Point_Precompute(const PointGFp& point, + RandomNumberGenerator& rng, + std::vector& ws); + + PointGFp mul(const BigInt& k, + RandomNumberGenerator& rng, + const BigInt& group_order, + std::vector& ws) const; + private: + const CurveGFp m_curve; + const size_t m_p_words; + const size_t m_window_bits; + + /* + * Table of 2^window_bits * 3*2*p_word words + * Kept in locked vector since the base point might be sensitive + * (normally isn't in most protocols but hard to say anything + * categorically.) + */ + secure_vector m_T; + }; + +class PointGFp_Multi_Point_Precompute final + { + public: + PointGFp_Multi_Point_Precompute(const PointGFp& g1, + const PointGFp& g2); + + /* + * Return (g1*k1 + g2*k2) + * Not constant time, intended to use with public inputs + */ + PointGFp multi_exp(const BigInt& k1, + const BigInt& k2) const; + private: + std::vector m_M; + }; + +} + +#endif 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 new file mode 100644 index 0000000000..2c23c1b47e --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pubkey/ecc_key/ecc_key.cpp @@ -0,0 +1,201 @@ +/* +* ECC Key implemenation +* (C) 2007 Manuel Hartl, FlexSecure GmbH +* Falko Strenzke, FlexSecure GmbH +* 2008-2010 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include +#include +#include +#include + +namespace Botan { + +size_t EC_PublicKey::key_length() const + { + return domain().get_p_bits(); + } + +size_t EC_PublicKey::estimated_strength() const + { + return ecp_work_factor(key_length()); + } + +EC_PublicKey::EC_PublicKey(const EC_Group& dom_par, + const PointGFp& pub_point) : + m_domain_params(dom_par), m_public_key(pub_point) + { + if (!dom_par.get_curve_oid().empty()) + m_domain_encoding = EC_DOMPAR_ENC_OID; + else + m_domain_encoding = EC_DOMPAR_ENC_EXPLICIT; + +#if 0 + if(domain().get_curve() != public_point().get_curve()) + throw Invalid_Argument("EC_PublicKey: curve mismatch in constructor"); +#endif + } + +EC_PublicKey::EC_PublicKey(const AlgorithmIdentifier& alg_id, + const std::vector& key_bits) : + m_domain_params{EC_Group(alg_id.get_parameters())}, + m_public_key{domain().OS2ECP(key_bits)} + { + if (!domain().get_curve_oid().empty()) + m_domain_encoding = EC_DOMPAR_ENC_OID; + else + m_domain_encoding = EC_DOMPAR_ENC_EXPLICIT; + } + +bool EC_PublicKey::check_key(RandomNumberGenerator& rng, + bool) const + { + return m_domain_params.verify_group(rng) && + m_domain_params.verify_public_element(public_point()); + } + + +AlgorithmIdentifier EC_PublicKey::algorithm_identifier() const + { + return AlgorithmIdentifier(get_oid(), DER_domain()); + } + +std::vector EC_PublicKey::public_key_bits() const + { + return public_point().encode(point_encoding()); + } + +void EC_PublicKey::set_point_encoding(PointGFp::Compression_Type enc) + { + if(enc != PointGFp::COMPRESSED && + enc != PointGFp::UNCOMPRESSED && + enc != PointGFp::HYBRID) + throw Invalid_Argument("Invalid point encoding for EC_PublicKey"); + + m_point_encoding = enc; + } + +void EC_PublicKey::set_parameter_encoding(EC_Group_Encoding form) + { + if(form != EC_DOMPAR_ENC_EXPLICIT && + form != EC_DOMPAR_ENC_IMPLICITCA && + form != EC_DOMPAR_ENC_OID) + throw Invalid_Argument("Invalid encoding form for EC-key object specified"); + + if((form == EC_DOMPAR_ENC_OID) && (m_domain_params.get_curve_oid().empty())) + throw Invalid_Argument("Invalid encoding form OID specified for " + "EC-key object whose corresponding domain " + "parameters are without oid"); + + m_domain_encoding = form; + } + +const BigInt& EC_PrivateKey::private_value() const + { + if(m_private_key == 0) + throw Invalid_State("EC_PrivateKey::private_value - uninitialized"); + + return m_private_key; + } + +/** +* EC_PrivateKey constructor +*/ +EC_PrivateKey::EC_PrivateKey(RandomNumberGenerator& rng, + const EC_Group& ec_group, + const BigInt& x, + bool with_modular_inverse) + { + m_domain_params = ec_group; + if (!ec_group.get_curve_oid().empty()) + m_domain_encoding = EC_DOMPAR_ENC_OID; + else + m_domain_encoding = EC_DOMPAR_ENC_EXPLICIT; + + if(x == 0) + { + m_private_key = ec_group.random_scalar(rng); + } + else + { + m_private_key = x; + } + + // Can't use rng here because ffi load functions use Null_RNG + if(with_modular_inverse) + { + // ECKCDSA + m_public_key = domain().get_base_point() * m_domain_params.inverse_mod_order(m_private_key); + } + else + { + m_public_key = domain().get_base_point() * m_private_key; + } + + BOTAN_ASSERT(m_public_key.on_the_curve(), + "Generated public key point was on the curve"); + } + +secure_vector EC_PrivateKey::private_key_bits() const + { + return DER_Encoder() + .start_cons(SEQUENCE) + .encode(static_cast(1)) + .encode(BigInt::encode_1363(m_private_key, m_private_key.bytes()), + OCTET_STRING) + .end_cons() + .get_contents(); + } + +EC_PrivateKey::EC_PrivateKey(const AlgorithmIdentifier& alg_id, + const secure_vector& key_bits, + bool with_modular_inverse) + { + m_domain_params = EC_Group(alg_id.get_parameters()); + m_domain_encoding = EC_DOMPAR_ENC_EXPLICIT; + + if (!domain().get_curve_oid().empty()) + m_domain_encoding = EC_DOMPAR_ENC_OID; + else + m_domain_encoding = EC_DOMPAR_ENC_EXPLICIT; + + OID key_parameters; + secure_vector public_key_bits; + + BER_Decoder(key_bits) + .start_cons(SEQUENCE) + .decode_and_check(1, "Unknown version code for ECC key") + .decode_octet_string_bigint(m_private_key) + .decode_optional(key_parameters, ASN1_Tag(0), PRIVATE) + .decode_optional_string(public_key_bits, BIT_STRING, 1, PRIVATE) + .end_cons(); + + if(public_key_bits.empty()) + { + if(with_modular_inverse) + { + // ECKCDSA + m_public_key = domain().get_base_point() * m_domain_params.inverse_mod_order(m_private_key); + } + else + { + m_public_key = domain().get_base_point() * m_private_key; + } + + BOTAN_ASSERT(m_public_key.on_the_curve(), + "Public point derived from loaded key was on the curve"); + } + else + { + m_public_key = domain().OS2ECP(public_key_bits); + // OS2ECP verifies that the point is on the curve + } + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/ecc_key/ecc_key.h b/src/libs/3rdparty/botan/src/lib/pubkey/ecc_key/ecc_key.h new file mode 100644 index 0000000000..ec2b5f9be3 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pubkey/ecc_key/ecc_key.h @@ -0,0 +1,172 @@ +/* +* ECDSA +* (C) 2007 Falko Strenzke, FlexSecure GmbH +* Manuel Hartl, FlexSecure GmbH +* (C) 2008-2010 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_ECC_PUBLIC_KEY_BASE_H_ +#define BOTAN_ECC_PUBLIC_KEY_BASE_H_ + +#include +#include + +namespace Botan { + +/** +* This class represents abstract ECC public keys. When encoding a key +* via an encoder that can be accessed via the corresponding member +* functions, the key will decide upon its internally stored encoding +* information whether to encode itself with or without domain +* parameters, or using the domain parameter oid. Furthermore, a public +* key without domain parameters can be decoded. In that case, it +* cannot be used for verification until its domain parameters are set +* by calling the corresponding member function. +*/ +class BOTAN_PUBLIC_API(2,0) EC_PublicKey : public virtual Public_Key + { + public: + /** + * Create a public key. + * @param dom_par EC domain parameters + * @param pub_point public point on the curve + */ + EC_PublicKey(const EC_Group& dom_par, + const PointGFp& pub_point); + + /** + * Load a public key. + * @param alg_id the X.509 algorithm identifier + * @param key_bits DER encoded public key bits + */ + EC_PublicKey(const AlgorithmIdentifier& alg_id, + const std::vector& key_bits); + + EC_PublicKey(const EC_PublicKey& other) = default; + EC_PublicKey& operator=(const EC_PublicKey& other) = default; + virtual ~EC_PublicKey() = default; + + /** + * Get the public point of this key. + * @throw Invalid_State is thrown if the + * domain parameters of this point are not set + * @result the public point of this key + */ + const PointGFp& public_point() const { return m_public_key; } + + AlgorithmIdentifier algorithm_identifier() const override; + + std::vector public_key_bits() const override; + + bool check_key(RandomNumberGenerator& rng, + bool strong) const override; + + /** + * Get the domain parameters of this key. + * @throw Invalid_State is thrown if the + * domain parameters of this point are not set + * @result the domain parameters of this key + */ + const EC_Group& domain() const { return m_domain_params; } + + /** + * Set the domain parameter encoding to be used when encoding this key. + * @param enc the encoding to use + */ + void set_parameter_encoding(EC_Group_Encoding enc); + + /** + * Set the point encoding method to be used when encoding this key. + * @param enc the encoding to use + */ + void set_point_encoding(PointGFp::Compression_Type enc); + + /** + * Return the DER encoding of this keys domain in whatever format + * is preset for this particular key + */ + std::vector DER_domain() const + { return domain().DER_encode(domain_format()); } + + /** + * Get the domain parameter encoding to be used when encoding this key. + * @result the encoding to use + */ + EC_Group_Encoding domain_format() const + { return m_domain_encoding; } + + /** + * Get the point encoding method to be used when encoding this key. + * @result the encoding to use + */ + PointGFp::Compression_Type point_encoding() const + { return m_point_encoding; } + + size_t key_length() const override; + size_t estimated_strength() const override; + + protected: + EC_PublicKey() : m_domain_params{}, m_public_key{}, m_domain_encoding(EC_DOMPAR_ENC_EXPLICIT) + {} + + EC_Group m_domain_params; + PointGFp m_public_key; + EC_Group_Encoding m_domain_encoding; + PointGFp::Compression_Type m_point_encoding = PointGFp::UNCOMPRESSED; + }; + +/** +* This abstract class represents ECC private keys +*/ +class BOTAN_PUBLIC_API(2,0) EC_PrivateKey : public virtual EC_PublicKey, + public virtual Private_Key + { + public: + /* + * If x=0, creates a new private key in the domain + * using the given rng. If with_modular_inverse is set, + * the public key will be calculated by multiplying + * the base point with the modular inverse of + * x (as in ECGDSA and ECKCDSA), otherwise by + * multiplying directly with x (as in ECDSA). + */ + EC_PrivateKey(RandomNumberGenerator& rng, + const EC_Group& domain, + const BigInt& x, + bool with_modular_inverse=false); + + /* + * Creates a new private key object from the + * ECPrivateKey structure given in key_bits. + * If with_modular_inverse is set, + * the public key will be calculated by multiplying + * the base point with the modular inverse of + * x (as in ECGDSA and ECKCDSA), otherwise by + * multiplying directly with x (as in ECDSA). + */ + EC_PrivateKey(const AlgorithmIdentifier& alg_id, + const secure_vector& key_bits, + bool with_modular_inverse=false); + + secure_vector private_key_bits() const override; + + /** + * Get the private key value of this key object. + * @result the private key value of this key object + */ + const BigInt& private_value() const; + + EC_PrivateKey(const EC_PrivateKey& other) = default; + EC_PrivateKey& operator=(const EC_PrivateKey& other) = default; + ~EC_PrivateKey() = default; + protected: + EC_PrivateKey() = default; + + BigInt m_private_key; + }; + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/ecc_key/info.txt b/src/libs/3rdparty/botan/src/lib/pubkey/ecc_key/info.txt new file mode 100644 index 0000000000..f46c9bb544 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pubkey/ecc_key/info.txt @@ -0,0 +1,10 @@ + +ECC_PUBLIC_KEY_CRYPTO -> 20131128 + + + +asn1 +bigint +ec_group +numbertheory + diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/ecdh/ecdh.cpp b/src/libs/3rdparty/botan/src/lib/pubkey/ecdh/ecdh.cpp new file mode 100644 index 0000000000..59f245a00c --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pubkey/ecdh/ecdh.cpp @@ -0,0 +1,85 @@ +/* +* ECDH implemenation +* (C) 2007 Manuel Hartl, FlexSecure GmbH +* 2007 Falko Strenzke, FlexSecure GmbH +* 2008-2010 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include + +#if defined(BOTAN_HAS_OPENSSL) + #include +#endif + +namespace Botan { + +namespace { + +/** +* ECDH operation +*/ +class ECDH_KA_Operation final : public PK_Ops::Key_Agreement_with_KDF + { + public: + + ECDH_KA_Operation(const ECDH_PrivateKey& key, const std::string& kdf, RandomNumberGenerator& rng) : + PK_Ops::Key_Agreement_with_KDF(kdf), + m_group(key.domain()), + m_rng(rng) + { + m_l_times_priv = m_group.inverse_mod_order(m_group.get_cofactor()) * key.private_value(); + } + + secure_vector raw_agree(const uint8_t w[], size_t w_len) override + { + PointGFp input_point = m_group.get_cofactor() * m_group.OS2ECP(w, w_len); + input_point.randomize_repr(m_rng); + + const PointGFp S = m_group.blinded_var_point_multiply( + input_point, m_l_times_priv, m_rng, m_ws); + + if(S.on_the_curve() == false) + throw Internal_Error("ECDH agreed value was not on the curve"); + return BigInt::encode_1363(S.get_affine_x(), m_group.get_p_bytes()); + } + private: + const EC_Group m_group; + BigInt m_l_times_priv; + RandomNumberGenerator& m_rng; + std::vector m_ws; + }; + +} + +std::unique_ptr +ECDH_PrivateKey::create_key_agreement_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) const + { +#if defined(BOTAN_HAS_OPENSSL) + if(provider == "openssl" || provider.empty()) + { + try + { + return make_openssl_ecdh_ka_op(*this, params); + } + catch(Lookup_Error&) + { + if(provider == "openssl") + throw; + } + } +#endif + + if(provider == "base" || provider.empty()) + return std::unique_ptr(new ECDH_KA_Operation(*this, params, rng)); + + throw Provider_Not_Found(algo_name(), provider); + } + + +} diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/ecdh/ecdh.h b/src/libs/3rdparty/botan/src/lib/pubkey/ecdh/ecdh.h new file mode 100644 index 0000000000..f88955ac40 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pubkey/ecdh/ecdh.h @@ -0,0 +1,106 @@ +/* +* ECDH +* (C) 2007 Falko Strenzke, FlexSecure GmbH +* Manuel Hartl, FlexSecure GmbH +* (C) 2008-2010 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_ECDH_KEY_H_ +#define BOTAN_ECDH_KEY_H_ + +#include + +namespace Botan { + +/** +* This class represents ECDH Public Keys. +*/ +class BOTAN_PUBLIC_API(2,0) ECDH_PublicKey : public virtual EC_PublicKey + { + public: + /** + * Create an ECDH public key. + * @param alg_id algorithm identifier + * @param key_bits DER encoded public key bits + */ + ECDH_PublicKey(const AlgorithmIdentifier& alg_id, + const std::vector& key_bits) : + EC_PublicKey(alg_id, key_bits) {} + + /** + * Construct a public key from a given public point. + * @param dom_par the domain parameters associated with this key + * @param public_point the public point defining this key + */ + ECDH_PublicKey(const EC_Group& dom_par, + const PointGFp& public_point) : + EC_PublicKey(dom_par, public_point) {} + + /** + * Get this keys algorithm name. + * @return this keys algorithm name + */ + std::string algo_name() const override { return "ECDH"; } + + /** + * @return public point value + */ + std::vector public_value() const + { return public_point().encode(PointGFp::UNCOMPRESSED); } + + /** + * @return public point value + */ + std::vector public_value(PointGFp::Compression_Type format) const + { return public_point().encode(format); } + + protected: + ECDH_PublicKey() = default; + }; + +/** +* This class represents ECDH Private Keys. +*/ +class BOTAN_PUBLIC_API(2,0) ECDH_PrivateKey final : public ECDH_PublicKey, + public EC_PrivateKey, + public PK_Key_Agreement_Key + { + public: + + /** + * Load a private key. + * @param alg_id the X.509 algorithm identifier + * @param key_bits ECPrivateKey bits + */ + ECDH_PrivateKey(const AlgorithmIdentifier& alg_id, + const secure_vector& key_bits) : + EC_PrivateKey(alg_id, key_bits) {} + + /** + * Generate a new private key + * @param rng a random number generator + * @param domain parameters to used for this key + * @param x the private key; if zero, a new random key is generated + */ + ECDH_PrivateKey(RandomNumberGenerator& rng, + const EC_Group& domain, + const BigInt& x = 0) : + EC_PrivateKey(rng, domain, x) {} + + std::vector public_value() const override + { return ECDH_PublicKey::public_value(PointGFp::UNCOMPRESSED); } + + std::vector public_value(PointGFp::Compression_Type type) const + { return ECDH_PublicKey::public_value(type); } + + std::unique_ptr + create_key_agreement_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) const override; + }; + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/ecdh/info.txt b/src/libs/3rdparty/botan/src/lib/pubkey/ecdh/info.txt new file mode 100644 index 0000000000..11ca921dab --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pubkey/ecdh/info.txt @@ -0,0 +1,10 @@ + +ECDH -> 20131128 + + + +asn1 +ec_group +ecc_key +numbertheory + diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/ecdsa/ecdsa.cpp b/src/libs/3rdparty/botan/src/lib/pubkey/ecdsa/ecdsa.cpp new file mode 100644 index 0000000000..2409d8f0d2 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pubkey/ecdsa/ecdsa.cpp @@ -0,0 +1,256 @@ +/* +* ECDSA implemenation +* (C) 2007 Manuel Hartl, FlexSecure GmbH +* 2007 Falko Strenzke, FlexSecure GmbH +* 2008-2010,2015,2016,2018 Jack Lloyd +* 2016 René Korthaus +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include +#include +#include + +#if defined(BOTAN_HAS_RFC6979_GENERATOR) + #include +#endif + +#if defined(BOTAN_HAS_BEARSSL) + #include +#endif + +#if defined(BOTAN_HAS_OPENSSL) + #include +#endif + +namespace Botan { + +bool ECDSA_PrivateKey::check_key(RandomNumberGenerator& rng, + bool strong) const + { + if(!public_point().on_the_curve()) + return false; + + if(!strong) + return true; + + return KeyPair::signature_consistency_check(rng, *this, "EMSA1(SHA-256)"); + } + +namespace { + +/** +* ECDSA signature operation +*/ +class ECDSA_Signature_Operation final : public PK_Ops::Signature_with_EMSA + { + public: + + ECDSA_Signature_Operation(const ECDSA_PrivateKey& ecdsa, + const std::string& emsa, + RandomNumberGenerator& rng) : + PK_Ops::Signature_with_EMSA(emsa), + m_group(ecdsa.domain()), + m_x(ecdsa.private_value()) + { +#if defined(BOTAN_HAS_RFC6979_GENERATOR) + m_rfc6979_hash = hash_for_emsa(emsa); +#endif + + m_b = m_group.random_scalar(rng); + m_b_inv = m_group.inverse_mod_order(m_b); + } + + size_t max_input_bits() const override { return m_group.get_order_bits(); } + + secure_vector raw_sign(const uint8_t msg[], size_t msg_len, + RandomNumberGenerator& rng) override; + + private: + const EC_Group m_group; + const BigInt& m_x; + +#if defined(BOTAN_HAS_RFC6979_GENERATOR) + std::string m_rfc6979_hash; +#endif + + std::vector m_ws; + + BigInt m_b, m_b_inv; + }; + +secure_vector +ECDSA_Signature_Operation::raw_sign(const uint8_t msg[], size_t msg_len, + RandomNumberGenerator& rng) + { + BigInt m(msg, msg_len, m_group.get_order_bits()); + +#if defined(BOTAN_HAS_RFC6979_GENERATOR) + const BigInt k = generate_rfc6979_nonce(m_x, m_group.get_order(), m, m_rfc6979_hash); +#else + const BigInt k = m_group.random_scalar(rng); +#endif + + const BigInt r = m_group.mod_order( + m_group.blinded_base_point_multiply_x(k, rng, m_ws)); + + const BigInt k_inv = m_group.inverse_mod_order(k); + + /* + * Blind the input message and compute x*r+m as (x*r*b + m*b)/b + */ + 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); + + 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()) + throw Internal_Error("During ECDSA signature generated zero r/s"); + + return BigInt::encode_fixed_length_int_pair(r, s, m_group.get_order_bytes()); + } + +/** +* ECDSA verification operation +*/ +class ECDSA_Verification_Operation final : public PK_Ops::Verification_with_EMSA + { + public: + ECDSA_Verification_Operation(const ECDSA_PublicKey& ecdsa, + const std::string& emsa) : + PK_Ops::Verification_with_EMSA(emsa), + m_group(ecdsa.domain()), + m_gy_mul(m_group.get_base_point(), ecdsa.public_point()) + { + } + + size_t max_input_bits() const override { return m_group.get_order_bits(); } + + bool with_recovery() const override { return false; } + + bool verify(const uint8_t msg[], size_t msg_len, + const uint8_t sig[], size_t sig_len) override; + private: + const EC_Group m_group; + const PointGFp_Multi_Point_Precompute m_gy_mul; + }; + +bool ECDSA_Verification_Operation::verify(const uint8_t msg[], size_t msg_len, + const uint8_t sig[], size_t sig_len) + { + if(sig_len != m_group.get_order_bytes() * 2) + return false; + + const BigInt e(msg, msg_len, m_group.get_order_bits()); + + const BigInt r(sig, sig_len / 2); + const BigInt s(sig + sig_len / 2, sig_len / 2); + + if(r <= 0 || r >= m_group.get_order() || s <= 0 || s >= m_group.get_order()) + return false; + + const BigInt w = m_group.inverse_mod_order(s); + + const BigInt u1 = m_group.multiply_mod_order(m_group.mod_order(e), w); + const BigInt u2 = m_group.multiply_mod_order(r, w); + const PointGFp R = m_gy_mul.multi_exp(u1, u2); + + if(R.is_zero()) + return false; + + const BigInt v = m_group.mod_order(R.get_affine_x()); + return (v == r); + } + +} + +std::unique_ptr +ECDSA_PublicKey::create_verification_op(const std::string& params, + const std::string& provider) const + { +#if defined(BOTAN_HAS_BEARSSL) + if(provider == "bearssl" || provider.empty()) + { + try + { + return make_bearssl_ecdsa_ver_op(*this, params); + } + catch(Lookup_Error& e) + { + if(provider == "bearssl") + throw; + } + } +#endif + +#if defined(BOTAN_HAS_OPENSSL) + if(provider == "openssl" || provider.empty()) + { + try + { + return make_openssl_ecdsa_ver_op(*this, params); + } + catch(Lookup_Error& e) + { + if(provider == "openssl") + throw; + } + } +#endif + + if(provider == "base" || provider.empty()) + return std::unique_ptr(new ECDSA_Verification_Operation(*this, params)); + + throw Provider_Not_Found(algo_name(), provider); + } + +std::unique_ptr +ECDSA_PrivateKey::create_signature_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) const + { +#if defined(BOTAN_HAS_BEARSSL) + if(provider == "bearssl" || provider.empty()) + { + try + { + return make_bearssl_ecdsa_sig_op(*this, params); + } + catch(Lookup_Error& e) + { + if(provider == "bearssl") + throw; + } + } +#endif + +#if defined(BOTAN_HAS_OPENSSL) + if(provider == "openssl" || provider.empty()) + { + try + { + return make_openssl_ecdsa_sig_op(*this, params); + } + catch(Lookup_Error& e) + { + if(provider == "openssl") + throw; + } + } +#endif + + if(provider == "base" || provider.empty()) + return std::unique_ptr(new ECDSA_Signature_Operation(*this, params, rng)); + + throw Provider_Not_Found(algo_name(), provider); + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/ecdsa/ecdsa.h b/src/libs/3rdparty/botan/src/lib/pubkey/ecdsa/ecdsa.h new file mode 100644 index 0000000000..2929059c56 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pubkey/ecdsa/ecdsa.h @@ -0,0 +1,98 @@ +/* +* ECDSA +* (C) 2007 Falko Strenzke, FlexSecure GmbH +* Manuel Hartl, FlexSecure GmbH +* (C) 2008-2010 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_ECDSA_KEY_H_ +#define BOTAN_ECDSA_KEY_H_ + +#include + +namespace Botan { + +/** +* This class represents ECDSA Public Keys. +*/ +class BOTAN_PUBLIC_API(2,0) ECDSA_PublicKey : public virtual EC_PublicKey + { + public: + + /** + * Create a public key from a given public point. + * @param dom_par the domain parameters associated with this key + * @param public_point the public point defining this key + */ + ECDSA_PublicKey(const EC_Group& dom_par, + const PointGFp& public_point) : + EC_PublicKey(dom_par, public_point) {} + + /** + * Load a public key. + * @param alg_id the X.509 algorithm identifier + * @param key_bits DER encoded public key bits + */ + ECDSA_PublicKey(const AlgorithmIdentifier& alg_id, + const std::vector& key_bits) : + EC_PublicKey(alg_id, key_bits) {} + + /** + * Get this keys algorithm name. + * @result this keys algorithm name ("ECDSA") + */ + std::string algo_name() const override { return "ECDSA"; } + + size_t message_parts() const override { return 2; } + + size_t message_part_size() const override + { return domain().get_order().bytes(); } + + std::unique_ptr + create_verification_op(const std::string& params, + const std::string& provider) const override; + protected: + ECDSA_PublicKey() = default; + }; + +/** +* This class represents ECDSA Private Keys +*/ +class BOTAN_PUBLIC_API(2,0) ECDSA_PrivateKey final : public ECDSA_PublicKey, + public EC_PrivateKey + { + public: + + /** + * Load a private key + * @param alg_id the X.509 algorithm identifier + * @param key_bits ECPrivateKey bits + */ + ECDSA_PrivateKey(const AlgorithmIdentifier& alg_id, + const secure_vector& key_bits) : + EC_PrivateKey(alg_id, key_bits) {} + + /** + * Create a private key. + * @param rng a random number generator + * @param domain parameters to used for this key + * @param x the private key (if zero, generate a new random key) + */ + ECDSA_PrivateKey(RandomNumberGenerator& rng, + const EC_Group& domain, + const BigInt& x = 0) : + EC_PrivateKey(rng, domain, x) {} + + bool check_key(RandomNumberGenerator& rng, bool) const override; + + std::unique_ptr + create_signature_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) const override; + }; + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/ecdsa/info.txt b/src/libs/3rdparty/botan/src/lib/pubkey/ecdsa/info.txt new file mode 100644 index 0000000000..6bd32ca175 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pubkey/ecdsa/info.txt @@ -0,0 +1,14 @@ + +ECDSA -> 20131128 + + + +asn1 +ec_group +ecc_key +keypair +numbertheory +rng +emsa1 +sha2_32 + diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/info.txt b/src/libs/3rdparty/botan/src/lib/pubkey/info.txt new file mode 100644 index 0000000000..c6e8036e59 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pubkey/info.txt @@ -0,0 +1,31 @@ + +PUBLIC_KEY_CRYPTO -> 20131128 + + + +blinding.h +pk_algs.h +pk_keys.h +pk_ops.h +pk_ops_fwd.h +pkcs8.h +pubkey.h +workfactor.h +x509_key.h + + + +pk_ops_impl.h + + + +asn1 +bigint +kdf +pem +pk_pad +numbertheory +rng +hash +hex + diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/keypair/info.txt b/src/libs/3rdparty/botan/src/lib/pubkey/keypair/info.txt new file mode 100644 index 0000000000..ed85abf691 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pubkey/keypair/info.txt @@ -0,0 +1,6 @@ + +KEYPAIR_TESTING -> 20131128 + + + + diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/keypair/keypair.cpp b/src/libs/3rdparty/botan/src/lib/pubkey/keypair/keypair.cpp new file mode 100644 index 0000000000..e8d88e99f3 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pubkey/keypair/keypair.cpp @@ -0,0 +1,85 @@ +/* +* Keypair Checks +* (C) 1999-2010 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include + +namespace Botan { + +namespace KeyPair { + +/* +* Check an encryption key pair for consistency +*/ +bool encryption_consistency_check(RandomNumberGenerator& rng, + const Private_Key& private_key, + const Public_Key& public_key, + const std::string& padding) + { + PK_Encryptor_EME encryptor(public_key, rng, padding); + PK_Decryptor_EME decryptor(private_key, rng, padding); + + /* + Weird corner case, if the key is too small to encrypt anything at + all. This can happen with very small RSA keys with PSS + */ + if(encryptor.maximum_input_size() == 0) + return true; + + std::vector plaintext = + unlock(rng.random_vec(encryptor.maximum_input_size() - 1)); + + std::vector ciphertext = encryptor.encrypt(plaintext, rng); + if(ciphertext == plaintext) + return false; + + std::vector decrypted = unlock(decryptor.decrypt(ciphertext)); + + return (plaintext == decrypted); + } + +/* +* Check a signature key pair for consistency +*/ +bool signature_consistency_check(RandomNumberGenerator& rng, + const Private_Key& private_key, + const Public_Key& public_key, + const std::string& padding) + { + PK_Signer signer(private_key, rng, padding); + PK_Verifier verifier(public_key, padding); + + std::vector message(32); + rng.randomize(message.data(), message.size()); + + std::vector signature; + + try + { + signature = signer.sign_message(message, rng); + } + catch(Encoding_Error&) + { + return false; + } + + if(!verifier.verify_message(message, signature)) + return false; + + // Now try to check a corrupt signature, ensure it does not succeed + ++signature[0]; + + if(verifier.verify_message(message, signature)) + return false; + + return true; + } + +} + +} diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/keypair/keypair.h b/src/libs/3rdparty/botan/src/lib/pubkey/keypair/keypair.h new file mode 100644 index 0000000000..4f28f325fd --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pubkey/keypair/keypair.h @@ -0,0 +1,83 @@ +/* +* Keypair Checks +* (C) 1999-2010 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_KEYPAIR_CHECKS_H_ +#define BOTAN_KEYPAIR_CHECKS_H_ + +#include + +namespace Botan { + +namespace KeyPair { + +/** +* Tests whether the key is consistent for encryption; whether +* encrypting and then decrypting gives to the original plaintext. +* @param rng the rng to use +* @param private_key the key to test +* @param public_key the key to test +* @param padding the encryption padding method to use +* @return true if consistent otherwise false +*/ +BOTAN_PUBLIC_API(2,0) bool +encryption_consistency_check(RandomNumberGenerator& rng, + const Private_Key& private_key, + const Public_Key& public_key, + const std::string& padding); + +/** +* Tests whether the key is consistent for signatures; whether a +* signature can be created and then verified +* @param rng the rng to use +* @param private_key the key to test +* @param public_key the key to test +* @param padding the signature padding method to use +* @return true if consistent otherwise false +*/ +BOTAN_PUBLIC_API(2,0) bool +signature_consistency_check(RandomNumberGenerator& rng, + const Private_Key& private_key, + const Public_Key& public_key, + const std::string& padding); + +/** +* Tests whether the key is consistent for encryption; whether +* encrypting and then decrypting gives to the original plaintext. +* @param rng the rng to use +* @param key the key to test +* @param padding the encryption padding method to use +* @return true if consistent otherwise false +*/ +inline bool +encryption_consistency_check(RandomNumberGenerator& rng, + const Private_Key& key, + const std::string& padding) + { + return encryption_consistency_check(rng, key, key, padding); + } + +/** +* Tests whether the key is consistent for signatures; whether a +* signature can be created and then verified +* @param rng the rng to use +* @param key the key to test +* @param padding the signature padding method to use +* @return true if consistent otherwise false +*/ +inline bool +signature_consistency_check(RandomNumberGenerator& rng, + const Private_Key& key, + const std::string& padding) + { + return signature_consistency_check(rng, key, key, padding); + } + +} + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/pbes2/info.txt b/src/libs/3rdparty/botan/src/lib/pubkey/pbes2/info.txt new file mode 100644 index 0000000000..f8c6d37196 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pubkey/pbes2/info.txt @@ -0,0 +1,10 @@ + +PKCS5_PBES2 -> 20141119 + + + +asn1 +cbc +hmac +pbkdf2 + diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/pbes2/pbes2.cpp b/src/libs/3rdparty/botan/src/lib/pubkey/pbes2/pbes2.cpp new file mode 100644 index 0000000000..cfac722d7c --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pubkey/pbes2/pbes2.cpp @@ -0,0 +1,312 @@ +/* +* PKCS #5 PBES2 +* (C) 1999-2008,2014 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(BOTAN_HAS_SCRYPT) + #include +#endif + +namespace Botan { + +namespace { + +SymmetricKey derive_key(const std::string& passphrase, + const AlgorithmIdentifier& kdf_algo, + size_t default_key_size) + { + if(kdf_algo.get_oid() == OIDS::lookup("PKCS5.PBKDF2")) + { + secure_vector salt; + size_t iterations = 0, key_length = 0; + + AlgorithmIdentifier prf_algo; + BER_Decoder(kdf_algo.get_parameters()) + .start_cons(SEQUENCE) + .decode(salt, OCTET_STRING) + .decode(iterations) + .decode_optional(key_length, INTEGER, UNIVERSAL) + .decode_optional(prf_algo, SEQUENCE, CONSTRUCTED, + AlgorithmIdentifier("HMAC(SHA-160)", + AlgorithmIdentifier::USE_NULL_PARAM)) + .end_cons(); + + 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(get_pbkdf("PBKDF2(" + prf + ")")); + + if(key_length == 0) + key_length = default_key_size; + + return pbkdf->pbkdf_iterations(key_length, passphrase, salt.data(), salt.size(), iterations); + } +#if defined(BOTAN_HAS_SCRYPT) + else if(kdf_algo.get_oid() == OIDS::lookup("Scrypt")) + { + secure_vector salt; + size_t N = 0, r = 0, p = 0; + size_t key_length = 0; + + AlgorithmIdentifier prf_algo; + BER_Decoder(kdf_algo.get_parameters()) + .start_cons(SEQUENCE) + .decode(salt, OCTET_STRING) + .decode(N) + .decode(r) + .decode(p) + .decode_optional(key_length, INTEGER, UNIVERSAL) + .end_cons(); + + if(key_length == 0) + key_length = default_key_size; + + secure_vector output(key_length); + scrypt(output.data(), output.size(), passphrase, + salt.data(), salt.size(), N, r, p); + + return SymmetricKey(output); + } +#endif + else + throw Decoding_Error("PBE-PKCS5 v2.0: Unknown KDF algorithm " + + kdf_algo.get_oid().as_string()); + } + +secure_vector derive_key(const std::string& passphrase, + const std::string& digest, + RandomNumberGenerator& rng, + size_t* msec_in_iterations_out, + size_t iterations_if_msec_null, + size_t key_length, + AlgorithmIdentifier& kdf_algo) + { + const secure_vector salt = rng.random_vec(12); + + if(digest == "Scrypt") + { +#if defined(BOTAN_HAS_SCRYPT) + + Scrypt_Params params(32768, 8, 4); + + if(msec_in_iterations_out) + params = Scrypt_Params(std::chrono::milliseconds(*msec_in_iterations_out)); + else + params = Scrypt_Params(iterations_if_msec_null); + + secure_vector key(key_length); + scrypt(key.data(), key.size(), passphrase, + salt.data(), salt.size(), params); + + std::vector scrypt_params; + DER_Encoder(scrypt_params) + .start_cons(SEQUENCE) + .encode(salt, OCTET_STRING) + .encode(params.N()) + .encode(params.r()) + .encode(params.p()) + .encode(key_length) + .end_cons(); + + kdf_algo = AlgorithmIdentifier(OIDS::lookup("Scrypt"), scrypt_params); + return key; +#else + throw Not_Implemented("Scrypt is not available in this build"); +#endif + } + else + { + const std::string prf = "HMAC(" + digest + ")"; + + std::unique_ptr pbkdf(get_pbkdf("PBKDF2(" + prf + ")")); + + size_t iterations = iterations_if_msec_null; + + secure_vector key; + + 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; + } + else + { + key = pbkdf->pbkdf_iterations(key_length, passphrase, salt.data(), salt.size(), iterations); + } + + std::vector pbkdf2_params; + + DER_Encoder(pbkdf2_params) + .start_cons(SEQUENCE) + .encode(salt, OCTET_STRING) + .encode(iterations) + .encode(key_length) + .encode_if(prf != "HMAC(SHA-160)", + AlgorithmIdentifier(prf, AlgorithmIdentifier::USE_NULL_PARAM)) + .end_cons(); + + kdf_algo = AlgorithmIdentifier("PKCS5.PBKDF2", pbkdf2_params); + return key; + } + } + +/* +* PKCS#5 v2.0 PBE Encryption +*/ +std::pair> +pbes2_encrypt_shared(const secure_vector& key_bits, + const std::string& passphrase, + size_t* msec_in_iterations_out, + size_t iterations_if_msec_null, + const std::string& cipher, + const std::string& prf, + RandomNumberGenerator& rng) + { + const std::vector cipher_spec = split_on(cipher, '/'); + 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") + throw Encoding_Error("PBE-PKCS5 v2.0: Don't know param format for " + cipher); + + const OID cipher_oid = OIDS::lookup(cipher); + if(cipher_oid.empty()) + throw Encoding_Error("PBE-PKCS5 v2.0: No OID assigned for " + cipher); + + std::unique_ptr enc = Cipher_Mode::create(cipher, ENCRYPTION); + + if(!enc) + throw Decoding_Error("PBE-PKCS5 cannot encrypt no cipher " + cipher); + + const size_t key_length = enc->key_spec().maximum_keylength(); + + const secure_vector iv = rng.random_vec(enc->default_nonce_length()); + + AlgorithmIdentifier kdf_algo; + + const secure_vector derived_key = + derive_key(passphrase, prf, rng, + msec_in_iterations_out, iterations_if_msec_null, + key_length, kdf_algo); + + enc->set_key(derived_key); + enc->start(iv); + secure_vector ctext = key_bits; + enc->finish(ctext); + + std::vector pbes2_params; + + DER_Encoder(pbes2_params) + .start_cons(SEQUENCE) + .encode(kdf_algo) + .encode( + AlgorithmIdentifier(cipher, + DER_Encoder().encode(iv, OCTET_STRING).get_contents_unlocked() + ) + ) + .end_cons(); + + AlgorithmIdentifier id(OIDS::lookup("PBE-PKCS5v20"), pbes2_params); + + return std::make_pair(id, unlock(ctext)); + } + + +} + +std::pair> +pbes2_encrypt(const secure_vector& key_bits, + const std::string& passphrase, + std::chrono::milliseconds msec, + const std::string& cipher, + const std::string& digest, + RandomNumberGenerator& rng) + { + size_t msec_in_iterations_out = static_cast(msec.count()); + return pbes2_encrypt_shared(key_bits, passphrase, &msec_in_iterations_out, 0, cipher, digest, rng); + // return value msec_in_iterations_out discarded + } + +std::pair> +pbes2_encrypt_msec(const secure_vector& key_bits, + const std::string& passphrase, + std::chrono::milliseconds msec, + size_t* out_iterations_if_nonnull, + const std::string& cipher, + const std::string& digest, + RandomNumberGenerator& rng) + { + size_t msec_in_iterations_out = static_cast(msec.count()); + + auto ret = pbes2_encrypt_shared(key_bits, passphrase, &msec_in_iterations_out, 0, cipher, digest, rng); + + if(out_iterations_if_nonnull) + *out_iterations_if_nonnull = msec_in_iterations_out; + + return ret; + } + +std::pair> +pbes2_encrypt_iter(const secure_vector& key_bits, + const std::string& passphrase, + size_t pbkdf_iter, + const std::string& cipher, + const std::string& digest, + RandomNumberGenerator& rng) + { + return pbes2_encrypt_shared(key_bits, passphrase, nullptr, pbkdf_iter, cipher, digest, rng); + } + +secure_vector +pbes2_decrypt(const secure_vector& key_bits, + const std::string& passphrase, + const std::vector& params) + { + AlgorithmIdentifier kdf_algo, enc_algo; + + BER_Decoder(params) + .start_cons(SEQUENCE) + .decode(kdf_algo) + .decode(enc_algo) + .end_cons(); + + const std::string cipher = OIDS::lookup(enc_algo.get_oid()); + const std::vector 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") + throw Decoding_Error("PBE-PKCS5 v2.0: Don't know param format for " + cipher); + + secure_vector iv; + BER_Decoder(enc_algo.get_parameters()).decode(iv, OCTET_STRING).verify_end(); + + std::unique_ptr dec = Cipher_Mode::create(cipher, DECRYPTION); + if(!dec) + throw Decoding_Error("PBE-PKCS5 cannot decrypt no cipher " + cipher); + + dec->set_key(derive_key(passphrase, kdf_algo, dec->key_spec().maximum_keylength())); + + dec->start(iv); + + secure_vector buf = key_bits; + dec->finish(buf); + + return buf; + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/pbes2/pbes2.h b/src/libs/3rdparty/botan/src/lib/pubkey/pbes2/pbes2.h new file mode 100644 index 0000000000..bc56abd97f --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pubkey/pbes2/pbes2.h @@ -0,0 +1,85 @@ +/* +* PKCS #5 v2.0 PBE +* (C) 1999-2007,2014 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_PBE_PKCS_v20_H_ +#define BOTAN_PBE_PKCS_v20_H_ + +#include +#include + +namespace Botan { + +class RandomNumberGenerator; + +/** +* Encrypt with PBES2 from PKCS #5 v2.0 +* @param key_bits the input +* @param passphrase the passphrase to use for encryption +* @param msec how many milliseconds to run PBKDF2 +* @param cipher specifies the block cipher to use to encrypt +* @param digest specifies the PRF to use with PBKDF2 (eg "HMAC(SHA-1)") +* @param rng a random number generator +*/ +std::pair> +BOTAN_PUBLIC_API(2,0) pbes2_encrypt(const secure_vector& key_bits, + const std::string& passphrase, + std::chrono::milliseconds msec, + const std::string& cipher, + const std::string& digest, + RandomNumberGenerator& rng); + +/** +* Encrypt with PBES2 from PKCS #5 v2.0 +* @param key_bits the input +* @param passphrase the passphrase to use for encryption +* @param msec how many milliseconds to run PBKDF2 +* @param out_iterations_if_nonnull if not null, set to the number +* of PBKDF iterations used +* @param cipher specifies the block cipher to use to encrypt +* @param digest specifies the PRF to use with PBKDF2 (eg "HMAC(SHA-1)") +* @param rng a random number generator +*/ +std::pair> +BOTAN_PUBLIC_API(2,1) pbes2_encrypt_msec(const secure_vector& key_bits, + const std::string& passphrase, + std::chrono::milliseconds msec, + size_t* out_iterations_if_nonnull, + const std::string& cipher, + const std::string& digest, + RandomNumberGenerator& rng); + +/** +* Encrypt with PBES2 from PKCS #5 v2.0 +* @param key_bits the input +* @param passphrase the passphrase to use for encryption +* @param iterations how many iterations to run PBKDF2 +* @param cipher specifies the block cipher to use to encrypt +* @param digest specifies the PRF to use with PBKDF2 (eg "HMAC(SHA-1)") +* @param rng a random number generator +*/ +std::pair> +BOTAN_PUBLIC_API(2,1) pbes2_encrypt_iter(const secure_vector& key_bits, + const std::string& passphrase, + size_t iterations, + const std::string& cipher, + const std::string& digest, + RandomNumberGenerator& rng); + +/** +* Decrypt a PKCS #5 v2.0 encrypted stream +* @param key_bits the input +* @param passphrase the passphrase to use for decryption +* @param params the PBES2 parameters +*/ +secure_vector +BOTAN_PUBLIC_API(2,0) pbes2_decrypt(const secure_vector& key_bits, + const std::string& passphrase, + const std::vector& params); + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/pem/info.txt b/src/libs/3rdparty/botan/src/lib/pubkey/pem/info.txt new file mode 100644 index 0000000000..471d9abd63 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pubkey/pem/info.txt @@ -0,0 +1,7 @@ + +PEM_CODEC -> 20131128 + + + +base64 + diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/pem/pem.cpp b/src/libs/3rdparty/botan/src/lib/pubkey/pem/pem.cpp new file mode 100644 index 0000000000..d2433860dd --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pubkey/pem/pem.cpp @@ -0,0 +1,169 @@ +/* +* PEM Encoding/Decoding +* (C) 1999-2007 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include + +namespace Botan { + +namespace PEM_Code { + +namespace { + +std::string linewrap(size_t width, const std::string& in) + { + std::string out; + for(size_t i = 0; i != in.size(); ++i) + { + if(i > 0 && i % width == 0) + { + out.push_back('\n'); + } + out.push_back(in[i]); + } + if(out.size() > 0 && out[out.size()-1] != '\n') + { + out.push_back('\n'); + } + + return out; + } + +} + +/* +* PEM encode BER/DER-encoded objects +*/ +std::string encode(const uint8_t der[], size_t length, const std::string& label, size_t width) + { + const std::string PEM_HEADER = "-----BEGIN " + label + "-----\n"; + const std::string PEM_TRAILER = "-----END " + label + "-----\n"; + + return (PEM_HEADER + linewrap(width, base64_encode(der, length)) + PEM_TRAILER); + } + +/* +* Decode PEM down to raw BER/DER +*/ +secure_vector decode_check_label(DataSource& source, + const std::string& label_want) + { + std::string label_got; + secure_vector ber = decode(source, label_got); + if(label_got != label_want) + throw Decoding_Error("PEM: Label mismatch, wanted " + label_want + + ", got " + label_got); + return ber; + } + +/* +* Decode PEM down to raw BER/DER +*/ +secure_vector decode(DataSource& source, std::string& label) + { + const size_t RANDOM_CHAR_LIMIT = 8; + + label.clear(); + + const std::string PEM_HEADER1 = "-----BEGIN "; + const std::string PEM_HEADER2 = "-----"; + size_t position = 0; + + while(position != PEM_HEADER1.length()) + { + uint8_t b; + if(!source.read_byte(b)) + throw Decoding_Error("PEM: No PEM header found"); + if(b == PEM_HEADER1[position]) + ++position; + else if(position >= RANDOM_CHAR_LIMIT) + throw Decoding_Error("PEM: Malformed PEM header"); + else + position = 0; + } + position = 0; + while(position != PEM_HEADER2.length()) + { + uint8_t b; + if(!source.read_byte(b)) + throw Decoding_Error("PEM: No PEM header found"); + if(b == PEM_HEADER2[position]) + ++position; + else if(position) + throw Decoding_Error("PEM: Malformed PEM header"); + + if(position == 0) + label += static_cast(b); + } + + std::vector b64; + + const std::string PEM_TRAILER = "-----END " + label + "-----"; + position = 0; + while(position != PEM_TRAILER.length()) + { + uint8_t b; + if(!source.read_byte(b)) + throw Decoding_Error("PEM: No PEM trailer found"); + if(b == PEM_TRAILER[position]) + ++position; + else if(position) + throw Decoding_Error("PEM: Malformed PEM trailer"); + + if(position == 0) + b64.push_back(b); + } + + return base64_decode(b64.data(), b64.size()); + } + +secure_vector decode_check_label(const std::string& pem, + const std::string& label_want) + { + DataSource_Memory src(pem); + return decode_check_label(src, label_want); + } + +secure_vector decode(const std::string& pem, std::string& label) + { + DataSource_Memory src(pem); + return decode(src, label); + } + +/* +* Search for a PEM signature +*/ +bool matches(DataSource& source, const std::string& extra, + size_t search_range) + { + const std::string PEM_HEADER = "-----BEGIN " + extra; + + secure_vector search_buf(search_range); + size_t got = source.peek(search_buf.data(), search_buf.size(), 0); + + if(got < PEM_HEADER.length()) + return false; + + size_t index = 0; + + for(size_t j = 0; j != got; ++j) + { + if(search_buf[j] == PEM_HEADER[index]) + ++index; + else + index = 0; + if(index == PEM_HEADER.size()) + return true; + } + return false; + } + +} + +} diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/pem/pem.h b/src/libs/3rdparty/botan/src/lib/pubkey/pem/pem.h new file mode 100644 index 0000000000..c02294dce5 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pubkey/pem/pem.h @@ -0,0 +1,91 @@ +/* +* PEM Encoding/Decoding +* (C) 1999-2007 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_PEM_H_ +#define BOTAN_PEM_H_ + +#include +#include + +namespace Botan { + +class DataSource; + +namespace PEM_Code { + +/** +* Encode some binary data in PEM format +* @param data binary data to encode +* @param data_len length of binary data in bytes +* @param label PEM label put after BEGIN and END +* @param line_width after this many characters, a new line is inserted +*/ +BOTAN_PUBLIC_API(2,0) std::string encode(const uint8_t data[], + size_t data_len, + const std::string& label, + size_t line_width = 64); + +/** +* Encode some binary data in PEM format +* @param data binary data to encode +* @param label PEM label +* @param line_width after this many characters, a new line is inserted +*/ +template +std::string encode(const std::vector& data, + const std::string& label, + size_t line_width = 64) + { + return encode(data.data(), data.size(), label, line_width); + } + +/** +* Decode PEM data +* @param pem a datasource containing PEM encoded data +* @param label is set to the PEM label found for later inspection +*/ +BOTAN_PUBLIC_API(2,0) secure_vector decode(DataSource& pem, + std::string& label); + +/** +* Decode PEM data +* @param pem a string containing PEM encoded data +* @param label is set to the PEM label found for later inspection +*/ +BOTAN_PUBLIC_API(2,0) secure_vector decode(const std::string& pem, + std::string& label); + +/** +* Decode PEM data +* @param pem a datasource containing PEM encoded data +* @param label is what we expect the label to be +*/ +BOTAN_PUBLIC_API(2,0) +secure_vector decode_check_label(DataSource& pem, + const std::string& label); + +/** +* Decode PEM data +* @param pem a string containing PEM encoded data +* @param label is what we expect the label to be +*/ +BOTAN_PUBLIC_API(2,0) +secure_vector decode_check_label(const std::string& pem, + const std::string& label); + +/** +* Heuristic test for PEM data. +*/ +BOTAN_PUBLIC_API(2,0) bool matches(DataSource& source, + const std::string& extra = "", + size_t search_range = 4096); + +} + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/pk_algs.cpp b/src/libs/3rdparty/botan/src/lib/pubkey/pk_algs.cpp new file mode 100644 index 0000000000..89ef7c708e --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pubkey/pk_algs.cpp @@ -0,0 +1,434 @@ +/* +* PK Key +* (C) 1999-2010,2016 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include + +#if defined(BOTAN_HAS_RSA) + #include +#endif + +#if defined(BOTAN_HAS_DSA) + #include +#endif + +#if defined(BOTAN_HAS_DL_GROUP) + #include +#endif + +#if defined(BOTAN_HAS_DIFFIE_HELLMAN) + #include +#endif + +#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO) + #include +#endif + +#if defined(BOTAN_HAS_ECDSA) + #include +#endif + +#if defined(BOTAN_HAS_ECGDSA) + #include +#endif + +#if defined(BOTAN_HAS_ECKCDSA) + #include +#endif + +#if defined(BOTAN_HAS_ED25519) + #include +#endif + +#if defined(BOTAN_HAS_GOST_34_10_2001) + #include +#endif + +#if defined(BOTAN_HAS_ELGAMAL) + #include +#endif + +#if defined(BOTAN_HAS_ECDH) + #include +#endif + +#if defined(BOTAN_HAS_CURVE_25519) + #include +#endif + +#if defined(BOTAN_HAS_MCELIECE) + #include +#endif + +#if defined(BOTAN_HAS_XMSS) + #include +#endif + +#if defined(BOTAN_HAS_SM2) + #include + #include +#endif + +#if defined(BOTAN_HAS_OPENSSL) + #include +#endif + +namespace Botan { + +std::unique_ptr +load_public_key(const AlgorithmIdentifier& alg_id, + const std::vector& key_bits) + { + const std::vector alg_info = split_on(OIDS::lookup(alg_id.get_oid()), '/'); + + if(alg_info.empty()) + throw Decoding_Error("Unknown algorithm OID: " + alg_id.get_oid().as_string()); + + const std::string alg_name = alg_info[0]; + +#if defined(BOTAN_HAS_RSA) + if(alg_name == "RSA") + return std::unique_ptr(new RSA_PublicKey(alg_id, key_bits)); +#endif + +#if defined(BOTAN_HAS_CURVE_25519) + if(alg_name == "Curve25519") + return std::unique_ptr(new Curve25519_PublicKey(alg_id, key_bits)); +#endif + +#if defined(BOTAN_HAS_MCELIECE) + if(alg_name == "McEliece") + return std::unique_ptr(new McEliece_PublicKey(key_bits)); +#endif + +#if defined(BOTAN_HAS_ECDSA) + if(alg_name == "ECDSA") + return std::unique_ptr(new ECDSA_PublicKey(alg_id, key_bits)); +#endif + +#if defined(BOTAN_HAS_ECDH) + if(alg_name == "ECDH") + return std::unique_ptr(new ECDH_PublicKey(alg_id, key_bits)); +#endif + +#if defined(BOTAN_HAS_DIFFIE_HELLMAN) + if(alg_name == "DH") + return std::unique_ptr(new DH_PublicKey(alg_id, key_bits)); +#endif + +#if defined(BOTAN_HAS_DSA) + if(alg_name == "DSA") + return std::unique_ptr(new DSA_PublicKey(alg_id, key_bits)); +#endif + +#if defined(BOTAN_HAS_ELGAMAL) + if(alg_name == "ElGamal") + return std::unique_ptr(new ElGamal_PublicKey(alg_id, key_bits)); +#endif + +#if defined(BOTAN_HAS_ECGDSA) + if(alg_name == "ECGDSA") + return std::unique_ptr(new ECGDSA_PublicKey(alg_id, key_bits)); +#endif + +#if defined(BOTAN_HAS_ECKCDSA) + if(alg_name == "ECKCDSA") + return std::unique_ptr(new ECKCDSA_PublicKey(alg_id, key_bits)); +#endif + +#if defined(BOTAN_HAS_ED25519) + if(alg_name == "Ed25519") + return std::unique_ptr(new Ed25519_PublicKey(alg_id, key_bits)); +#endif + +#if defined(BOTAN_HAS_GOST_34_10_2001) + if(alg_name == "GOST-34.10") + return std::unique_ptr(new GOST_3410_PublicKey(alg_id, key_bits)); +#endif + +#if defined(BOTAN_HAS_SM2) + if(alg_name == "SM2_Sig") + return std::unique_ptr(new SM2_Signature_PublicKey(alg_id, key_bits)); + if(alg_name == "SM2_Enc") + return std::unique_ptr(new SM2_Encryption_PublicKey(alg_id, key_bits)); +#endif + +#if defined(BOTAN_HAS_XMSS) + if(alg_name == "XMSS") + return std::unique_ptr(new XMSS_PublicKey(key_bits)); +#endif + + throw Decoding_Error("Unhandled PK algorithm " + alg_name); + } + +std::unique_ptr +load_private_key(const AlgorithmIdentifier& alg_id, + const secure_vector& key_bits) + { + const std::string alg_name = OIDS::lookup(alg_id.get_oid()); + if(alg_name == "") + throw Decoding_Error("Unknown algorithm OID: " + alg_id.get_oid().as_string()); + +#if defined(BOTAN_HAS_RSA) + if(alg_name == "RSA") + return std::unique_ptr(new RSA_PrivateKey(alg_id, key_bits)); +#endif + +#if defined(BOTAN_HAS_CURVE_25519) + if(alg_name == "Curve25519") + return std::unique_ptr(new Curve25519_PrivateKey(alg_id, key_bits)); +#endif + +#if defined(BOTAN_HAS_ECDSA) + if(alg_name == "ECDSA") + return std::unique_ptr(new ECDSA_PrivateKey(alg_id, key_bits)); +#endif + +#if defined(BOTAN_HAS_ECDH) + if(alg_name == "ECDH") + return std::unique_ptr(new ECDH_PrivateKey(alg_id, key_bits)); +#endif + +#if defined(BOTAN_HAS_DIFFIE_HELLMAN) + if(alg_name == "DH") + return std::unique_ptr(new DH_PrivateKey(alg_id, key_bits)); +#endif + +#if defined(BOTAN_HAS_DSA) + if(alg_name == "DSA") + return std::unique_ptr(new DSA_PrivateKey(alg_id, key_bits)); +#endif + +#if defined(BOTAN_HAS_MCELIECE) + if(alg_name == "McEliece") + return std::unique_ptr(new McEliece_PrivateKey(key_bits)); +#endif + +#if defined(BOTAN_HAS_ECGDSA) + if(alg_name == "ECGDSA") + return std::unique_ptr(new ECGDSA_PrivateKey(alg_id, key_bits)); +#endif + +#if defined(BOTAN_HAS_ECKCDSA) + if(alg_name == "ECKCDSA") + return std::unique_ptr(new ECKCDSA_PrivateKey(alg_id, key_bits)); +#endif + +#if defined(BOTAN_HAS_ED25519) + if(alg_name == "Ed25519") + return std::unique_ptr(new Ed25519_PrivateKey(alg_id, key_bits)); +#endif + +#if defined(BOTAN_HAS_GOST_34_10_2001) + if(alg_name == "GOST-34.10") + return std::unique_ptr(new GOST_3410_PrivateKey(alg_id, key_bits)); +#endif + +#if defined(BOTAN_HAS_SM2) + if(alg_name == "SM2_Sig") + return std::unique_ptr(new SM2_Signature_PrivateKey(alg_id, key_bits)); + if(alg_name == "SM2_Enc") + return std::unique_ptr(new SM2_Encryption_PrivateKey(alg_id, key_bits)); +#endif + +#if defined(BOTAN_HAS_ELGAMAL) + if(alg_name == "ElGamal") + return std::unique_ptr(new ElGamal_PrivateKey(alg_id, key_bits)); +#endif + +#if defined(BOTAN_HAS_XMSS) + if(alg_name == "XMSS") + return std::unique_ptr(new XMSS_PrivateKey(key_bits)); +#endif + + throw Decoding_Error("Unhandled PK algorithm " + alg_name); + } + +#if defined(BOTAN_HAS_ECC_GROUP) + +namespace { + +std::string default_ec_group_for(const std::string& alg_name) + { + if(alg_name == "SM2_Enc" || alg_name == "SM2_Sig") + return "sm2p256v1"; + if(alg_name == "GOST-34.10") + return "gost_256A"; + if(alg_name == "ECGDSA") + return "brainpool256r1"; + return "secp256r1"; + + } + +} + +#endif + +std::unique_ptr +create_private_key(const std::string& alg_name, + RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) + { + /* + * Default paramaters are chosen for work factor > 2**128 where possible + */ + +#if defined(BOTAN_HAS_CURVE_25519) + if(alg_name == "Curve25519") + return std::unique_ptr(new Curve25519_PrivateKey(rng)); +#endif + +#if defined(BOTAN_HAS_RSA) + if(alg_name == "RSA") + { + const size_t rsa_bits = (params.empty() ? 3072 : to_u32bit(params)); +#if defined(BOTAN_HAS_OPENSSL) + if(provider.empty() || provider == "openssl") + { + std::unique_ptr pk; + if((pk = make_openssl_rsa_private_key(rng, rsa_bits))) + return pk; + + if(!provider.empty()) + return nullptr; + } +#endif + return std::unique_ptr(new RSA_PrivateKey(rng, rsa_bits)); + } +#endif + +#if defined(BOTAN_HAS_MCELIECE) + if(alg_name == "McEliece") + { + std::vector mce_param = + Botan::split_on(params.empty() ? "2960,57" : params, ','); + + if(mce_param.size() != 2) + throw Invalid_Argument("create_private_key bad McEliece parameters " + params); + + size_t mce_n = Botan::to_u32bit(mce_param[0]); + size_t mce_t = Botan::to_u32bit(mce_param[1]); + + return std::unique_ptr(new Botan::McEliece_PrivateKey(rng, mce_n, mce_t)); + } +#endif + +#if defined(BOTAN_HAS_XMSS) + if(alg_name == "XMSS") + { + return std::unique_ptr( + new XMSS_PrivateKey(XMSS_Parameters(params.empty() ? "XMSS_SHA2-512_W16_H10" : params).oid(), rng)); + } +#endif + +#if defined(BOTAN_HAS_ED25519) + if(alg_name == "Ed25519") + { + return std::unique_ptr(new Ed25519_PrivateKey(rng)); + } +#endif + + // ECC crypto +#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO) + + if(alg_name == "ECDSA" || + alg_name == "ECDH" || + alg_name == "ECKCDSA" || + alg_name == "ECGDSA" || + alg_name == "SM2_Sig" || + alg_name == "SM2_Enc" || + alg_name == "GOST-34.10") + { + const EC_Group ec_group(params.empty() ? default_ec_group_for(alg_name) : params); + +#if defined(BOTAN_HAS_ECDSA) + if(alg_name == "ECDSA") + return std::unique_ptr(new ECDSA_PrivateKey(rng, ec_group)); +#endif + +#if defined(BOTAN_HAS_ECDH) + if(alg_name == "ECDH") + return std::unique_ptr(new ECDH_PrivateKey(rng, ec_group)); +#endif + +#if defined(BOTAN_HAS_ECKCDSA) + if(alg_name == "ECKCDSA") + return std::unique_ptr(new ECKCDSA_PrivateKey(rng, ec_group)); +#endif + +#if defined(BOTAN_HAS_GOST_34_10_2001) + if(alg_name == "GOST-34.10") + return std::unique_ptr(new GOST_3410_PrivateKey(rng, ec_group)); +#endif + +#if defined(BOTAN_HAS_SM2) + if(alg_name == "SM2_Sig") + return std::unique_ptr(new SM2_Signature_PrivateKey(rng, ec_group)); + if(alg_name == "SM2_Enc") + return std::unique_ptr(new SM2_Encryption_PrivateKey(rng, ec_group)); +#endif + +#if defined(BOTAN_HAS_ECGDSA) + if(alg_name == "ECGDSA") + return std::unique_ptr(new ECGDSA_PrivateKey(rng, ec_group)); +#endif + } +#endif + + // DL crypto +#if defined(BOTAN_HAS_DL_GROUP) + if(alg_name == "DH" || alg_name == "DSA" || alg_name == "ElGamal") + { + std::string default_group = (alg_name == "DSA") ? "dsa/botan/2048" : "modp/ietf/2048"; + DL_Group modp_group(params.empty() ? default_group : params); + +#if defined(BOTAN_HAS_DIFFIE_HELLMAN) + if(alg_name == "DH") + return std::unique_ptr(new DH_PrivateKey(rng, modp_group)); +#endif + +#if defined(BOTAN_HAS_DSA) + if(alg_name == "DSA") + return std::unique_ptr(new DSA_PrivateKey(rng, modp_group)); +#endif + +#if defined(BOTAN_HAS_ELGAMAL) + if(alg_name == "ElGamal") + return std::unique_ptr(new ElGamal_PrivateKey(rng, modp_group)); +#endif + } +#endif + + BOTAN_UNUSED(alg_name, rng, params, provider); + + return std::unique_ptr(); + } + +std::vector +probe_provider_private_key(const std::string& alg_name, + const std::vector possible) + { + std::vector providers; + for(auto&& prov : possible) + { + if(prov == "base" || +#if defined(BOTAN_HAS_OPENSSL) + (prov == "openssl" && alg_name == "RSA") || +#endif + 0) + { + providers.push_back(prov); // available + } + } + + BOTAN_UNUSED(alg_name); + + return providers; + } +} diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/pk_algs.h b/src/libs/3rdparty/botan/src/lib/pubkey/pk_algs.h new file mode 100644 index 0000000000..e3c7174288 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pubkey/pk_algs.h @@ -0,0 +1,46 @@ +/* +* PK Key Factory +* (C) 1999-2010,2016 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_PK_KEY_FACTORY_H_ +#define BOTAN_PK_KEY_FACTORY_H_ + +#include +#include +#include + +namespace Botan { + +BOTAN_PUBLIC_API(2,0) std::unique_ptr +load_public_key(const AlgorithmIdentifier& alg_id, + const std::vector& key_bits); + +BOTAN_PUBLIC_API(2,0) std::unique_ptr +load_private_key(const AlgorithmIdentifier& alg_id, + const secure_vector& key_bits); + +/** +* Create a new key +* For ECC keys, algo_params specifies EC group (eg, "secp256r1") +* For DH/DSA/ElGamal keys, algo_params is DL group (eg, "modp/ietf/2048") +* For RSA, algo_params is integer keylength +* For McEliece, algo_params is n,t +* If algo_params is left empty, suitable default parameters are chosen. +*/ +BOTAN_PUBLIC_API(2,0) std::unique_ptr +create_private_key(const std::string& algo_name, + RandomNumberGenerator& rng, + const std::string& algo_params = "", + const std::string& provider = ""); + +BOTAN_PUBLIC_API(2,2) +std::vector +probe_provider_private_key(const std::string& algo_name, + const std::vector possible); + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/pk_keys.cpp b/src/libs/3rdparty/botan/src/lib/pubkey/pk_keys.cpp new file mode 100644 index 0000000000..fbbc6f7dd4 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pubkey/pk_keys.cpp @@ -0,0 +1,148 @@ +/* +* PK Key Types +* (C) 1999-2007 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include +#include +#include + +namespace Botan { + +std::string create_hex_fingerprint(const uint8_t bits[], + size_t bits_len, + const std::string& hash_name) + { + std::unique_ptr hash_fn(HashFunction::create_or_throw(hash_name)); + const std::string hex_hash = hex_encode(hash_fn->process(bits, bits_len)); + + std::string fprint; + + for(size_t i = 0; i != hex_hash.size(); i += 2) + { + if(i != 0) + fprint.push_back(':'); + + fprint.push_back(hex_hash[i]); + fprint.push_back(hex_hash[i+1]); + } + + return fprint; + } + +std::vector Public_Key::subject_public_key() const + { + std::vector output; + + DER_Encoder(output).start_cons(SEQUENCE) + .encode(algorithm_identifier()) + .encode(public_key_bits(), BIT_STRING) + .end_cons(); + + return output; + } + +/* +* Default OID access +*/ +OID Public_Key::get_oid() const + { + try { + return OIDS::lookup(algo_name()); + } + catch(Lookup_Error&) + { + throw Lookup_Error("PK algo " + algo_name() + " has no defined OIDs"); + } + } + +secure_vector Private_Key::private_key_info() const + { + const size_t PKCS8_VERSION = 0; + + return DER_Encoder() + .start_cons(SEQUENCE) + .encode(PKCS8_VERSION) + .encode(pkcs8_algorithm_identifier()) + .encode(private_key_bits(), OCTET_STRING) + .end_cons() + .get_contents(); + } + +/* +* Hash of the X.509 subjectPublicKey encoding +*/ +std::string Public_Key::fingerprint_public(const std::string& hash_algo) const + { + return create_hex_fingerprint(subject_public_key(), hash_algo); + } + +/* +* Hash of the PKCS #8 encoding for this key object +*/ +std::string Private_Key::fingerprint_private(const std::string& hash_algo) const + { + return create_hex_fingerprint(private_key_bits(), hash_algo); + } + +std::unique_ptr +Public_Key::create_encryption_op(RandomNumberGenerator& /*rng*/, + const std::string& /*params*/, + const std::string& /*provider*/) const + { + throw Lookup_Error(algo_name() + " does not support encryption"); + } + +std::unique_ptr +Public_Key::create_kem_encryption_op(RandomNumberGenerator& /*rng*/, + const std::string& /*params*/, + const std::string& /*provider*/) const + { + throw Lookup_Error(algo_name() + " does not support KEM encryption"); + } + +std::unique_ptr +Public_Key::create_verification_op(const std::string& /*params*/, + const std::string& /*provider*/) const + { + throw Lookup_Error(algo_name() + " does not support verification"); + } + +std::unique_ptr +Private_Key::create_decryption_op(RandomNumberGenerator& /*rng*/, + const std::string& /*params*/, + const std::string& /*provider*/) const + { + throw Lookup_Error(algo_name() + " does not support decryption"); + } + +std::unique_ptr +Private_Key::create_kem_decryption_op(RandomNumberGenerator& /*rng*/, + const std::string& /*params*/, + const std::string& /*provider*/) const + { + throw Lookup_Error(algo_name() + " does not support KEM decryption"); + } + +std::unique_ptr +Private_Key::create_signature_op(RandomNumberGenerator& /*rng*/, + const std::string& /*params*/, + const std::string& /*provider*/) const + { + throw Lookup_Error(algo_name() + " does not support signatures"); + } + +std::unique_ptr +Private_Key::create_key_agreement_op(RandomNumberGenerator& /*rng*/, + const std::string& /*params*/, + const std::string& /*provider*/) const + { + throw Lookup_Error(algo_name() + " does not support key agreement"); + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/pk_keys.h b/src/libs/3rdparty/botan/src/lib/pubkey/pk_keys.h new file mode 100644 index 0000000000..79254ea290 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pubkey/pk_keys.h @@ -0,0 +1,317 @@ +/* +* PK Key Types +* (C) 1999-2007 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_PK_KEYS_H_ +#define BOTAN_PK_KEYS_H_ + +#include +#include +#include +#include + +namespace Botan { + +class RandomNumberGenerator; + +/** +* Public Key Base Class. +*/ +class BOTAN_PUBLIC_API(2,0) Public_Key + { + public: + Public_Key() =default; + Public_Key(const Public_Key& other) = default; + Public_Key& operator=(const Public_Key& other) = default; + virtual ~Public_Key() = default; + + /** + * Get the name of the underlying public key scheme. + * @return name of the public key scheme + */ + virtual std::string algo_name() const = 0; + + /** + * Return the estimated strength of the underlying key against + * the best currently known attack. Note that this ignores anything + * but pure attacks against the key itself and do not take into + * account padding schemes, usage mistakes, etc which might reduce + * the strength. However it does suffice to provide an upper bound. + * + * @return estimated strength in bits + */ + virtual size_t estimated_strength() const = 0; + + /** + * Return an integer value best approximating the length of the + * primary security parameter. For example for RSA this will be + * the size of the modulus, for ECDSA the size of the ECC group, + * and for McEliece the size of the code will be returned. + */ + virtual size_t key_length() const = 0; + + /** + * Get the OID of the underlying public key scheme. + * @return OID of the public key scheme + */ + virtual OID get_oid() const; + + /** + * Test the key values for consistency. + * @param rng rng to use + * @param strong whether to perform strong and lengthy version + * of the test + * @return true if the test is passed + */ + virtual bool check_key(RandomNumberGenerator& rng, + bool strong) const = 0; + + + /** + * @return X.509 AlgorithmIdentifier for this key + */ + virtual AlgorithmIdentifier algorithm_identifier() const = 0; + + /** + * @return BER encoded public key bits + */ + virtual std::vector public_key_bits() const = 0; + + /** + * @return X.509 subject key encoding for this key object + */ + std::vector subject_public_key() const; + + /** + * @return Hash of the subject public key + */ + std::string fingerprint_public(const std::string& alg = "SHA-256") const; + + // Internal or non-public declarations follow + + /** + * Returns more than 1 if the output of this algorithm + * (ciphertext, signature) should be treated as more than one + * value. This is used for algorithms like DSA and ECDSA, where + * the (r,s) output pair can be encoded as either a plain binary + * list or a TLV tagged DER encoding depending on the protocol. + * + * This function is public but applications should have few + * reasons to ever call this. + * + * @return number of message parts + */ + virtual size_t message_parts() const { return 1; } + + /** + * Returns how large each of the message parts refered to + * by message_parts() is + * + * This function is public but applications should have few + * reasons to ever call this. + * + * @return size of the message parts in bits + */ + virtual size_t message_part_size() const { return 0; } + + /** + * This is an internal library function exposed on key types. + * In almost all cases applications should use wrappers in pubkey.h + * + * Return an encryption operation for this key/params or throw + * + * @param rng a random number generator. The PK_Op may maintain a + * reference to the RNG and use it many times. The rng must outlive + * any operations which reference it. + * @param params additional parameters + * @param provider the provider to use + */ + virtual std::unique_ptr + create_encryption_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) const; + + /** + * This is an internal library function exposed on key types. + * In almost all cases applications should use wrappers in pubkey.h + * + * Return a KEM encryption operation for this key/params or throw + * + * @param rng a random number generator. The PK_Op may maintain a + * reference to the RNG and use it many times. The rng must outlive + * any operations which reference it. + * @param params additional parameters + * @param provider the provider to use + */ + virtual std::unique_ptr + create_kem_encryption_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) const; + + /** + * This is an internal library function exposed on key types. + * In almost all cases applications should use wrappers in pubkey.h + * + * Return a verification operation for this key/params or throw + * @param params additional parameters + * @param provider the provider to use + */ + virtual std::unique_ptr + create_verification_op(const std::string& params, + const std::string& provider) const; + }; + +/** +* Private Key Base Class +*/ +class BOTAN_PUBLIC_API(2,0) Private_Key : public virtual Public_Key + { + public: + Private_Key() = default; + Private_Key(const Private_Key& other) = default; + Private_Key& operator=(const Private_Key& other) = default; + virtual ~Private_Key() = default; + + /** + * @return BER encoded private key bits + */ + virtual secure_vector private_key_bits() const = 0; + + /** + * @return PKCS #8 private key encoding for this key object + */ + secure_vector private_key_info() const; + + /** + * @return PKCS #8 AlgorithmIdentifier for this key + * Might be different from the X.509 identifier, but normally is not + */ + virtual AlgorithmIdentifier pkcs8_algorithm_identifier() const + { return algorithm_identifier(); } + + // Internal or non-public declarations follow + + /** + * @return Hash of the PKCS #8 encoding for this key object + */ + std::string fingerprint_private(const std::string& alg) const; + + BOTAN_DEPRECATED("Use fingerprint_private or fingerprint_public") + inline std::string fingerprint(const std::string& alg) const + { + return fingerprint_private(alg); // match behavior in previous versions + } + + /** + * This is an internal library function exposed on key types. + * In almost all cases applications should use wrappers in pubkey.h + * + * Return an decryption operation for this key/params or throw + * + * @param rng a random number generator. The PK_Op may maintain a + * reference to the RNG and use it many times. The rng must outlive + * any operations which reference it. + * @param params additional parameters + * @param provider the provider to use + * + */ + virtual std::unique_ptr + create_decryption_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) const; + + /** + * This is an internal library function exposed on key types. + * In almost all cases applications should use wrappers in pubkey.h + * + * Return a KEM decryption operation for this key/params or throw + * + * @param rng a random number generator. The PK_Op may maintain a + * reference to the RNG and use it many times. The rng must outlive + * any operations which reference it. + * @param params additional parameters + * @param provider the provider to use + */ + virtual std::unique_ptr + create_kem_decryption_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) const; + + /** + * This is an internal library function exposed on key types. + * In almost all cases applications should use wrappers in pubkey.h + * + * Return a signature operation for this key/params or throw + * + * @param rng a random number generator. The PK_Op may maintain a + * reference to the RNG and use it many times. The rng must outlive + * any operations which reference it. + * @param params additional parameters + * @param provider the provider to use + */ + virtual std::unique_ptr + create_signature_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) const; + + /** + * This is an internal library function exposed on key types. + * In almost all cases applications should use wrappers in pubkey.h + * + * Return a key agreement operation for this key/params or throw + * + * @param rng a random number generator. The PK_Op may maintain a + * reference to the RNG and use it many times. The rng must outlive + * any operations which reference it. + * @param params additional parameters + * @param provider the provider to use + */ + virtual std::unique_ptr + create_key_agreement_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) const; + }; + +/** +* PK Secret Value Derivation Key +*/ +class BOTAN_PUBLIC_API(2,0) PK_Key_Agreement_Key : public virtual Private_Key + { + public: + /* + * @return public component of this key + */ + virtual std::vector public_value() const = 0; + + PK_Key_Agreement_Key() = default; + PK_Key_Agreement_Key(const PK_Key_Agreement_Key&) = default; + PK_Key_Agreement_Key& operator=(const PK_Key_Agreement_Key&) = default; + virtual ~PK_Key_Agreement_Key() = default; + }; + +/* +* Old compat typedefs +* TODO: remove these? +*/ +typedef PK_Key_Agreement_Key PK_KA_Key; +typedef Public_Key X509_PublicKey; +typedef Private_Key PKCS8_PrivateKey; + +std::string BOTAN_PUBLIC_API(2,4) + create_hex_fingerprint(const uint8_t bits[], size_t len, + const std::string& hash_name); + +template +std::string create_hex_fingerprint(const std::vector& vec, + const std::string& hash_name) + { + return create_hex_fingerprint(vec.data(), vec.size(), hash_name); + } + + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/pk_ops.cpp b/src/libs/3rdparty/botan/src/lib/pubkey/pk_ops.cpp new file mode 100644 index 0000000000..025836878b --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pubkey/pk_ops.cpp @@ -0,0 +1,173 @@ +/* +* PK Operation Types +* (C) 2010,2015 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include + +namespace Botan { + +PK_Ops::Encryption_with_EME::Encryption_with_EME(const std::string& eme) + { + m_eme.reset(get_eme(eme)); + if(!m_eme.get()) + throw Algorithm_Not_Found(eme); + } + +size_t PK_Ops::Encryption_with_EME::max_input_bits() const + { + return 8 * m_eme->maximum_input_size(max_raw_input_bits()); + } + +secure_vector PK_Ops::Encryption_with_EME::encrypt(const uint8_t msg[], size_t msg_len, + RandomNumberGenerator& rng) + { + const size_t max_raw = max_raw_input_bits(); + const std::vector encoded = unlock(m_eme->encode(msg, msg_len, max_raw, rng)); + return raw_encrypt(encoded.data(), encoded.size(), rng); + } + +PK_Ops::Decryption_with_EME::Decryption_with_EME(const std::string& eme) + { + m_eme.reset(get_eme(eme)); + if(!m_eme.get()) + throw Algorithm_Not_Found(eme); + } + +secure_vector +PK_Ops::Decryption_with_EME::decrypt(uint8_t& valid_mask, + const uint8_t ciphertext[], + size_t ciphertext_len) + { + const secure_vector raw = raw_decrypt(ciphertext, ciphertext_len); + return m_eme->unpad(valid_mask, raw.data(), raw.size()); + } + +PK_Ops::Key_Agreement_with_KDF::Key_Agreement_with_KDF(const std::string& kdf) + { + if(kdf != "Raw") + m_kdf.reset(get_kdf(kdf)); + } + +secure_vector PK_Ops::Key_Agreement_with_KDF::agree(size_t key_len, + const uint8_t w[], size_t w_len, + const uint8_t salt[], size_t salt_len) + { + secure_vector z = raw_agree(w, w_len); + if(m_kdf) + return m_kdf->derive_key(key_len, z, salt, salt_len); + return z; + } + +PK_Ops::Signature_with_EMSA::Signature_with_EMSA(const std::string& emsa) : + Signature(), + m_emsa(get_emsa(emsa)), + m_hash(hash_for_emsa(emsa)), + m_prefix_used(false) + { + if(!m_emsa) + throw Algorithm_Not_Found(emsa); + } + +void PK_Ops::Signature_with_EMSA::update(const uint8_t msg[], size_t msg_len) + { + if(has_prefix() && !m_prefix_used) + { + m_prefix_used = true; + secure_vector prefix = message_prefix(); + m_emsa->update(prefix.data(), prefix.size()); + } + m_emsa->update(msg, msg_len); + } + +secure_vector PK_Ops::Signature_with_EMSA::sign(RandomNumberGenerator& rng) + { + m_prefix_used = false; + const secure_vector msg = m_emsa->raw_data(); + const auto padded = m_emsa->encoding_of(msg, this->max_input_bits(), rng); + return raw_sign(padded.data(), padded.size(), rng); + } + +PK_Ops::Verification_with_EMSA::Verification_with_EMSA(const std::string& emsa) : + Verification(), + m_emsa(get_emsa(emsa)), + m_hash(hash_for_emsa(emsa)), + m_prefix_used(false) + { + if(!m_emsa) + throw Algorithm_Not_Found(emsa); + } + +void PK_Ops::Verification_with_EMSA::update(const uint8_t msg[], size_t msg_len) + { + if(has_prefix() && !m_prefix_used) + { + m_prefix_used = true; + secure_vector prefix = message_prefix(); + m_emsa->update(prefix.data(), prefix.size()); + } + m_emsa->update(msg, msg_len); + } + +bool PK_Ops::Verification_with_EMSA::is_valid_signature(const uint8_t sig[], size_t sig_len) + { + m_prefix_used = false; + const secure_vector msg = m_emsa->raw_data(); + + if(with_recovery()) + { + secure_vector output_of_key = verify_mr(sig, sig_len); + return m_emsa->verify(output_of_key, msg, max_input_bits()); + } + else + { + Null_RNG rng; + secure_vector encoded = m_emsa->encoding_of(msg, max_input_bits(), rng); + return verify(encoded.data(), encoded.size(), sig, sig_len); + } + } + +void PK_Ops::KEM_Encryption_with_KDF::kem_encrypt(secure_vector& out_encapsulated_key, + secure_vector& out_shared_key, + size_t desired_shared_key_len, + Botan::RandomNumberGenerator& rng, + const uint8_t salt[], + size_t salt_len) + { + secure_vector raw_shared; + this->raw_kem_encrypt(out_encapsulated_key, raw_shared, rng); + + out_shared_key = m_kdf->derive_key(desired_shared_key_len, + raw_shared.data(), raw_shared.size(), + salt, salt_len); + } + +PK_Ops::KEM_Encryption_with_KDF::KEM_Encryption_with_KDF(const std::string& kdf) + { + m_kdf.reset(get_kdf(kdf)); + } + +secure_vector +PK_Ops::KEM_Decryption_with_KDF::kem_decrypt(const uint8_t encap_key[], + size_t len, + size_t desired_shared_key_len, + const uint8_t salt[], + size_t salt_len) + { + secure_vector raw_shared = this->raw_kem_decrypt(encap_key, len); + + return m_kdf->derive_key(desired_shared_key_len, + raw_shared.data(), raw_shared.size(), + salt, salt_len); + } + +PK_Ops::KEM_Decryption_with_KDF::KEM_Decryption_with_KDF(const std::string& kdf) + { + m_kdf.reset(get_kdf(kdf)); + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/pk_ops.h b/src/libs/3rdparty/botan/src/lib/pubkey/pk_ops.h new file mode 100644 index 0000000000..0aaf0b0dfe --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pubkey/pk_ops.h @@ -0,0 +1,150 @@ +/* +* (C) 2010,2015 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_PK_OPERATIONS_H_ +#define BOTAN_PK_OPERATIONS_H_ + +/** +* Ordinary applications should never need to include or use this +* header. It is exposed only for specialized applications which want +* to implement new versions of public key crypto without merging them +* as changes to the library. One actual example of such usage is an +* application which creates RSA signatures using a custom TPM library. +* Unless you're doing something like that, you don't need anything +* here. Instead use pubkey.h which wraps these types safely and +* provides a stable application-oriented API. +*/ + +#include +#include + +namespace Botan { + +class RandomNumberGenerator; +class EME; +class KDF; +class EMSA; + +namespace PK_Ops { + +/** +* Public key encryption interface +*/ +class BOTAN_PUBLIC_API(2,0) Encryption + { + public: + virtual secure_vector encrypt(const uint8_t msg[], + size_t msg_len, + RandomNumberGenerator& rng) = 0; + + virtual size_t max_input_bits() const = 0; + + virtual ~Encryption() = default; + }; + +/** +* Public key decryption interface +*/ +class BOTAN_PUBLIC_API(2,0) Decryption + { + public: + virtual secure_vector decrypt(uint8_t& valid_mask, + const uint8_t ciphertext[], + size_t ciphertext_len) = 0; + + virtual ~Decryption() = default; + }; + +/** +* Public key signature verification interface +*/ +class BOTAN_PUBLIC_API(2,0) Verification + { + public: + /* + * Add more data to the message currently being signed + * @param msg the message + * @param msg_len the length of msg in bytes + */ + virtual void update(const uint8_t msg[], size_t msg_len) = 0; + + /* + * Perform a verification operation + * @param rng a random number generator + */ + virtual bool is_valid_signature(const uint8_t sig[], size_t sig_len) = 0; + + virtual ~Verification() = default; + }; + +/** +* Public key signature creation interface +*/ +class BOTAN_PUBLIC_API(2,0) Signature + { + public: + /* + * Add more data to the message currently being signed + * @param msg the message + * @param msg_len the length of msg in bytes + */ + virtual void update(const uint8_t msg[], size_t msg_len) = 0; + + /* + * Perform a signature operation + * @param rng a random number generator + */ + virtual secure_vector sign(RandomNumberGenerator& rng) = 0; + + virtual ~Signature() = default; + }; + +/** +* A generic key agreement operation (eg DH or ECDH) +*/ +class BOTAN_PUBLIC_API(2,0) Key_Agreement + { + public: + virtual secure_vector agree(size_t key_len, + const uint8_t other_key[], size_t other_key_len, + const uint8_t salt[], size_t salt_len) = 0; + + virtual ~Key_Agreement() = default; + }; + +/** +* KEM (key encapsulation) +*/ +class BOTAN_PUBLIC_API(2,0) KEM_Encryption + { + public: + virtual void kem_encrypt(secure_vector& out_encapsulated_key, + secure_vector& out_shared_key, + size_t desired_shared_key_len, + Botan::RandomNumberGenerator& rng, + const uint8_t salt[], + size_t salt_len) = 0; + + virtual ~KEM_Encryption() = default; + }; + +class BOTAN_PUBLIC_API(2,0) KEM_Decryption + { + public: + virtual secure_vector kem_decrypt(const uint8_t encap_key[], + size_t len, + size_t desired_shared_key_len, + const uint8_t salt[], + size_t salt_len) = 0; + + virtual ~KEM_Decryption() = default; + }; + +} + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/pk_ops_fwd.h b/src/libs/3rdparty/botan/src/lib/pubkey/pk_ops_fwd.h new file mode 100644 index 0000000000..92a3c2a969 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pubkey/pk_ops_fwd.h @@ -0,0 +1,27 @@ +/* +* PK Operation Types Forward Decls +* (C) 2016 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_PK_OPERATIONS_FWD_H_ +#define BOTAN_PK_OPERATIONS_FWD_H_ + +namespace Botan { + +namespace PK_Ops { + +class Encryption; +class Decryption; +class Verification; +class Signature; +class Key_Agreement; +class KEM_Encryption; +class KEM_Decryption; + +} + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/pk_ops_impl.h b/src/libs/3rdparty/botan/src/lib/pubkey/pk_ops_impl.h new file mode 100644 index 0000000000..1878a74177 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pubkey/pk_ops_impl.h @@ -0,0 +1,231 @@ + +/* +* (C) 2015 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_PK_OPERATION_IMPL_H_ +#define BOTAN_PK_OPERATION_IMPL_H_ + +#include +#include +#include +#include + +namespace Botan { + +namespace PK_Ops { + +class Encryption_with_EME : public Encryption + { + public: + size_t max_input_bits() const override; + + secure_vector encrypt(const uint8_t msg[], size_t msg_len, + RandomNumberGenerator& rng) override; + + ~Encryption_with_EME() = default; + protected: + explicit Encryption_with_EME(const std::string& eme); + private: + virtual size_t max_raw_input_bits() const = 0; + + virtual secure_vector raw_encrypt(const uint8_t msg[], size_t len, + RandomNumberGenerator& rng) = 0; + std::unique_ptr m_eme; + }; + +class Decryption_with_EME : public Decryption + { + public: + secure_vector decrypt(uint8_t& valid_mask, + const uint8_t msg[], size_t msg_len) override; + + ~Decryption_with_EME() = default; + protected: + explicit Decryption_with_EME(const std::string& eme); + private: + virtual secure_vector raw_decrypt(const uint8_t msg[], size_t len) = 0; + std::unique_ptr m_eme; + }; + +class Verification_with_EMSA : public Verification + { + public: + ~Verification_with_EMSA() = default; + + void update(const uint8_t msg[], size_t msg_len) override; + bool is_valid_signature(const uint8_t sig[], size_t sig_len) override; + + bool do_check(const secure_vector& msg, + const uint8_t sig[], size_t sig_len); + + std::string hash_for_signature() { return m_hash; } + + protected: + explicit Verification_with_EMSA(const std::string& emsa); + + /** + * Get the maximum message size in bits supported by this public key. + * @return maximum message in bits + */ + virtual size_t max_input_bits() const = 0; + + /** + * @return boolean specifying if this signature scheme uses + * a message prefix returned by message_prefix() + */ + virtual bool has_prefix() { return false; } + + /** + * @return the message prefix if this signature scheme uses + * a message prefix, signaled via has_prefix() + */ + virtual secure_vector message_prefix() const { throw Exception( "No prefix" ); } + + /** + * @return boolean specifying if this key type supports message + * recovery and thus if you need to call verify() or verify_mr() + */ + virtual bool with_recovery() const = 0; + + /* + * Perform a signature check operation + * @param msg the message + * @param msg_len the length of msg in bytes + * @param sig the signature + * @param sig_len the length of sig in bytes + * @returns if signature is a valid one for message + */ + virtual bool verify(const uint8_t[], size_t, + const uint8_t[], size_t) + { + throw Invalid_State("Message recovery required"); + } + + /* + * Perform a signature operation (with message recovery) + * Only call this if with_recovery() returns true + * @param msg the message + * @param msg_len the length of msg in bytes + * @returns recovered message + */ + virtual secure_vector verify_mr(const uint8_t[], size_t) + { + throw Invalid_State("Message recovery not supported"); + } + + std::unique_ptr clone_emsa() const { return std::unique_ptr(m_emsa->clone()); } + + private: + std::unique_ptr m_emsa; + const std::string m_hash; + bool m_prefix_used; + }; + +class Signature_with_EMSA : public Signature + { + public: + void update(const uint8_t msg[], size_t msg_len) override; + + secure_vector sign(RandomNumberGenerator& rng) override; + protected: + explicit Signature_with_EMSA(const std::string& emsa); + ~Signature_with_EMSA() = default; + + std::string hash_for_signature() { return m_hash; } + + /** + * @return boolean specifying if this signature scheme uses + * a message prefix returned by message_prefix() + */ + virtual bool has_prefix() { return false; } + + /** + * @return the message prefix if this signature scheme uses + * a message prefix, signaled via has_prefix() + */ + virtual secure_vector message_prefix() const { throw Exception( "No prefix" ); } + + std::unique_ptr clone_emsa() const { return std::unique_ptr(m_emsa->clone()); } + + private: + + /** + * Get the maximum message size in bits supported by this public key. + * @return maximum message in bits + */ + virtual size_t max_input_bits() const = 0; + + bool self_test_signature(const std::vector& msg, + const std::vector& sig) const; + + virtual secure_vector raw_sign(const uint8_t msg[], size_t msg_len, + RandomNumberGenerator& rng) = 0; + + std::unique_ptr m_emsa; + const std::string m_hash; + bool m_prefix_used; + }; + +class Key_Agreement_with_KDF : public Key_Agreement + { + public: + secure_vector agree(size_t key_len, + const uint8_t other_key[], size_t other_key_len, + const uint8_t salt[], size_t salt_len) override; + + protected: + explicit Key_Agreement_with_KDF(const std::string& kdf); + ~Key_Agreement_with_KDF() = default; + private: + virtual secure_vector raw_agree(const uint8_t w[], size_t w_len) = 0; + std::unique_ptr m_kdf; + }; + +class KEM_Encryption_with_KDF : public KEM_Encryption + { + public: + void kem_encrypt(secure_vector& out_encapsulated_key, + secure_vector& out_shared_key, + size_t desired_shared_key_len, + Botan::RandomNumberGenerator& rng, + const uint8_t salt[], + size_t salt_len) override; + + protected: + virtual void raw_kem_encrypt(secure_vector& out_encapsulated_key, + secure_vector& raw_shared_key, + Botan::RandomNumberGenerator& rng) = 0; + + explicit KEM_Encryption_with_KDF(const std::string& kdf); + ~KEM_Encryption_with_KDF() = default; + private: + std::unique_ptr m_kdf; + }; + +class KEM_Decryption_with_KDF : public KEM_Decryption + { + public: + secure_vector kem_decrypt(const uint8_t encap_key[], + size_t len, + size_t desired_shared_key_len, + const uint8_t salt[], + size_t salt_len) override; + + protected: + virtual secure_vector + raw_kem_decrypt(const uint8_t encap_key[], size_t len) = 0; + + explicit KEM_Decryption_with_KDF(const std::string& kdf); + ~KEM_Decryption_with_KDF() = default; + private: + std::unique_ptr m_kdf; + }; + +} + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/pkcs8.cpp b/src/libs/3rdparty/botan/src/lib/pubkey/pkcs8.cpp new file mode 100644 index 0000000000..8d3eba6dc7 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pubkey/pkcs8.cpp @@ -0,0 +1,468 @@ +/* +* PKCS #8 +* (C) 1999-2010,2014,2018 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(BOTAN_HAS_PKCS5_PBES2) + #include +#endif + +namespace Botan { + +namespace PKCS8 { + +namespace { + +/* +* Get info from an EncryptedPrivateKeyInfo +*/ +secure_vector PKCS8_extract(DataSource& source, + AlgorithmIdentifier& pbe_alg_id) + { + secure_vector key_data; + + BER_Decoder(source) + .start_cons(SEQUENCE) + .decode(pbe_alg_id) + .decode(key_data, OCTET_STRING) + .verify_end(); + + return key_data; + } + +/* +* PEM decode and/or decrypt a private key +*/ +secure_vector PKCS8_decode( + DataSource& source, + std::function get_passphrase, + AlgorithmIdentifier& pk_alg_id, + bool is_encrypted) + { + AlgorithmIdentifier pbe_alg_id; + secure_vector key_data, key; + + try { + if(ASN1::maybe_BER(source) && !PEM_Code::matches(source)) + { + if(is_encrypted) + { + key_data = PKCS8_extract(source, pbe_alg_id); + } + else + { + // todo read more efficiently + while(!source.end_of_data()) + { + uint8_t b; + size_t read = source.read_byte(b); + if(read) + { + key_data.push_back(b); + } + } + } + } + else + { + std::string label; + key_data = PEM_Code::decode(source, label); + + // todo remove autodetect for pem as well? + if(label == "PRIVATE KEY") + is_encrypted = false; + else if(label == "ENCRYPTED PRIVATE KEY") + { + DataSource_Memory key_source(key_data); + key_data = PKCS8_extract(key_source, pbe_alg_id); + } + else + throw PKCS8_Exception("Unknown PEM label " + label); + } + + if(key_data.empty()) + throw PKCS8_Exception("No key data found"); + } + catch(Decoding_Error& e) + { + throw Decoding_Error("PKCS #8 private key decoding failed: " + std::string(e.what())); + } + + try + { + if(is_encrypted) + { + if(OIDS::lookup(pbe_alg_id.get_oid()) != "PBE-PKCS5v20") + throw Exception("Unknown PBE type " + pbe_alg_id.get_oid().as_string()); +#if defined(BOTAN_HAS_PKCS5_PBES2) + key = pbes2_decrypt(key_data, get_passphrase(), pbe_alg_id.get_parameters()); +#else + BOTAN_UNUSED(get_passphrase); + throw Decoding_Error("Private key is encrypted but PBES2 was disabled in build"); +#endif + } + else + key = key_data; + + BER_Decoder(key) + .start_cons(SEQUENCE) + .decode_and_check(0, "Unknown PKCS #8 version number") + .decode(pk_alg_id) + .decode(key, OCTET_STRING) + .discard_remaining() + .end_cons(); + } + catch(std::exception& e) + { + throw Decoding_Error("PKCS #8 private key decoding failed: " + std::string(e.what())); + } + return key; + } + +} + +/* +* BER encode a PKCS #8 private key, unencrypted +*/ +secure_vector BER_encode(const Private_Key& key) + { + // keeping around for compat + return key.private_key_info(); + } + +/* +* PEM encode a PKCS #8 private key, unencrypted +*/ +std::string PEM_encode(const Private_Key& key) + { + return PEM_Code::encode(PKCS8::BER_encode(key), "PRIVATE KEY"); + } + +#if defined(BOTAN_HAS_PKCS5_PBES2) + +namespace { + +std::pair +choose_pbe_params(const std::string& pbe_algo, const std::string& key_algo) + { + if(pbe_algo.empty()) + { + // Defaults: + if(key_algo == "Curve25519" || key_algo == "McEliece") + return std::make_pair("AES-256/GCM", "SHA-512"); + else // for everything else (RSA, DSA, ECDSA, GOST, ...) + return std::make_pair("AES-256/CBC", "SHA-256"); + } + + SCAN_Name request(pbe_algo); + if(request.algo_name() != "PBE-PKCS5v20" || request.arg_count() != 2) + throw Exception("Unsupported PBE " + pbe_algo); + return std::make_pair(request.arg(0), request.arg(1)); + } + +} + +#endif + +/* +* BER encode a PKCS #8 private key, encrypted +*/ +std::vector BER_encode(const Private_Key& key, + RandomNumberGenerator& rng, + const std::string& pass, + std::chrono::milliseconds msec, + const std::string& pbe_algo) + { +#if defined(BOTAN_HAS_PKCS5_PBES2) + const auto pbe_params = choose_pbe_params(pbe_algo, key.algo_name()); + + const std::pair> pbe_info = + pbes2_encrypt_msec(PKCS8::BER_encode(key), pass, msec, nullptr, + pbe_params.first, pbe_params.second, rng); + + std::vector output; + DER_Encoder der(output); + der.start_cons(SEQUENCE) + .encode(pbe_info.first) + .encode(pbe_info.second, OCTET_STRING) + .end_cons(); + + return output; +#else + BOTAN_UNUSED(key, rng, pass, msec, pbe_algo); + throw Encoding_Error("PKCS8::BER_encode cannot encrypt because PBES2 was disabled in build"); +#endif + } + +/* +* PEM encode a PKCS #8 private key, encrypted +*/ +std::string PEM_encode(const Private_Key& key, + RandomNumberGenerator& rng, + const std::string& pass, + std::chrono::milliseconds msec, + const std::string& pbe_algo) + { + if(pass.empty()) + return PEM_encode(key); + + return PEM_Code::encode(PKCS8::BER_encode(key, rng, pass, msec, pbe_algo), + "ENCRYPTED PRIVATE KEY"); + } + +/* +* BER encode a PKCS #8 private key, encrypted +*/ +std::vector BER_encode_encrypted_pbkdf_iter(const Private_Key& key, + RandomNumberGenerator& rng, + const std::string& pass, + size_t pbkdf_iterations, + const std::string& cipher, + const std::string& pbkdf_hash) + { +#if defined(BOTAN_HAS_PKCS5_PBES2) + const std::pair> pbe_info = + pbes2_encrypt_iter(key.private_key_info(), + pass, pbkdf_iterations, + cipher.empty() ? "AES-256/CBC" : cipher, + pbkdf_hash.empty() ? "SHA-256" : pbkdf_hash, + rng); + + std::vector output; + DER_Encoder der(output); + der.start_cons(SEQUENCE) + .encode(pbe_info.first) + .encode(pbe_info.second, OCTET_STRING) + .end_cons(); + + return output; + +#else + BOTAN_UNUSED(key, rng, pass, pbkdf_iterations, cipher, pbkdf_hash); + throw Encoding_Error("PKCS8::BER_encode_encrypted_pbkdf_iter cannot encrypt because PBES2 disabled in build"); +#endif + } + +/* +* PEM encode a PKCS #8 private key, encrypted +*/ +std::string PEM_encode_encrypted_pbkdf_iter(const Private_Key& key, + RandomNumberGenerator& rng, + const std::string& pass, + size_t pbkdf_iterations, + const std::string& cipher, + const std::string& pbkdf_hash) + { + return PEM_Code::encode( + PKCS8::BER_encode_encrypted_pbkdf_iter(key, rng, pass, pbkdf_iterations, cipher, pbkdf_hash), + "ENCRYPTED PRIVATE KEY"); + } + +/* +* BER encode a PKCS #8 private key, encrypted +*/ +std::vector BER_encode_encrypted_pbkdf_msec(const Private_Key& key, + RandomNumberGenerator& rng, + const std::string& pass, + std::chrono::milliseconds pbkdf_msec, + size_t* pbkdf_iterations, + const std::string& cipher, + const std::string& pbkdf_hash) + { +#if defined(BOTAN_HAS_PKCS5_PBES2) + const std::pair> pbe_info = + pbes2_encrypt_msec(key.private_key_info(), pass, + pbkdf_msec, pbkdf_iterations, + cipher.empty() ? "AES-256/CBC" : cipher, + pbkdf_hash.empty() ? "SHA-256" : pbkdf_hash, + rng); + + std::vector output; + DER_Encoder(output) + .start_cons(SEQUENCE) + .encode(pbe_info.first) + .encode(pbe_info.second, OCTET_STRING) + .end_cons(); + + return output; +#else + BOTAN_UNUSED(key, rng, pass, pbkdf_msec, pbkdf_iterations, cipher, pbkdf_hash); + throw Encoding_Error("BER_encode_encrypted_pbkdf_msec cannot encrypt because PBES2 disabled in build"); +#endif + } + +/* +* PEM encode a PKCS #8 private key, encrypted +*/ +std::string PEM_encode_encrypted_pbkdf_msec(const Private_Key& key, + RandomNumberGenerator& rng, + const std::string& pass, + std::chrono::milliseconds pbkdf_msec, + size_t* pbkdf_iterations, + const std::string& cipher, + const std::string& pbkdf_hash) + { + return PEM_Code::encode( + PKCS8::BER_encode_encrypted_pbkdf_msec(key, rng, pass, pbkdf_msec, pbkdf_iterations, cipher, pbkdf_hash), + "ENCRYPTED PRIVATE KEY"); + } + +namespace { + +/* +* Extract a private key (encrypted/unencrypted) and return it +*/ +std::unique_ptr +load_key(DataSource& source, + std::function get_pass, + bool is_encrypted) + { + AlgorithmIdentifier alg_id; + secure_vector pkcs8_key = PKCS8_decode(source, get_pass, alg_id, is_encrypted); + + const std::string alg_name = OIDS::lookup(alg_id.get_oid()); + if(alg_name.empty() || alg_name == alg_id.get_oid().as_string()) + throw PKCS8_Exception("Unknown algorithm OID: " + + alg_id.get_oid().as_string()); + + return load_private_key(alg_id, pkcs8_key); + } + +} + +/* +* Extract an encrypted private key and return it +*/ +std::unique_ptr load_key(DataSource& source, + std::function get_pass) + { + return load_key(source, get_pass, true); + } + +/* +* Extract an encrypted private key and return it +*/ +std::unique_ptr load_key(DataSource& source, + const std::string& pass) + { + return load_key(source, [pass]() { return pass; }, true); + } + +/* +* Extract an unencrypted private key and return it +*/ +std::unique_ptr load_key(DataSource& source) + { + auto fail_fn = []() -> std::string { + throw PKCS8_Exception("Internal error: Attempt to read password for unencrypted key"); + }; + + return load_key(source, fail_fn, false); + } + +/* +* Make a copy of this private key +*/ +std::unique_ptr copy_key(const Private_Key& key) + { + DataSource_Memory source(PEM_encode(key)); + return PKCS8::load_key(source); + } + +/* +* Extract an encrypted private key and return it +*/ +Private_Key* load_key(DataSource& source, + RandomNumberGenerator& rng, + std::function get_pass) + { + BOTAN_UNUSED(rng); + return PKCS8::load_key(source, get_pass).release(); + } + +/* +* Extract an encrypted private key and return it +*/ +Private_Key* load_key(DataSource& source, + RandomNumberGenerator& rng, + const std::string& pass) + { + BOTAN_UNUSED(rng); + return PKCS8::load_key(source, pass).release(); + } + +/* +* Extract an unencrypted private key and return it +*/ +Private_Key* load_key(DataSource& source, + RandomNumberGenerator& rng) + { + BOTAN_UNUSED(rng); + return PKCS8::load_key(source).release(); + } + +#if defined(BOTAN_TARGET_OS_HAS_FILESYSTEM) + +/* +* Extract an encrypted private key and return it +*/ +Private_Key* load_key(const std::string& fsname, + RandomNumberGenerator& rng, + std::function get_pass) + { + BOTAN_UNUSED(rng); + DataSource_Stream in(fsname); + return PKCS8::load_key(in, get_pass).release(); + } + +/* +* Extract an encrypted private key and return it +*/ +Private_Key* load_key(const std::string& fsname, + RandomNumberGenerator& rng, + const std::string& pass) + { + BOTAN_UNUSED(rng); + DataSource_Stream in(fsname); + return PKCS8::load_key(in, [pass]() { return pass; }).release(); + } + +/* +* Extract an unencrypted private key and return it +*/ +Private_Key* load_key(const std::string& fsname, + RandomNumberGenerator& rng) + { + BOTAN_UNUSED(rng); + DataSource_Stream in(fsname); + return PKCS8::load_key(in).release(); + } +#endif + +/* +* Make a copy of this private key +*/ +Private_Key* copy_key(const Private_Key& key, + RandomNumberGenerator& rng) + { + BOTAN_UNUSED(rng); + return PKCS8::copy_key(key).release(); + } + + + +} + +} diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/pkcs8.h b/src/libs/3rdparty/botan/src/lib/pubkey/pkcs8.h new file mode 100644 index 0000000000..0bc9a18f14 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pubkey/pkcs8.h @@ -0,0 +1,288 @@ +/* +* PKCS #8 +* (C) 1999-2007 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_PKCS8_H_ +#define BOTAN_PKCS8_H_ + +#include +#include +#include +#include +#include +#include + +namespace Botan { + +class DataSource; +class RandomNumberGenerator; + +/** +* PKCS #8 General Exception +*/ +class BOTAN_PUBLIC_API(2,0) PKCS8_Exception final : public Decoding_Error + { + public: + explicit PKCS8_Exception(const std::string& error) : + Decoding_Error("PKCS #8: " + error) {} + }; + +/** +* This namespace contains functions for handling PKCS #8 private keys +*/ +namespace PKCS8 { + +/** +* BER encode a private key +* @param key the private key to encode +* @return BER encoded key +*/ +BOTAN_PUBLIC_API(2,0) secure_vector BER_encode(const Private_Key& key); + +/** +* Get a string containing a PEM encoded private key. +* @param key the key to encode +* @return encoded key +*/ +BOTAN_PUBLIC_API(2,0) std::string PEM_encode(const Private_Key& key); + +/** +* Encrypt a key using PKCS #8 encryption +* @param key the key to encode +* @param rng the rng to use +* @param pass the password to use for encryption +* @param msec number of milliseconds to run the password derivation +* @param pbe_algo the name of the desired password-based encryption +* algorithm; if empty ("") a reasonable (portable/secure) +* default will be chosen. +* @return encrypted key in binary BER form +*/ +BOTAN_PUBLIC_API(2,0) std::vector +BER_encode(const Private_Key& key, + RandomNumberGenerator& rng, + const std::string& pass, + std::chrono::milliseconds msec = std::chrono::milliseconds(300), + const std::string& pbe_algo = ""); + +/** +* Get a string containing a PEM encoded private key, encrypting it with a +* password. +* @param key the key to encode +* @param rng the rng to use +* @param pass the password to use for encryption +* @param msec number of milliseconds to run the password derivation +* @param pbe_algo the name of the desired password-based encryption +* algorithm; if empty ("") a reasonable (portable/secure) +* default will be chosen. +* @return encrypted key in PEM form +*/ +BOTAN_PUBLIC_API(2,0) std::string +PEM_encode(const Private_Key& key, + RandomNumberGenerator& rng, + const std::string& pass, + std::chrono::milliseconds msec = std::chrono::milliseconds(300), + const std::string& pbe_algo = ""); + +/** +* Encrypt a key using PKCS #8 encryption and a fixed iteration count +* @param key the key to encode +* @param rng the rng to use +* @param pass the password to use for encryption +* @param pbkdf_iter number of interations to run PBKDF2 +* @param cipher if non-empty specifies the cipher to use. CBC and GCM modes +* are supported, for example "AES-128/CBC", "AES-256/GCM", "Serpent/CBC". +* If empty a suitable default is chosen. +* @param pbkdf_hash if non-empty specifies the PBKDF hash function to use. +* For example "SHA-256" or "SHA-384". If empty a suitable default is chosen. +* @return encrypted key in binary BER form +*/ +BOTAN_PUBLIC_API(2,1) std::vector +BER_encode_encrypted_pbkdf_iter(const Private_Key& key, + RandomNumberGenerator& rng, + const std::string& pass, + size_t pbkdf_iter, + const std::string& cipher = "", + const std::string& pbkdf_hash = ""); + +/** +* Get a string containing a PEM encoded private key, encrypting it with a +* password. +* @param key the key to encode +* @param rng the rng to use +* @param pass the password to use for encryption +* @param pbkdf_iter number of iterations to run PBKDF +* @param cipher if non-empty specifies the cipher to use. CBC and GCM modes +* are supported, for example "AES-128/CBC", "AES-256/GCM", "Serpent/CBC". +* If empty a suitable default is chosen. +* @param pbkdf_hash if non-empty specifies the PBKDF hash function to use. +* For example "SHA-256" or "SHA-384". If empty a suitable default is chosen. +* @return encrypted key in PEM form +*/ +BOTAN_PUBLIC_API(2,1) std::string +PEM_encode_encrypted_pbkdf_iter(const Private_Key& key, + RandomNumberGenerator& rng, + const std::string& pass, + size_t pbkdf_iter, + const std::string& cipher = "", + const std::string& pbkdf_hash = ""); + +/** +* Encrypt a key using PKCS #8 encryption and a variable iteration count +* @param key the key to encode +* @param rng the rng to use +* @param pass the password to use for encryption +* @param pbkdf_msec how long to run PBKDF2 +* @param pbkdf_iterations if non-null, set to the number of iterations used +* @param cipher if non-empty specifies the cipher to use. CBC and GCM modes +* are supported, for example "AES-128/CBC", "AES-256/GCM", "Serpent/CBC". +* If empty a suitable default is chosen. +* @param pbkdf_hash if non-empty specifies the PBKDF hash function to use. +* For example "SHA-256" or "SHA-384". If empty a suitable default is chosen. +* @return encrypted key in binary BER form +*/ +BOTAN_PUBLIC_API(2,1) std::vector +BER_encode_encrypted_pbkdf_msec(const Private_Key& key, + RandomNumberGenerator& rng, + const std::string& pass, + std::chrono::milliseconds pbkdf_msec, + size_t* pbkdf_iterations, + const std::string& cipher = "", + const std::string& pbkdf_hash = ""); + +/** +* Get a string containing a PEM encoded private key, encrypting it with a +* password. +* @param key the key to encode +* @param rng the rng to use +* @param pass the password to use for encryption +* @param pbkdf_msec how long in milliseconds to run PBKDF2 +* @param pbkdf_iterations (output argument) number of iterations of PBKDF +* that ended up being used +* @param cipher if non-empty specifies the cipher to use. CBC and GCM modes +* are supported, for example "AES-128/CBC", "AES-256/GCM", "Serpent/CBC". +* If empty a suitable default is chosen. +* @param pbkdf_hash if non-empty specifies the PBKDF hash function to use. +* For example "SHA-256" or "SHA-384". If empty a suitable default is chosen. +* @return encrypted key in PEM form +*/ +BOTAN_PUBLIC_API(2,1) std::string +PEM_encode_encrypted_pbkdf_msec(const Private_Key& key, + RandomNumberGenerator& rng, + const std::string& pass, + std::chrono::milliseconds pbkdf_msec, + size_t* pbkdf_iterations, + const std::string& cipher = "", + const std::string& pbkdf_hash = ""); + +/** +* Load an encrypted key from a data source. +* @param source the data source providing the encoded key +* @param rng ignored for compatability +* @param get_passphrase a function that returns passphrases +* @return loaded private key object +*/ +BOTAN_PUBLIC_API(2,0) Private_Key* load_key(DataSource& source, + RandomNumberGenerator& rng, + std::function get_passphrase); + +/** Load an encrypted key from a data source. +* @param source the data source providing the encoded key +* @param rng ignored for compatability +* @param pass the passphrase to decrypt the key +* @return loaded private key object +*/ +BOTAN_PUBLIC_API(2,0) Private_Key* load_key(DataSource& source, + RandomNumberGenerator& rng, + const std::string& pass); + +/** Load an unencrypted key from a data source. +* @param source the data source providing the encoded key +* @param rng ignored for compatability +* @return loaded private key object +*/ +BOTAN_PUBLIC_API(2,0) Private_Key* load_key(DataSource& source, + RandomNumberGenerator& rng); + +#if defined(BOTAN_TARGET_OS_HAS_FILESYSTEM) +/** +* Load an encrypted key from a file. +* @param filename the path to the file containing the encoded key +* @param rng ignored for compatability +* @param get_passphrase a function that returns passphrases +* @return loaded private key object +*/ +BOTAN_PUBLIC_API(2,0) Private_Key* load_key(const std::string& filename, + RandomNumberGenerator& rng, + std::function get_passphrase); + +/** Load an encrypted key from a file. +* @param filename the path to the file containing the encoded key +* @param rng ignored for compatability +* @param pass the passphrase to decrypt the key +* @return loaded private key object +*/ +BOTAN_PUBLIC_API(2,0) Private_Key* load_key(const std::string& filename, + RandomNumberGenerator& rng, + const std::string& pass); + +/** Load an unencrypted key from a file. +* @param filename the path to the file containing the encoded key +* @param rng ignored for compatability +* @return loaded private key object +*/ +BOTAN_PUBLIC_API(2,0) Private_Key* load_key(const std::string& filename, + RandomNumberGenerator& rng); +#endif + +/** +* Copy an existing encoded key object. +* @param key the key to copy +* @param rng ignored for compatability +* @return new copy of the key +*/ +BOTAN_PUBLIC_API(2,0) Private_Key* copy_key(const Private_Key& key, + RandomNumberGenerator& rng); + + +/** +* Load an encrypted key from a data source. +* @param source the data source providing the encoded key +* @param get_passphrase a function that returns passphrases +* @return loaded private key object +*/ +BOTAN_PUBLIC_API(2,3) +std::unique_ptr load_key(DataSource& source, + std::function get_passphrase); + +/** Load an encrypted key from a data source. +* @param source the data source providing the encoded key +* @param pass the passphrase to decrypt the key +* @return loaded private key object +*/ +BOTAN_PUBLIC_API(2,3) +std::unique_ptr load_key(DataSource& source, + const std::string& pass); + +/** Load an unencrypted key from a data source. +* @param source the data source providing the encoded key +* @return loaded private key object +*/ +BOTAN_PUBLIC_API(2,3) +std::unique_ptr load_key(DataSource& source); + +/** +* Copy an existing encoded key object. +* @param key the key to copy +* @return new copy of the key +*/ +BOTAN_PUBLIC_API(2,3) +std::unique_ptr copy_key(const Private_Key& key); + +} + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/pubkey.cpp b/src/libs/3rdparty/botan/src/lib/pubkey/pubkey.cpp new file mode 100644 index 0000000000..99d8927663 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pubkey/pubkey.cpp @@ -0,0 +1,350 @@ +/* +* (C) 1999-2010,2015,2018 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include +#include +#include +#include + +namespace Botan { + +secure_vector PK_Decryptor::decrypt(const uint8_t in[], size_t length) const + { + uint8_t valid_mask = 0; + + secure_vector decoded = do_decrypt(valid_mask, in, length); + + if(valid_mask == 0) + throw Decoding_Error("Invalid public key ciphertext, cannot decrypt"); + + return decoded; + } + +secure_vector +PK_Decryptor::decrypt_or_random(const uint8_t in[], + size_t length, + size_t expected_pt_len, + RandomNumberGenerator& rng, + const uint8_t required_content_bytes[], + const uint8_t required_content_offsets[], + size_t required_contents_length) const + { + const secure_vector fake_pms = rng.random_vec(expected_pt_len); + + uint8_t valid_mask = 0; + secure_vector decoded = do_decrypt(valid_mask, in, length); + + valid_mask &= CT::is_equal(decoded.size(), expected_pt_len); + + decoded.resize(expected_pt_len); + + for(size_t i = 0; i != required_contents_length; ++i) + { + /* + These values are chosen by the application and for TLS are constants, + so this early failure via assert is fine since we know 0,1 < 48 + + If there is a protocol that has content checks on the key where + the expected offsets are controllable by the attacker this could + still leak. + + Alternately could always reduce the offset modulo the length? + */ + + const uint8_t exp = required_content_bytes[i]; + const uint8_t off = required_content_offsets[i]; + + BOTAN_ASSERT(off < expected_pt_len, "Offset in range of plaintext"); + + valid_mask &= CT::is_equal(decoded[off], exp); + } + + CT::conditional_copy_mem(valid_mask, + /*output*/decoded.data(), + /*from0*/decoded.data(), + /*from1*/fake_pms.data(), + expected_pt_len); + + return decoded; + } + +secure_vector +PK_Decryptor::decrypt_or_random(const uint8_t in[], + size_t length, + size_t expected_pt_len, + RandomNumberGenerator& rng) const + { + return decrypt_or_random(in, length, expected_pt_len, rng, + nullptr, nullptr, 0); + } + +PK_Encryptor_EME::PK_Encryptor_EME(const Public_Key& key, + RandomNumberGenerator& rng, + const std::string& padding, + const std::string& provider) + { + m_op = key.create_encryption_op(rng, padding, provider); + if(!m_op) + throw Invalid_Argument("Key type " + key.algo_name() + " does not support encryption"); + } + +PK_Encryptor_EME::~PK_Encryptor_EME() { /* for unique_ptr */ } + +std::vector +PK_Encryptor_EME::enc(const uint8_t in[], size_t length, RandomNumberGenerator& rng) const + { + return unlock(m_op->encrypt(in, length, rng)); + } + +size_t PK_Encryptor_EME::maximum_input_size() const + { + return m_op->max_input_bits() / 8; + } + +PK_Decryptor_EME::PK_Decryptor_EME(const Private_Key& key, + RandomNumberGenerator& rng, + const std::string& padding, + const std::string& provider) + { + m_op = key.create_decryption_op(rng, padding, provider); + if(!m_op) + throw Invalid_Argument("Key type " + key.algo_name() + " does not support decryption"); + } + +PK_Decryptor_EME::~PK_Decryptor_EME() { /* for unique_ptr */ } + +secure_vector PK_Decryptor_EME::do_decrypt(uint8_t& valid_mask, + const uint8_t in[], size_t in_len) const + { + return m_op->decrypt(valid_mask, in, in_len); + } + +PK_KEM_Encryptor::PK_KEM_Encryptor(const Public_Key& key, + RandomNumberGenerator& rng, + const std::string& param, + const std::string& provider) + { + m_op = key.create_kem_encryption_op(rng, param, provider); + if(!m_op) + throw Invalid_Argument("Key type " + key.algo_name() + " does not support KEM encryption"); + } + +PK_KEM_Encryptor::~PK_KEM_Encryptor() { /* for unique_ptr */ } + +void PK_KEM_Encryptor::encrypt(secure_vector& out_encapsulated_key, + secure_vector& out_shared_key, + size_t desired_shared_key_len, + Botan::RandomNumberGenerator& rng, + const uint8_t salt[], + size_t salt_len) + { + m_op->kem_encrypt(out_encapsulated_key, + out_shared_key, + desired_shared_key_len, + rng, + salt, + salt_len); + } + +PK_KEM_Decryptor::PK_KEM_Decryptor(const Private_Key& key, + RandomNumberGenerator& rng, + const std::string& param, + const std::string& provider) + { + m_op = key.create_kem_decryption_op(rng, param, provider); + if(!m_op) + throw Invalid_Argument("Key type " + key.algo_name() + " does not support KEM decryption"); + } + +PK_KEM_Decryptor::~PK_KEM_Decryptor() { /* for unique_ptr */ } + +secure_vector PK_KEM_Decryptor::decrypt(const uint8_t encap_key[], + size_t encap_key_len, + size_t desired_shared_key_len, + const uint8_t salt[], + size_t salt_len) + { + return m_op->kem_decrypt(encap_key, encap_key_len, + desired_shared_key_len, + salt, salt_len); + } + +PK_Key_Agreement::PK_Key_Agreement(const Private_Key& key, + RandomNumberGenerator& rng, + const std::string& kdf, + const std::string& provider) + { + m_op = key.create_key_agreement_op(rng, kdf, provider); + if(!m_op) + throw Invalid_Argument("Key type " + key.algo_name() + " does not support key agreement"); + } + +PK_Key_Agreement::~PK_Key_Agreement() { /* for unique_ptr */ } + +PK_Key_Agreement& PK_Key_Agreement::operator=(PK_Key_Agreement&& other) + { + if(this != &other) + { + m_op = std::move(other.m_op); + } + return (*this); + } + +PK_Key_Agreement::PK_Key_Agreement(PK_Key_Agreement&& other) : + m_op(std::move(other.m_op)) + {} + +SymmetricKey PK_Key_Agreement::derive_key(size_t key_len, + const uint8_t in[], size_t in_len, + const uint8_t salt[], + size_t salt_len) const + { + return m_op->agree(key_len, in, in_len, salt, salt_len); + } + +PK_Signer::PK_Signer(const Private_Key& key, + RandomNumberGenerator& rng, + const std::string& emsa, + Signature_Format format, + const std::string& provider) + { + m_op = key.create_signature_op(rng, emsa, provider); + if(!m_op) + throw Invalid_Argument("Key type " + key.algo_name() + " does not support signature generation"); + m_sig_format = format; + m_parts = key.message_parts(); + m_part_size = key.message_part_size(); + } + +PK_Signer::~PK_Signer() { /* for unique_ptr */ } + +void PK_Signer::update(const uint8_t in[], size_t length) + { + m_op->update(in, length); + } + +namespace { + +std::vector der_encode_signature(const std::vector& sig, + size_t parts, + size_t part_size) + { + if(sig.size() % parts != 0 || sig.size() != parts * part_size) + throw Encoding_Error("Unexpected size for DER signature"); + + std::vector sig_parts(parts); + for(size_t i = 0; i != sig_parts.size(); ++i) + sig_parts[i].binary_decode(&sig[part_size*i], part_size); + + std::vector output; + DER_Encoder(output) + .start_cons(SEQUENCE) + .encode_list(sig_parts) + .end_cons(); + return output; + } + +} + +std::vector PK_Signer::signature(RandomNumberGenerator& rng) + { + const std::vector sig = unlock(m_op->sign(rng)); + + if(m_sig_format == IEEE_1363) + { + return sig; + } + else if(m_sig_format == DER_SEQUENCE) + { + return der_encode_signature(sig, m_parts, m_part_size); + } + else + throw Internal_Error("PK_Signer: Invalid signature format enum"); + } + +PK_Verifier::PK_Verifier(const Public_Key& key, + const std::string& emsa, + Signature_Format format, + const std::string& provider) + { + m_op = key.create_verification_op(emsa, provider); + if(!m_op) + throw Invalid_Argument("Key type " + key.algo_name() + " does not support signature verification"); + m_sig_format = format; + m_parts = key.message_parts(); + m_part_size = key.message_part_size(); + } + +PK_Verifier::~PK_Verifier() { /* for unique_ptr */ } + +void PK_Verifier::set_input_format(Signature_Format format) + { + if(format != IEEE_1363 && m_parts == 1) + throw Invalid_Argument("PK_Verifier: This algorithm does not support DER encoding"); + m_sig_format = format; + } + +bool PK_Verifier::verify_message(const uint8_t msg[], size_t msg_length, + const uint8_t sig[], size_t sig_length) + { + update(msg, msg_length); + return check_signature(sig, sig_length); + } + +void PK_Verifier::update(const uint8_t in[], size_t length) + { + m_op->update(in, length); + } + +bool PK_Verifier::check_signature(const uint8_t sig[], size_t length) + { + try { + if(m_sig_format == IEEE_1363) + { + return m_op->is_valid_signature(sig, length); + } + else if(m_sig_format == DER_SEQUENCE) + { + std::vector real_sig; + BER_Decoder decoder(sig, length); + BER_Decoder ber_sig = decoder.start_cons(SEQUENCE); + + BOTAN_ASSERT_NOMSG(m_parts != 0 && m_part_size != 0); + + size_t count = 0; + + while(ber_sig.more_items()) + { + BigInt sig_part; + ber_sig.decode(sig_part); + real_sig += BigInt::encode_1363(sig_part, m_part_size); + ++count; + } + + if(count != m_parts) + throw Decoding_Error("PK_Verifier: signature size invalid"); + + const std::vector reencoded = + der_encode_signature(real_sig, m_parts, m_part_size); + + if(reencoded.size() != length || + same_mem(reencoded.data(), sig, reencoded.size()) == false) + { + throw Decoding_Error("PK_Verifier: signature is not the canonical DER encoding"); + } + + return m_op->is_valid_signature(real_sig.data(), real_sig.size()); + } + else + throw Internal_Error("PK_Verifier: Invalid signature format enum"); + } + catch(Invalid_Argument&) { return false; } + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/pubkey.h b/src/libs/3rdparty/botan/src/lib/pubkey/pubkey.h new file mode 100644 index 0000000000..a33142079f --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pubkey/pubkey.h @@ -0,0 +1,771 @@ +/* +* Public Key Interface +* (C) 1999-2010 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_PUBKEY_H_ +#define BOTAN_PUBKEY_H_ + +#include +#include +#include + +#if defined(BOTAN_HAS_SYSTEM_RNG) + #include + #define BOTAN_PUBKEY_INCLUDE_DEPRECATED_CONSTRUCTORS +#endif + +namespace Botan { + +class RandomNumberGenerator; + +/** +* The two types of signature format supported by Botan. +*/ +enum Signature_Format { IEEE_1363, DER_SEQUENCE }; + +/** +* Public Key Encryptor +* This is the primary interface for public key encryption +*/ +class BOTAN_PUBLIC_API(2,0) PK_Encryptor + { + public: + + /** + * Encrypt a message. + * @param in the message as a byte array + * @param length the length of the above byte array + * @param rng the random number source to use + * @return encrypted message + */ + std::vector encrypt(const uint8_t in[], size_t length, + RandomNumberGenerator& rng) const + { + return enc(in, length, rng); + } + + /** + * Encrypt a message. + * @param in the message + * @param rng the random number source to use + * @return encrypted message + */ + template + std::vector encrypt(const std::vector& in, + RandomNumberGenerator& rng) const + { + return enc(in.data(), in.size(), rng); + } + + /** + * Return the maximum allowed message size in bytes. + * @return maximum message size in bytes + */ + virtual size_t maximum_input_size() const = 0; + + PK_Encryptor() = default; + virtual ~PK_Encryptor() = default; + + PK_Encryptor(const PK_Encryptor&) = delete; + PK_Encryptor& operator=(const PK_Encryptor&) = delete; + + private: + virtual std::vector enc(const uint8_t[], size_t, + RandomNumberGenerator&) const = 0; + }; + +/** +* Public Key Decryptor +*/ +class BOTAN_PUBLIC_API(2,0) PK_Decryptor + { + public: + /** + * Decrypt a ciphertext, throwing an exception if the input + * seems to be invalid (eg due to an accidental or malicious + * error in the ciphertext). + * + * @param in the ciphertext as a byte array + * @param length the length of the above byte array + * @return decrypted message + */ + secure_vector decrypt(const uint8_t in[], size_t length) const; + + /** + * Same as above, but taking a vector + * @param in the ciphertext + * @return decrypted message + */ + template + secure_vector decrypt(const std::vector& in) const + { + return decrypt(in.data(), in.size()); + } + + /** + * Decrypt a ciphertext. If the ciphertext is invalid (eg due to + * invalid padding) or is not the expected length, instead + * returns a random string of the expected length. Use to avoid + * oracle attacks, especially against PKCS #1 v1.5 decryption. + */ + secure_vector + decrypt_or_random(const uint8_t in[], + size_t length, + size_t expected_pt_len, + RandomNumberGenerator& rng) const; + + /** + * Decrypt a ciphertext. If the ciphertext is invalid (eg due to + * invalid padding) or is not the expected length, instead + * returns a random string of the expected length. Use to avoid + * oracle attacks, especially against PKCS #1 v1.5 decryption. + * + * Additionally checks (also in const time) that: + * contents[required_content_offsets[i]] == required_content_bytes[i] + * for 0 <= i < required_contents + * + * Used for example in TLS, which encodes the client version in + * the content bytes: if there is any timing variation the version + * check can be used as an oracle to recover the key. + */ + secure_vector + decrypt_or_random(const uint8_t in[], + size_t length, + size_t expected_pt_len, + RandomNumberGenerator& rng, + const uint8_t required_content_bytes[], + const uint8_t required_content_offsets[], + size_t required_contents) const; + + PK_Decryptor() = default; + virtual ~PK_Decryptor() = default; + + PK_Decryptor(const PK_Decryptor&) = delete; + PK_Decryptor& operator=(const PK_Decryptor&) = delete; + + private: + virtual secure_vector do_decrypt(uint8_t& valid_mask, + const uint8_t in[], size_t in_len) const = 0; + }; + +/** +* Public Key Signer. Use the sign_message() functions for small +* messages. Use multiple calls update() to process large messages and +* generate the signature by finally calling signature(). +*/ +class BOTAN_PUBLIC_API(2,0) PK_Signer final + { + public: + + /** + * Construct a PK Signer. + * @param key the key to use inside this signer + * @param rng the random generator to use + * @param emsa the EMSA to use + * An example would be "EMSA1(SHA-224)". + * @param format the signature format to use + * @param provider the provider to use + */ + PK_Signer(const Private_Key& key, + RandomNumberGenerator& rng, + const std::string& emsa, + Signature_Format format = IEEE_1363, + const std::string& provider = ""); + +#if defined(BOTAN_PUBKEY_INCLUDE_DEPRECATED_CONSTRUCTORS) + /** + * Construct a PK Signer. + * @param key the key to use inside this signer + * @param emsa the EMSA to use + * An example would be "EMSA1(SHA-224)". + * @param format the signature format to use + */ + BOTAN_DEPRECATED("Use constructor taking a RNG object") + PK_Signer(const Private_Key& key, + const std::string& emsa, + Signature_Format format = IEEE_1363, + const std::string& provider = "") : + PK_Signer(key, system_rng(), emsa, format, provider) + {} +#endif + + ~PK_Signer(); + + PK_Signer(const PK_Signer&) = delete; + PK_Signer& operator=(const PK_Signer&) = delete; + + /** + * Sign a message all in one go + * @param in the message to sign as a byte array + * @param length the length of the above byte array + * @param rng the rng to use + * @return signature + */ + std::vector sign_message(const uint8_t in[], size_t length, + RandomNumberGenerator& rng) + { + this->update(in, length); + return this->signature(rng); + } + + /** + * Sign a message. + * @param in the message to sign + * @param rng the rng to use + * @return signature + */ + std::vector sign_message(const std::vector& 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 sign_message(const secure_vector& in, + RandomNumberGenerator& rng) + { return sign_message(in.data(), in.size(), rng); } + + /** + * Add a message part (single byte). + * @param in the byte to add + */ + void update(uint8_t in) { update(&in, 1); } + + /** + * Add a message part. + * @param in the message part to add as a byte array + * @param length the length of the above byte array + */ + void update(const uint8_t in[], size_t length); + + /** + * Add a message part. + * @param in the message part to add + */ + void update(const std::vector& in) { update(in.data(), in.size()); } + + /** + * Add a message part. + * @param in the message part to add + */ + void update(const std::string& in) + { + update(cast_char_ptr_to_uint8(in.data()), in.size()); + } + + /** + * Get the signature of the so far processed message (provided by the + * calls to update()). + * @param rng the rng to use + * @return signature of the total message + */ + std::vector 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; } + private: + std::unique_ptr m_op; + Signature_Format m_sig_format; + size_t m_parts, m_part_size; + }; + +/** +* Public Key Verifier. Use the verify_message() functions for small +* messages. Use multiple calls update() to process large messages and +* verify the signature by finally calling check_signature(). +*/ +class BOTAN_PUBLIC_API(2,0) PK_Verifier final + { + public: + /** + * Construct a PK Verifier. + * @param pub_key the public key to verify against + * @param emsa the EMSA to use (eg "EMSA3(SHA-1)") + * @param format the signature format to use + * @param provider the provider to use + */ + PK_Verifier(const Public_Key& pub_key, + const std::string& emsa, + Signature_Format format = IEEE_1363, + const std::string& provider = ""); + + ~PK_Verifier(); + + PK_Verifier& operator=(const PK_Verifier&) = delete; + PK_Verifier(const PK_Verifier&) = delete; + + /** + * Verify a signature. + * @param msg the message that the signature belongs to, as a byte array + * @param msg_length the length of the above byte array msg + * @param sig the signature as a byte array + * @param sig_length the length of the above byte array sig + * @return true if the signature is valid + */ + bool verify_message(const uint8_t msg[], size_t msg_length, + const uint8_t sig[], size_t sig_length); + /** + * Verify a signature. + * @param msg the message that the signature belongs to + * @param sig the signature + * @return true if the signature is valid + */ + template + bool verify_message(const std::vector& msg, + const std::vector& sig) + { + return verify_message(msg.data(), msg.size(), + sig.data(), sig.size()); + } + + /** + * Add a message part (single byte) of the message corresponding to the + * signature to be verified. + * @param in the byte to add + */ + void update(uint8_t in) { update(&in, 1); } + + /** + * Add a message part of the message corresponding to the + * signature to be verified. + * @param msg_part the new message part as a byte array + * @param length the length of the above byte array + */ + void update(const uint8_t msg_part[], size_t length); + + /** + * Add a message part of the message corresponding to the + * signature to be verified. + * @param in the new message part + */ + void update(const std::vector& in) + { update(in.data(), in.size()); } + + /** + * Add a message part of the message corresponding to the + * signature to be verified. + */ + void update(const std::string& in) + { + update(cast_char_ptr_to_uint8(in.data()), in.size()); + } + + /** + * Check the signature of the buffered message, i.e. the one build + * by successive calls to update. + * @param sig the signature to be verified as a byte array + * @param length the length of the above byte array + * @return true if the signature is valid, false otherwise + */ + bool check_signature(const uint8_t sig[], size_t length); + + /** + * Check the signature of the buffered message, i.e. the one build + * by successive calls to update. + * @param sig the signature to be verified + * @return true if the signature is valid, false otherwise + */ + template + bool check_signature(const std::vector& sig) + { + return check_signature(sig.data(), sig.size()); + } + + /** + * Set the format of the signatures fed to this verifier. + * @param format the signature format to use + */ + void set_input_format(Signature_Format format); + + private: + std::unique_ptr m_op; + Signature_Format m_sig_format; + size_t m_parts, m_part_size; + }; + +/** +* Key used for key agreement +*/ +class BOTAN_PUBLIC_API(2,0) PK_Key_Agreement final + { + public: + + /** + * Construct a PK Key Agreement. + * @param key the key to use + * @param rng the random generator to use + * @param kdf name of the KDF to use (or 'Raw' for no KDF) + * @param provider the algo provider to use (or empty for default) + */ + PK_Key_Agreement(const Private_Key& key, + RandomNumberGenerator& rng, + const std::string& kdf, + const std::string& provider = ""); + +#if defined(BOTAN_PUBKEY_INCLUDE_DEPRECATED_CONSTRUCTORS) + /** + * Construct a PK Key Agreement. + * @param key the key to use + * @param kdf name of the KDF to use (or 'Raw' for no KDF) + * @param provider the algo provider to use (or empty for default) + */ + BOTAN_DEPRECATED("Use constructor taking a RNG object") + PK_Key_Agreement(const Private_Key& key, + const std::string& kdf, + const std::string& provider = "") : + PK_Key_Agreement(key, system_rng(), kdf, provider) + {} +#endif + + ~PK_Key_Agreement(); + + // For ECIES + PK_Key_Agreement& operator=(PK_Key_Agreement&&); + PK_Key_Agreement(PK_Key_Agreement&&); + + 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 + * @param in_len the length of in in bytes + * @param params extra derivation params + * @param params_len the length of params in bytes + */ + SymmetricKey derive_key(size_t key_len, + const uint8_t in[], + size_t in_len, + 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 + */ + SymmetricKey derive_key(size_t key_len, + const std::vector& in, + const uint8_t params[], + size_t params_len) const + { + return derive_key(key_len, in.data(), in.size(), + params, params_len); + } + + /* + * 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 + */ + SymmetricKey derive_key(size_t key_len, + const uint8_t in[], size_t in_len, + const std::string& params = "") const + { + return derive_key(key_len, in, in_len, + cast_char_ptr_to_uint8(params.data()), + params.length()); + } + + /* + * Perform Key Agreement Operation + * @param key_len the desired key output size + * @param in the other parties key + * @param params extra derivation params + */ + SymmetricKey derive_key(size_t key_len, + const std::vector& in, + const std::string& params = "") const + { + return derive_key(key_len, in.data(), in.size(), + cast_char_ptr_to_uint8(params.data()), + params.length()); + } + + private: + std::unique_ptr m_op; + }; + +/** +* Encryption using a standard message recovery algorithm like RSA or +* ElGamal, paired with an encoding scheme like OAEP. +*/ +class BOTAN_PUBLIC_API(2,0) PK_Encryptor_EME final : public PK_Encryptor + { + public: + size_t maximum_input_size() const override; + + /** + * Construct an instance. + * @param key the key to use inside the encryptor + * @param rng the RNG to use + * @param padding the message encoding scheme to use (eg "OAEP(SHA-256)") + * @param provider the provider to use + */ + PK_Encryptor_EME(const Public_Key& key, + RandomNumberGenerator& rng, + const std::string& padding, + const std::string& provider = ""); + +#if defined(BOTAN_PUBKEY_INCLUDE_DEPRECATED_CONSTRUCTORS) + /** + * Construct an instance. + * @param key the key to use inside the encryptor + * @param padding the message encoding scheme to use (eg "OAEP(SHA-256)") + */ + BOTAN_DEPRECATED("Use constructor taking a RNG object") + PK_Encryptor_EME(const Public_Key& key, + const std::string& padding, + const std::string& provider = "") : + PK_Encryptor_EME(key, system_rng(), padding, provider) {} +#endif + + ~PK_Encryptor_EME(); + + PK_Encryptor_EME& operator=(const PK_Encryptor_EME&) = delete; + PK_Encryptor_EME(const PK_Encryptor_EME&) = delete; + private: + std::vector enc(const uint8_t[], size_t, + RandomNumberGenerator& rng) const override; + + std::unique_ptr m_op; + }; + +/** +* Decryption with an MR algorithm and an EME. +*/ +class BOTAN_PUBLIC_API(2,0) PK_Decryptor_EME final : public PK_Decryptor + { + public: + /** + * Construct an instance. + * @param key the key to use inside the decryptor + * @param rng the random generator to use + * @param eme the EME to use + * @param provider the provider to use + */ + PK_Decryptor_EME(const Private_Key& key, + RandomNumberGenerator& rng, + const std::string& eme, + const std::string& provider = ""); + + +#if defined(BOTAN_PUBKEY_INCLUDE_DEPRECATED_CONSTRUCTORS) + /** + * Construct an instance. + * @param key the key to use inside the decryptor + * @param eme the message encoding scheme to use (eg "OAEP(SHA-256)") + */ + BOTAN_DEPRECATED("Use constructor taking a RNG object") + PK_Decryptor_EME(const Private_Key& key, + const std::string& eme, + const std::string& provider = "") : + PK_Decryptor_EME(key, system_rng(), eme, provider) {} +#endif + + ~PK_Decryptor_EME(); + PK_Decryptor_EME& operator=(const PK_Decryptor_EME&) = delete; + PK_Decryptor_EME(const PK_Decryptor_EME&) = delete; + private: + secure_vector do_decrypt(uint8_t& valid_mask, + const uint8_t in[], + size_t in_len) const override; + + std::unique_ptr m_op; + }; + +/** +* Public Key Key Encapsulation Mechanism Encryption. +*/ +class BOTAN_PUBLIC_API(2,0) PK_KEM_Encryptor final + { + public: + /** + * Construct an instance. + * @param key the key to use inside the encryptor + * @param rng the RNG to use + * @param kem_param additional KEM parameters + * @param provider the provider to use + */ + PK_KEM_Encryptor(const Public_Key& key, + RandomNumberGenerator& rng, + const std::string& kem_param = "", + const std::string& provider = ""); + +#if defined(BOTAN_PUBKEY_INCLUDE_DEPRECATED_CONSTRUCTORS) + BOTAN_DEPRECATED("Use constructor taking a RNG object") + PK_KEM_Encryptor(const Public_Key& key, + const std::string& kem_param = "", + const std::string& provider = "") : + PK_KEM_Encryptor(key, system_rng(), kem_param, provider) {} +#endif + + ~PK_KEM_Encryptor(); + + PK_KEM_Encryptor& operator=(const PK_KEM_Encryptor&) = delete; + PK_KEM_Encryptor(const PK_KEM_Encryptor&) = delete; + + /** + * Generate a shared key for data encryption. + * @param out_encapsulated_key the generated encapsulated key + * @param out_shared_key the generated shared key + * @param desired_shared_key_len desired size of the shared key in bytes + * @param rng the RNG to use + * @param salt a salt value used in the KDF + * @param salt_len size of the salt value in bytes + */ + void encrypt(secure_vector& out_encapsulated_key, + secure_vector& out_shared_key, + size_t desired_shared_key_len, + Botan::RandomNumberGenerator& rng, + const uint8_t salt[], + size_t salt_len); + + /** + * Generate a shared key for data encryption. + * @param out_encapsulated_key the generated encapsulated key + * @param out_shared_key the generated shared key + * @param desired_shared_key_len desired size of the shared key in bytes + * @param rng the RNG to use + * @param salt a salt value used in the KDF + */ + template + void encrypt(secure_vector& out_encapsulated_key, + secure_vector& out_shared_key, + size_t desired_shared_key_len, + Botan::RandomNumberGenerator& rng, + const std::vector& salt) + { + this->encrypt(out_encapsulated_key, + out_shared_key, + desired_shared_key_len, + rng, + salt.data(), salt.size()); + } + + + /** + * Generate a shared key for data encryption. + * @param out_encapsulated_key the generated encapsulated key + * @param out_shared_key the generated shared key + * @param desired_shared_key_len desired size of the shared key in bytes + * @param rng the RNG to use + */ + void encrypt(secure_vector& out_encapsulated_key, + secure_vector& out_shared_key, + size_t desired_shared_key_len, + Botan::RandomNumberGenerator& rng) + { + this->encrypt(out_encapsulated_key, + out_shared_key, + desired_shared_key_len, + rng, + nullptr, + 0); + } + + private: + std::unique_ptr m_op; + }; + +/** +* Public Key Key Encapsulation Mechanism Decryption. +*/ +class BOTAN_PUBLIC_API(2,0) PK_KEM_Decryptor final + { + public: + /** + * Construct an instance. + * @param key the key to use inside the decryptor + * @param rng the RNG to use + * @param kem_param additional KEM parameters + * @param provider the provider to use + */ + PK_KEM_Decryptor(const Private_Key& key, + RandomNumberGenerator& rng, + const std::string& kem_param = "", + const std::string& provider = ""); + +#if defined(BOTAN_PUBKEY_INCLUDE_DEPRECATED_CONSTRUCTORS) + BOTAN_DEPRECATED("Use constructor taking a RNG object") + PK_KEM_Decryptor(const Private_Key& key, + const std::string& kem_param = "", + const std::string& provider = "") : + PK_KEM_Decryptor(key, system_rng(), kem_param, provider) + {} +#endif + + ~PK_KEM_Decryptor(); + PK_KEM_Decryptor& operator=(const PK_KEM_Decryptor&) = delete; + PK_KEM_Decryptor(const PK_KEM_Decryptor&) = delete; + + /** + * Decrypts the shared key for data encryption. + * @param encap_key the encapsulated key + * @param encap_key_len size of the encapsulated key in bytes + * @param desired_shared_key_len desired size of the shared key in bytes + * @param salt a salt value used in the KDF + * @param salt_len size of the salt value in bytes + * @return the shared data encryption key + */ + secure_vector decrypt(const uint8_t encap_key[], + size_t encap_key_len, + size_t desired_shared_key_len, + const uint8_t salt[], + size_t salt_len); + + /** + * Decrypts the shared key for data encryption. + * @param encap_key the encapsulated key + * @param encap_key_len size of the encapsulated key in bytes + * @param desired_shared_key_len desired size of the shared key in bytes + * @return the shared data encryption key + */ + secure_vector decrypt(const uint8_t encap_key[], + size_t encap_key_len, + size_t desired_shared_key_len) + { + return this->decrypt(encap_key, encap_key_len, + desired_shared_key_len, + nullptr, 0); + } + + /** + * Decrypts the shared key for data encryption. + * @param encap_key the encapsulated key + * @param desired_shared_key_len desired size of the shared key in bytes + * @param salt a salt value used in the KDF + * @return the shared data encryption key + */ + template + secure_vector decrypt(const std::vector& encap_key, + size_t desired_shared_key_len, + const std::vector& salt) + { + return this->decrypt(encap_key.data(), encap_key.size(), + desired_shared_key_len, + salt.data(), salt.size()); + } + + private: + std::unique_ptr m_op; + }; + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/rsa/info.txt b/src/libs/3rdparty/botan/src/lib/pubkey/rsa/info.txt new file mode 100644 index 0000000000..9fc9354b83 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pubkey/rsa/info.txt @@ -0,0 +1,10 @@ + +RSA -> 20160730 + + + +keypair +numbertheory +emsa_pssr +sha2_32 + diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/rsa/rsa.cpp b/src/libs/3rdparty/botan/src/lib/pubkey/rsa/rsa.cpp new file mode 100644 index 0000000000..eb4c612ae0 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pubkey/rsa/rsa.cpp @@ -0,0 +1,579 @@ +/* +* RSA +* (C) 1999-2010,2015,2016,2018 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(BOTAN_HAS_OPENSSL) + #include +#endif + +#if defined(BOTAN_TARGET_OS_HAS_THREADS) + #include +#endif + +namespace Botan { + +size_t RSA_PublicKey::key_length() const + { + return m_n.bits(); + } + +size_t RSA_PublicKey::estimated_strength() const + { + return if_work_factor(key_length()); + } + +AlgorithmIdentifier RSA_PublicKey::algorithm_identifier() const + { + return AlgorithmIdentifier(get_oid(), + AlgorithmIdentifier::USE_NULL_PARAM); + } + +std::vector RSA_PublicKey::public_key_bits() const + { + std::vector output; + DER_Encoder der(output); + der.start_cons(SEQUENCE) + .encode(m_n) + .encode(m_e) + .end_cons(); + + return output; + } + +RSA_PublicKey::RSA_PublicKey(const AlgorithmIdentifier&, + const std::vector& key_bits) + { + BER_Decoder(key_bits) + .start_cons(SEQUENCE) + .decode(m_n) + .decode(m_e) + .end_cons(); + } + +/* +* Check RSA Public Parameters +*/ +bool RSA_PublicKey::check_key(RandomNumberGenerator&, bool) const + { + if(m_n < 35 || m_n.is_even() || m_e < 3 || m_e.is_even()) + return false; + return true; + } + +secure_vector RSA_PrivateKey::private_key_bits() const + { + return DER_Encoder() + .start_cons(SEQUENCE) + .encode(static_cast(0)) + .encode(m_n) + .encode(m_e) + .encode(m_d) + .encode(m_p) + .encode(m_q) + .encode(m_d1) + .encode(m_d2) + .encode(m_c) + .end_cons() + .get_contents(); + } + +RSA_PrivateKey::RSA_PrivateKey(const AlgorithmIdentifier&, + const secure_vector& key_bits) + { + BER_Decoder(key_bits) + .start_cons(SEQUENCE) + .decode_and_check(0, "Unknown PKCS #1 key format version") + .decode(m_n) + .decode(m_e) + .decode(m_d) + .decode(m_p) + .decode(m_q) + .decode(m_d1) + .decode(m_d2) + .decode(m_c) + .end_cons(); + } + +RSA_PrivateKey::RSA_PrivateKey(const BigInt& prime1, + const BigInt& prime2, + const BigInt& exp, + const BigInt& d_exp, + const BigInt& mod) : + m_d{ d_exp }, m_p{ prime1 }, m_q{ prime2 }, m_d1{}, m_d2{}, m_c{ inverse_mod( m_q, m_p ) } + { + m_n = mod.is_nonzero() ? mod : m_p * m_q; + m_e = exp; + + if(m_d == 0) + { + const BigInt phi_n = lcm(m_p - 1, m_q - 1); + m_d = inverse_mod(m_e, phi_n); + } + + m_d1 = m_d % (m_p - 1); + m_d2 = m_d % (m_q - 1); + } + +/* +* Create a RSA private key +*/ +RSA_PrivateKey::RSA_PrivateKey(RandomNumberGenerator& rng, + size_t bits, size_t exp) + { + if(bits < 1024) + throw Invalid_Argument(algo_name() + ": Can't make a key that is only " + + std::to_string(bits) + " bits long"); + if(exp < 3 || exp % 2 == 0) + throw Invalid_Argument(algo_name() + ": Invalid encryption exponent"); + + m_e = exp; + + const size_t p_bits = (bits + 1) / 2; + const size_t q_bits = bits - p_bits; + + do + { + m_p = generate_rsa_prime(rng, rng, p_bits, m_e); + m_q = generate_rsa_prime(rng, rng, q_bits, m_e); + m_n = m_p * m_q; + } while(m_n.bits() != bits); + + // FIXME: lcm calls gcd which is not const time + const BigInt phi_n = lcm(m_p - 1, m_q - 1); + // FIXME: this uses binary ext gcd because phi_n is even + m_d = inverse_mod(m_e, phi_n); + m_d1 = m_d % (m_p - 1); + m_d2 = m_d % (m_q - 1); + m_c = inverse_mod(m_q, m_p); + } + +/* +* Check Private RSA Parameters +*/ +bool RSA_PrivateKey::check_key(RandomNumberGenerator& rng, bool strong) const + { + if(m_n < 35 || m_n.is_even() || m_e < 3 || m_e.is_even()) + return false; + + if(m_d < 2 || m_p < 3 || m_q < 3 || m_p*m_q != m_n) + return false; + + if(m_d1 != m_d % (m_p - 1) || m_d2 != m_d % (m_q - 1) || m_c != inverse_mod(m_q, m_p)) + return false; + + const size_t prob = (strong) ? 128 : 12; + + if(!is_prime(m_p, rng, prob) || !is_prime(m_q, rng, prob)) + return false; + + if(strong) + { + if((m_e * m_d) % lcm(m_p - 1, m_q - 1) != 1) + return false; + + return KeyPair::signature_consistency_check(rng, *this, "EMSA4(SHA-256)"); + } + + return true; + } + +namespace { + +/** +* RSA private (decrypt/sign) operation +*/ +class RSA_Private_Operation + { + protected: + size_t get_max_input_bits() const { return (m_mod_bits - 1); } + + const size_t exp_blinding_bits = 64; + + explicit RSA_Private_Operation(const RSA_PrivateKey& rsa, RandomNumberGenerator& rng) : + m_key(rsa), + m_mod_p(m_key.get_p()), + m_mod_q(m_key.get_q()), + m_monty_p(std::make_shared(m_key.get_p(), m_mod_p)), + m_monty_q(std::make_shared(m_key.get_q(), m_mod_q)), + m_powermod_e_n(m_key.get_e(), m_key.get_n()), + m_blinder(m_key.get_n(), + rng, + [this](const BigInt& k) { return m_powermod_e_n(k); }, + [this](const BigInt& k) { return inverse_mod(k, m_key.get_n()); }), + m_blinding_bits(64), + m_mod_bytes(m_key.get_n().bytes()), + m_mod_bits(m_key.get_n().bits()), + m_max_d1_bits(m_key.get_p().bits() + m_blinding_bits), + m_max_d2_bits(m_key.get_q().bits() + m_blinding_bits) + { + } + + BigInt blinded_private_op(const BigInt& m) const + { + if(m >= m_key.get_n()) + throw Invalid_Argument("RSA private op - input is too large"); + + return m_blinder.unblind(private_op(m_blinder.blind(m))); + } + + BigInt private_op(const BigInt& m) const + { + const size_t powm_window = 4; + + const BigInt d1_mask(m_blinder.rng(), m_blinding_bits); + +#if defined(BOTAN_TARGET_OS_HAS_THREADS) + auto future_j1 = std::async(std::launch::async, [this, &m, &d1_mask, powm_window]() { + const BigInt masked_d1 = m_key.get_d1() + (d1_mask * (m_key.get_p() - 1)); + auto powm_d1_p = monty_precompute(m_monty_p, m, powm_window); + return monty_execute(*powm_d1_p, masked_d1, m_max_d1_bits); + }); +#else + const BigInt masked_d1 = m_key.get_d1() + (d1_mask * (m_key.get_p() - 1)); + auto powm_d1_p = monty_precompute(m_monty_p, m, powm_window); + BigInt j1 = monty_execute(*powm_d1_p, masked_d1, m_max_d1_bits); +#endif + + const BigInt d2_mask(m_blinder.rng(), m_blinding_bits); + const BigInt masked_d2 = m_key.get_d2() + (d2_mask * (m_key.get_q() - 1)); + auto powm_d2_q = monty_precompute(m_monty_q, m, powm_window); + const BigInt j2 = monty_execute(*powm_d2_q, masked_d2, m_max_d2_bits); + + /* + * To recover the final value from the CRT representation (j1,j2) + * we use Garner's algorithm: + * c = q^-1 mod p (this is precomputed) + * h = c*(j1-j2) mod p + * m = j2 + h*q + */ + +#if defined(BOTAN_TARGET_OS_HAS_THREADS) + BigInt j1 = future_j1.get(); +#endif + + /* + To prevent a side channel that allows detecting case where j1 < j2, + add p to j1 before reducing [computing c*(p+j1-j2) mod p] + */ + j1 = m_mod_p.reduce(sub_mul(m_key.get_p() + j1, j2, m_key.get_c())); + return mul_add(j1, m_key.get_q(), j2); + } + + const RSA_PrivateKey& m_key; + + // TODO these could all be computed once and stored in the key object + Modular_Reducer m_mod_p; + Modular_Reducer m_mod_q; + std::shared_ptr m_monty_p; + std::shared_ptr m_monty_q; + + Fixed_Exponent_Power_Mod m_powermod_e_n; + Blinder m_blinder; + const size_t m_blinding_bits; + const size_t m_mod_bytes; + const size_t m_mod_bits; + const size_t m_max_d1_bits; + const size_t m_max_d2_bits; + }; + +class RSA_Signature_Operation final : public PK_Ops::Signature_with_EMSA, + private RSA_Private_Operation + { + public: + + size_t max_input_bits() const override { return get_max_input_bits(); } + + RSA_Signature_Operation(const RSA_PrivateKey& rsa, const std::string& emsa, RandomNumberGenerator& rng) : + PK_Ops::Signature_with_EMSA(emsa), + RSA_Private_Operation(rsa, rng) + { + } + + secure_vector raw_sign(const uint8_t msg[], size_t msg_len, + RandomNumberGenerator&) override + { + const BigInt m(msg, msg_len); + const BigInt x = blinded_private_op(m); + const BigInt c = m_powermod_e_n(x); + BOTAN_ASSERT(m == c, "RSA sign consistency check"); + return BigInt::encode_1363(x, m_mod_bytes); + } + }; + +class RSA_Decryption_Operation final : public PK_Ops::Decryption_with_EME, + private RSA_Private_Operation + { + public: + + RSA_Decryption_Operation(const RSA_PrivateKey& rsa, const std::string& eme, RandomNumberGenerator& rng) : + PK_Ops::Decryption_with_EME(eme), + RSA_Private_Operation(rsa, rng) + { + } + + secure_vector raw_decrypt(const uint8_t msg[], size_t msg_len) override + { + const BigInt m(msg, msg_len); + const BigInt x = blinded_private_op(m); + const BigInt c = m_powermod_e_n(x); + BOTAN_ASSERT(m == c, "RSA decrypt consistency check"); + return BigInt::encode_1363(x, m_mod_bytes); + } + }; + +class RSA_KEM_Decryption_Operation final : public PK_Ops::KEM_Decryption_with_KDF, + private RSA_Private_Operation + { + public: + + RSA_KEM_Decryption_Operation(const RSA_PrivateKey& key, + const std::string& kdf, + RandomNumberGenerator& rng) : + PK_Ops::KEM_Decryption_with_KDF(kdf), + RSA_Private_Operation(key, rng) + {} + + secure_vector + raw_kem_decrypt(const uint8_t encap_key[], size_t len) override + { + const BigInt m(encap_key, len); + const BigInt x = blinded_private_op(m); + const BigInt c = m_powermod_e_n(x); + BOTAN_ASSERT(m == c, "RSA KEM consistency check"); + return BigInt::encode_1363(x, m_mod_bytes); + } + }; + +/** +* RSA public (encrypt/verify) operation +*/ +class RSA_Public_Operation + { + public: + explicit RSA_Public_Operation(const RSA_PublicKey& rsa) : + m_n(rsa.get_n()), + m_e(rsa.get_e()), + m_monty_n(std::make_shared(m_n)) + {} + + size_t get_max_input_bits() const { return (m_n.bits() - 1); } + + protected: + BigInt public_op(const BigInt& m) const + { + if(m >= m_n) + throw Invalid_Argument("RSA public op - input is too large"); + + const size_t powm_window = 1; + + auto powm_m_n = monty_precompute(m_monty_n, m, powm_window, false); + return monty_execute_vartime(*powm_m_n, m_e); + } + + const BigInt& get_n() const { return m_n; } + + const BigInt& m_n; + const BigInt& m_e; + std::shared_ptr m_monty_n; + }; + +class RSA_Encryption_Operation final : public PK_Ops::Encryption_with_EME, + private RSA_Public_Operation + { + public: + + RSA_Encryption_Operation(const RSA_PublicKey& rsa, const std::string& eme) : + PK_Ops::Encryption_with_EME(eme), + RSA_Public_Operation(rsa) + { + } + + size_t max_raw_input_bits() const override { return get_max_input_bits(); } + + secure_vector raw_encrypt(const uint8_t msg[], size_t msg_len, + RandomNumberGenerator&) override + { + BigInt m(msg, msg_len); + return BigInt::encode_1363(public_op(m), m_n.bytes()); + } + }; + +class RSA_Verify_Operation final : public PK_Ops::Verification_with_EMSA, + private RSA_Public_Operation + { + public: + + size_t max_input_bits() const override { return get_max_input_bits(); } + + RSA_Verify_Operation(const RSA_PublicKey& rsa, const std::string& emsa) : + PK_Ops::Verification_with_EMSA(emsa), + RSA_Public_Operation(rsa) + { + } + + bool with_recovery() const override { return true; } + + secure_vector verify_mr(const uint8_t msg[], size_t msg_len) override + { + BigInt m(msg, msg_len); + return BigInt::encode_locked(public_op(m)); + } + }; + +class RSA_KEM_Encryption_Operation final : public PK_Ops::KEM_Encryption_with_KDF, + private RSA_Public_Operation + { + public: + + RSA_KEM_Encryption_Operation(const RSA_PublicKey& key, + const std::string& kdf) : + PK_Ops::KEM_Encryption_with_KDF(kdf), + RSA_Public_Operation(key) {} + + private: + void raw_kem_encrypt(secure_vector& out_encapsulated_key, + secure_vector& raw_shared_key, + Botan::RandomNumberGenerator& rng) override + { + const BigInt r = BigInt::random_integer(rng, 1, get_n()); + const BigInt c = public_op(r); + + out_encapsulated_key = BigInt::encode_locked(c); + raw_shared_key = BigInt::encode_locked(r); + } + }; + +} + +std::unique_ptr +RSA_PublicKey::create_encryption_op(RandomNumberGenerator& /*rng*/, + const std::string& params, + const std::string& provider) const + { +#if defined(BOTAN_HAS_OPENSSL) + if(provider == "openssl" || provider.empty()) + { + try + { + return make_openssl_rsa_enc_op(*this, params); + } + catch(Exception& e) + { + /* + * If OpenSSL for some reason could not handle this (eg due to OAEP params), + * throw if openssl was specifically requested but otherwise just fall back + * to the normal version. + */ + if(provider == "openssl") + throw Lookup_Error("OpenSSL RSA provider rejected key:" + std::string(e.what())); + } + } +#endif + + if(provider == "base" || provider.empty()) + return std::unique_ptr(new RSA_Encryption_Operation(*this, params)); + throw Provider_Not_Found(algo_name(), provider); + } + +std::unique_ptr +RSA_PublicKey::create_kem_encryption_op(RandomNumberGenerator& /*rng*/, + const std::string& params, + const std::string& provider) const + { + if(provider == "base" || provider.empty()) + return std::unique_ptr(new RSA_KEM_Encryption_Operation(*this, params)); + throw Provider_Not_Found(algo_name(), provider); + } + +std::unique_ptr +RSA_PublicKey::create_verification_op(const std::string& params, + const std::string& provider) const + { +#if defined(BOTAN_HAS_OPENSSL) + if(provider == "openssl" || provider.empty()) + { + std::unique_ptr res = make_openssl_rsa_ver_op(*this, params); + if(res) + return res; + } +#endif + + if(provider == "base" || provider.empty()) + return std::unique_ptr(new RSA_Verify_Operation(*this, params)); + + throw Provider_Not_Found(algo_name(), provider); + } + +std::unique_ptr +RSA_PrivateKey::create_decryption_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) const + { +#if defined(BOTAN_HAS_OPENSSL) + if(provider == "openssl" || provider.empty()) + { + try + { + return make_openssl_rsa_dec_op(*this, params); + } + catch(Exception& e) + { + if(provider == "openssl") + throw Lookup_Error("OpenSSL RSA provider rejected key:" + std::string(e.what())); + } + } +#endif + + if(provider == "base" || provider.empty()) + return std::unique_ptr(new RSA_Decryption_Operation(*this, params, rng)); + + throw Provider_Not_Found(algo_name(), provider); + } + +std::unique_ptr +RSA_PrivateKey::create_kem_decryption_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) const + { + if(provider == "base" || provider.empty()) + return std::unique_ptr(new RSA_KEM_Decryption_Operation(*this, params, rng)); + + throw Provider_Not_Found(algo_name(), provider); + } + +std::unique_ptr +RSA_PrivateKey::create_signature_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) const + { +#if defined(BOTAN_HAS_OPENSSL) + if(provider == "openssl" || provider.empty()) + { + std::unique_ptr res = make_openssl_rsa_sig_op(*this, params); + if(res) + return res; + } +#endif + + if(provider == "base" || provider.empty()) + return std::unique_ptr(new RSA_Signature_Operation(*this, params, rng)); + + throw Provider_Not_Found(algo_name(), provider); + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/rsa/rsa.h b/src/libs/3rdparty/botan/src/lib/pubkey/rsa/rsa.h new file mode 100644 index 0000000000..ad4fceab99 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pubkey/rsa/rsa.h @@ -0,0 +1,164 @@ +/* +* RSA +* (C) 1999-2008,2016 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_RSA_H_ +#define BOTAN_RSA_H_ + +#include +#include + +namespace Botan { + +/** +* RSA Public Key +*/ +class BOTAN_PUBLIC_API(2,0) RSA_PublicKey : public virtual Public_Key + { + public: + /** + * Load a public key. + * @param alg_id the X.509 algorithm identifier + * @param key_bits DER encoded public key bits + */ + RSA_PublicKey(const AlgorithmIdentifier& alg_id, + const std::vector& key_bits); + + /** + * Create a public key. + * @arg n the modulus + * @arg e the exponent + */ + RSA_PublicKey(const BigInt& n, const BigInt& e) : + m_n(n), m_e(e) {} + + std::string algo_name() const override { return "RSA"; } + + bool check_key(RandomNumberGenerator& rng, bool) const override; + + AlgorithmIdentifier algorithm_identifier() const override; + + std::vector public_key_bits() const override; + + /** + * @return public modulus + */ + const BigInt& get_n() const { return m_n; } + + /** + * @return public exponent + */ + const BigInt& get_e() const { return m_e; } + + size_t key_length() const override; + size_t estimated_strength() const override; + + std::unique_ptr + create_encryption_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) const override; + + std::unique_ptr + create_kem_encryption_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) const override; + + std::unique_ptr + create_verification_op(const std::string& params, + const std::string& provider) const override; + + protected: + RSA_PublicKey() = default; + + BigInt m_n, m_e; + }; + +/** +* RSA Private Key +*/ +class BOTAN_PUBLIC_API(2,0) RSA_PrivateKey final : public Private_Key, public RSA_PublicKey + { + public: + /** + * Load a private key. + * @param alg_id the X.509 algorithm identifier + * @param key_bits PKCS#1 RSAPrivateKey bits + */ + RSA_PrivateKey(const AlgorithmIdentifier& alg_id, + const secure_vector& key_bits); + + /** + * Construct a private key from the specified parameters. + * @param p the first prime + * @param q the second prime + * @param e the exponent + * @param d if specified, this has to be d with + * exp * d = 1 mod (p - 1, q - 1). Leave it as 0 if you wish to + * the constructor to calculate it. + * @param n if specified, this must be n = p * q. Leave it as 0 + * if you wish to the constructor to calculate it. + */ + RSA_PrivateKey(const BigInt& p, const BigInt& q, + const BigInt& e, const BigInt& d = 0, + const BigInt& n = 0); + + /** + * Create a new private key with the specified bit length + * @param rng the random number generator to use + * @param bits the desired bit length of the private key + * @param exp the public exponent to be used + */ + RSA_PrivateKey(RandomNumberGenerator& rng, + size_t bits, size_t exp = 65537); + + bool check_key(RandomNumberGenerator& rng, bool) const override; + + /** + * Get the first prime p. + * @return prime p + */ + const BigInt& get_p() const { return m_p; } + + /** + * Get the second prime q. + * @return prime q + */ + const BigInt& get_q() const { return m_q; } + + /** + * Get d with exp * d = 1 mod (p - 1, q - 1). + * @return d + */ + const BigInt& get_d() const { return m_d; } + + const BigInt& get_c() const { return m_c; } + const BigInt& get_d1() const { return m_d1; } + const BigInt& get_d2() const { return m_d2; } + + secure_vector private_key_bits() const override; + + std::unique_ptr + create_decryption_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) const override; + + std::unique_ptr + create_kem_decryption_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) const override; + + std::unique_ptr + create_signature_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) const override; + + private: + BigInt m_d, m_p, m_q, m_d1, m_d2, m_c; + }; + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/workfactor.cpp b/src/libs/3rdparty/botan/src/lib/pubkey/workfactor.cpp new file mode 100644 index 0000000000..71604c06bb --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pubkey/workfactor.cpp @@ -0,0 +1,64 @@ +/* +* Public Key Work Factor Functions +* (C) 1999-2007,2012 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include + +namespace Botan { + +size_t ecp_work_factor(size_t bits) + { + return bits / 2; + } + +namespace { + +size_t nfs_workfactor(size_t bits, double k) + { + // approximates natural logarithm of integer of given bitsize + const double log2_e = std::log2(std::exp(1)); + const double log_p = bits / log2_e; + + const double log_log_p = std::log(log_p); + + // RFC 3766: k * e^((1.92 + o(1)) * cubrt(ln(n) * (ln(ln(n)))^2)) + const double est = 1.92 * std::pow(log_p * log_log_p * log_log_p, 1.0/3.0); + + // return log2 of the workfactor + return static_cast(std::log2(k) + log2_e * est); + } + +} + +size_t if_work_factor(size_t bits) + { + // RFC 3766 estimates k at .02 and o(1) to be effectively zero for sizes of interest + + return nfs_workfactor(bits, .02); + } + +size_t dl_work_factor(size_t bits) + { + // Lacking better estimates... + return if_work_factor(bits); + } + +size_t dl_exponent_size(size_t bits) + { + /* + This uses a slightly tweaked version of the standard work factor + function above. It assumes k is 1 (thus overestimating the strength + of the prime group by 5-6 bits), and always returns at least 128 bits + (this only matters for very small primes). + */ + const size_t MIN_WORKFACTOR = 64; + + return 2 * std::max(MIN_WORKFACTOR, nfs_workfactor(bits, 1)); + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/workfactor.h b/src/libs/3rdparty/botan/src/lib/pubkey/workfactor.h new file mode 100644 index 0000000000..0eea246d7e --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pubkey/workfactor.h @@ -0,0 +1,50 @@ +/* +* Public Key Work Factor Functions +* (C) 1999-2007 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_WORKFACTOR_H_ +#define BOTAN_WORKFACTOR_H_ + +#include + +namespace Botan { + +/** +* Estimate work factor for discrete logarithm +* @param prime_group_size size of the group in bits +* @return estimated security level for this group +*/ +BOTAN_PUBLIC_API(2,0) size_t dl_work_factor(size_t prime_group_size); + +/** +* Return the appropriate exponent size to use for a particular prime +* group. This is twice the size of the estimated cost of breaking the +* key using an index calculus attack; the assumption is that if an +* arbitrary discrete log on a group of size bits would take about 2^n +* effort, and thus using an exponent of size 2^(2*n) implies that all +* available attacks are about as easy (as e.g Pollard's kangaroo +* algorithm can compute the DL in sqrt(x) operations) while minimizing +* the exponent size for performance reasons. +*/ +BOTAN_PUBLIC_API(2,0) size_t dl_exponent_size(size_t prime_group_size); + +/** +* Estimate work factor for integer factorization +* @param n_bits size of modulus in bits +* @return estimated security level for this modulus +*/ +BOTAN_PUBLIC_API(2,0) size_t if_work_factor(size_t n_bits); + +/** +* Estimate work factor for EC discrete logarithm +* @param prime_group_size size of the group in bits +* @return estimated security level for this group +*/ +BOTAN_PUBLIC_API(2,0) size_t ecp_work_factor(size_t prime_group_size); + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/x509_key.cpp b/src/libs/3rdparty/botan/src/lib/pubkey/x509_key.cpp new file mode 100644 index 0000000000..6e49d953a4 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pubkey/x509_key.cpp @@ -0,0 +1,106 @@ +/* +* X.509 Public Key +* (C) 1999-2010 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include +#include +#include + +namespace Botan { + +namespace X509 { + +std::vector BER_encode(const Public_Key& key) + { + // keeping it around for compat + return key.subject_public_key(); + } + +/* +* PEM encode a X.509 public key +*/ +std::string PEM_encode(const Public_Key& key) + { + return PEM_Code::encode(key.subject_public_key(), + "PUBLIC KEY"); + } + +/* +* Extract a public key and return it +*/ +Public_Key* load_key(DataSource& source) + { + try { + AlgorithmIdentifier alg_id; + std::vector key_bits; + + if(ASN1::maybe_BER(source) && !PEM_Code::matches(source)) + { + BER_Decoder(source) + .start_cons(SEQUENCE) + .decode(alg_id) + .decode(key_bits, BIT_STRING) + .end_cons(); + } + else + { + DataSource_Memory ber( + PEM_Code::decode_check_label(source, "PUBLIC KEY") + ); + + BER_Decoder(ber) + .start_cons(SEQUENCE) + .decode(alg_id) + .decode(key_bits, BIT_STRING) + .end_cons(); + } + + if(key_bits.empty()) + throw Decoding_Error("X.509 public key decoding failed"); + + 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())); + } + } + +#if defined(BOTAN_TARGET_OS_HAS_FILESYSTEM) +/* +* Extract a public key and return it +*/ +Public_Key* load_key(const std::string& fsname) + { + DataSource_Stream source(fsname, true); + return X509::load_key(source); + } +#endif + +/* +* Extract a public key and return it +*/ +Public_Key* load_key(const std::vector& mem) + { + DataSource_Memory source(mem); + return X509::load_key(source); + } + +/* +* Make a copy of this public key +*/ +Public_Key* copy_key(const Public_Key& key) + { + DataSource_Memory source(PEM_encode(key)); + return X509::load_key(source); + } + +} + +} diff --git a/src/libs/3rdparty/botan/src/lib/pubkey/x509_key.h b/src/libs/3rdparty/botan/src/lib/pubkey/x509_key.h new file mode 100644 index 0000000000..58d537bbe7 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/pubkey/x509_key.h @@ -0,0 +1,80 @@ +/* +* X.509 Public Key +* (C) 1999-2010 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_X509_PUBLIC_KEY_H_ +#define BOTAN_X509_PUBLIC_KEY_H_ + +#include +#include +#include +#include + +namespace Botan { + +class RandomNumberGenerator; +class DataSource; + +/** +* The two types of X509 encoding supported by Botan. +* This enum is not used anymore, and will be removed in a future major release. +*/ +enum X509_Encoding { RAW_BER, PEM }; + +/** +* This namespace contains functions for handling X.509 public keys +*/ +namespace X509 { + +/** +* BER encode a key +* @param key the public key to encode +* @return BER encoding of this key +*/ +BOTAN_PUBLIC_API(2,0) std::vector BER_encode(const Public_Key& key); + +/** +* PEM encode a public key into a string. +* @param key the key to encode +* @return PEM encoded key +*/ +BOTAN_PUBLIC_API(2,0) std::string PEM_encode(const Public_Key& key); + +/** +* Create a public key from a data source. +* @param source the source providing the DER or PEM encoded key +* @return new public key object +*/ +BOTAN_PUBLIC_API(2,0) Public_Key* load_key(DataSource& source); + +#if defined(BOTAN_TARGET_OS_HAS_FILESYSTEM) +/** +* Create a public key from a file +* @param filename pathname to the file to load +* @return new public key object +*/ +BOTAN_PUBLIC_API(2,0) Public_Key* load_key(const std::string& filename); +#endif + +/** +* Create a public key from a memory region. +* @param enc the memory region containing the DER or PEM encoded key +* @return new public key object +*/ +BOTAN_PUBLIC_API(2,0) Public_Key* load_key(const std::vector& enc); + +/** +* Copy a key. +* @param key the public key to copy +* @return new public key object +*/ +BOTAN_PUBLIC_API(2,0) Public_Key* copy_key(const Public_Key& key); + +} + +} + +#endif 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 new file mode 100644 index 0000000000..ec439e7cfb --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/rng/auto_rng/auto_rng.cpp @@ -0,0 +1,112 @@ +/* +* (C) 2016 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include + +#if defined(BOTAN_HAS_SYSTEM_RNG) + #include +#endif + +#if !defined(BOTAN_AUTO_RNG_HMAC) +#error "No hash function defined for AutoSeeded_RNG in build.h (try enabling sha2_32)" +#endif + +namespace Botan { + +AutoSeeded_RNG::~AutoSeeded_RNG() + { + // for unique_ptr + } + +AutoSeeded_RNG::AutoSeeded_RNG(RandomNumberGenerator& underlying_rng, + size_t reseed_interval) + { + m_rng.reset(new HMAC_DRBG(MessageAuthenticationCode::create_or_throw(BOTAN_AUTO_RNG_HMAC), + underlying_rng, + reseed_interval)); + force_reseed(); + } + +AutoSeeded_RNG::AutoSeeded_RNG(Entropy_Sources& entropy_sources, + size_t reseed_interval) + { + m_rng.reset(new HMAC_DRBG(MessageAuthenticationCode::create_or_throw(BOTAN_AUTO_RNG_HMAC), + entropy_sources, + reseed_interval)); + force_reseed(); + } + +AutoSeeded_RNG::AutoSeeded_RNG(RandomNumberGenerator& underlying_rng, + Entropy_Sources& entropy_sources, + size_t reseed_interval) + { + m_rng.reset(new HMAC_DRBG( + MessageAuthenticationCode::create_or_throw(BOTAN_AUTO_RNG_HMAC), + underlying_rng, entropy_sources, reseed_interval)); + force_reseed(); + } + +AutoSeeded_RNG::AutoSeeded_RNG(size_t reseed_interval) : +#if defined(BOTAN_HAS_SYSTEM_RNG) + AutoSeeded_RNG(system_rng(), reseed_interval) +#else + AutoSeeded_RNG(Entropy_Sources::global_sources(), reseed_interval) +#endif + { + } + +void AutoSeeded_RNG::force_reseed() + { + m_rng->force_reseed(); + m_rng->next_byte(); + + if(!m_rng->is_seeded()) + { + throw Exception("AutoSeeded_RNG reseeding failed"); + } + } + +bool AutoSeeded_RNG::is_seeded() const + { + return m_rng->is_seeded(); + } + +void AutoSeeded_RNG::clear() + { + m_rng->clear(); + } + +std::string AutoSeeded_RNG::name() const + { + return m_rng->name(); + } + +void AutoSeeded_RNG::add_entropy(const uint8_t in[], size_t len) + { + m_rng->add_entropy(in, len); + } + +size_t AutoSeeded_RNG::reseed(Entropy_Sources& srcs, + size_t poll_bits, + std::chrono::milliseconds poll_timeout) + { + return m_rng->reseed(srcs, poll_bits, poll_timeout); + } + +void AutoSeeded_RNG::randomize(uint8_t output[], size_t output_len) + { + randomize_with_ts_input(output, output_len); + } + +void AutoSeeded_RNG::randomize_with_input(uint8_t output[], size_t output_len, + const uint8_t ad[], size_t ad_len) + { + m_rng->randomize_with_input(output, output_len, ad, ad_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 new file mode 100644 index 0000000000..866c56e12f --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/rng/auto_rng/auto_rng.h @@ -0,0 +1,96 @@ +/* +* Auto Seeded RNG +* (C) 2008,2016 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_AUTO_SEEDING_RNG_H_ +#define BOTAN_AUTO_SEEDING_RNG_H_ + +#include + +namespace Botan { + +class Stateful_RNG; + +/** +* A userspace PRNG +*/ +class BOTAN_PUBLIC_API(2,0) AutoSeeded_RNG final : public RandomNumberGenerator + { + public: + void randomize(uint8_t out[], size_t len) override; + + void randomize_with_input(uint8_t output[], size_t output_len, + const uint8_t input[], size_t input_len) override; + + bool is_seeded() const override; + + /** + * Mark state as requiring a reseed on next use + */ + void force_reseed(); + + size_t reseed(Entropy_Sources& srcs, + size_t poll_bits = BOTAN_RNG_RESEED_POLL_BITS, + std::chrono::milliseconds poll_timeout = BOTAN_RNG_RESEED_DEFAULT_TIMEOUT) override; + + void add_entropy(const uint8_t in[], size_t len) override; + + std::string name() const override; + + void clear() override; + + /** + * Uses the system RNG (if available) or else a default group of + * entropy sources (all other systems) to gather seed material. + * + * @param reseed_interval specifies a limit of how many times + * the RNG will be called before automatic reseeding is performed + */ + AutoSeeded_RNG(size_t reseed_interval = BOTAN_RNG_DEFAULT_RESEED_INTERVAL); + + /** + * Uses the BOTAN_AUTO_RNG_DRBG RNG to gather seed material. + * + * @param underlying_rng is a reference to some RNG which will be used + * to perform the periodic reseeding + * @param reseed_interval specifies a limit of how many times + * the RNG will be called before automatic reseeding is performed + */ + AutoSeeded_RNG(RandomNumberGenerator& underlying_rng, + size_t reseed_interval = BOTAN_RNG_DEFAULT_RESEED_INTERVAL); + + /** + * Uses the BOTAN_AUTO_RNG_DRBG RNG to gather seed material. + * + * @param entropy_sources will be polled to perform reseeding periodically + * @param reseed_interval specifies a limit of how many times + * the RNG will be called before automatic reseeding is performed + */ + AutoSeeded_RNG(Entropy_Sources& entropy_sources, + size_t reseed_interval = BOTAN_RNG_DEFAULT_RESEED_INTERVAL); + + /** + * Uses the BOTAN_AUTO_RNG_DRBG RNG to gather seed material. + * + * @param underlying_rng is a reference to some RNG which will be used + * to perform the periodic reseeding + * @param entropy_sources will be polled to perform reseeding periodically + * @param reseed_interval specifies a limit of how many times + * the RNG will be called before automatic reseeding is performed + */ + AutoSeeded_RNG(RandomNumberGenerator& underlying_rng, + Entropy_Sources& entropy_sources, + size_t reseed_interval = BOTAN_RNG_DEFAULT_RESEED_INTERVAL); + + ~AutoSeeded_RNG(); + + private: + std::unique_ptr m_rng; + }; + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/rng/auto_rng/info.txt b/src/libs/3rdparty/botan/src/lib/rng/auto_rng/info.txt new file mode 100644 index 0000000000..f1adcc8001 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/rng/auto_rng/info.txt @@ -0,0 +1,8 @@ + +AUTO_SEEDING_RNG -> 20160821 +AUTO_RNG -> 20161126 + + + +hmac_drbg + diff --git a/src/libs/3rdparty/botan/src/lib/rng/hmac_drbg/hmac_drbg.cpp b/src/libs/3rdparty/botan/src/lib/rng/hmac_drbg/hmac_drbg.cpp new file mode 100644 index 0000000000..a01b761d99 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/rng/hmac_drbg/hmac_drbg.cpp @@ -0,0 +1,184 @@ +/* +* HMAC_DRBG +* (C) 2014,2015,2016 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include + +namespace Botan { + +HMAC_DRBG::HMAC_DRBG(std::unique_ptr prf, + RandomNumberGenerator& underlying_rng, + size_t reseed_interval, + size_t max_number_of_bytes_per_request) : + Stateful_RNG(underlying_rng, reseed_interval), + m_mac(std::move(prf)), + m_max_number_of_bytes_per_request(max_number_of_bytes_per_request) + { + BOTAN_ASSERT_NONNULL(m_mac); + + if(m_max_number_of_bytes_per_request == 0 || m_max_number_of_bytes_per_request > 64 * 1024) + { + throw Invalid_Argument("Invalid value for max_number_of_bytes_per_request"); + } + + clear(); + } + +HMAC_DRBG::HMAC_DRBG(std::unique_ptr prf, + RandomNumberGenerator& underlying_rng, + Entropy_Sources& entropy_sources, + size_t reseed_interval, + size_t max_number_of_bytes_per_request ) : + Stateful_RNG(underlying_rng, entropy_sources, reseed_interval), + m_mac(std::move(prf)), + m_max_number_of_bytes_per_request(max_number_of_bytes_per_request) + { + BOTAN_ASSERT_NONNULL(m_mac); + + if(m_max_number_of_bytes_per_request == 0 || m_max_number_of_bytes_per_request > 64 * 1024) + { + throw Invalid_Argument("Invalid value for max_number_of_bytes_per_request"); + } + + clear(); + } + +HMAC_DRBG::HMAC_DRBG(std::unique_ptr prf, + Entropy_Sources& entropy_sources, + size_t reseed_interval, + size_t max_number_of_bytes_per_request) : + Stateful_RNG(entropy_sources, reseed_interval), + m_mac(std::move(prf)), + m_max_number_of_bytes_per_request(max_number_of_bytes_per_request) + { + BOTAN_ASSERT_NONNULL(m_mac); + + if(m_max_number_of_bytes_per_request == 0 || m_max_number_of_bytes_per_request > 64 * 1024) + { + throw Invalid_Argument("Invalid value for max_number_of_bytes_per_request"); + } + + clear(); + } + +HMAC_DRBG::HMAC_DRBG(std::unique_ptr prf) : + Stateful_RNG(), + m_mac(std::move(prf)), + m_max_number_of_bytes_per_request(64*1024) + { + BOTAN_ASSERT_NONNULL(m_mac); + clear(); + } + +void HMAC_DRBG::clear() + { + Stateful_RNG::clear(); + + m_V.resize(m_mac->output_length()); + for(size_t i = 0; i != m_V.size(); ++i) + m_V[i] = 0x01; + m_mac->set_key(std::vector(m_mac->output_length(), 0x00)); + } + +std::string HMAC_DRBG::name() const + { + return "HMAC_DRBG(" + m_mac->name() + ")"; + } + +void HMAC_DRBG::randomize(uint8_t output[], size_t output_len) + { + randomize_with_input(output, output_len, nullptr, 0); + } + +/* +* HMAC_DRBG generation +* See NIST SP800-90A section 10.1.2.5 +*/ +void HMAC_DRBG::randomize_with_input(uint8_t output[], size_t output_len, + const uint8_t input[], size_t input_len) + { + while(output_len > 0) + { + size_t this_req = std::min(m_max_number_of_bytes_per_request, output_len); + output_len -= this_req; + + reseed_check(); + + if(input_len > 0) + { + update(input, input_len); + } + + while(this_req) + { + const size_t to_copy = std::min(this_req, m_V.size()); + m_mac->update(m_V.data(), m_V.size()); + m_mac->final(m_V.data()); + copy_mem(output, m_V.data(), to_copy); + + output += to_copy; + this_req -= to_copy; + } + + update(input, input_len); + } + + } + +/* +* Reset V and the mac key with new values +* See NIST SP800-90A section 10.1.2.2 +*/ +void HMAC_DRBG::update(const uint8_t input[], size_t input_len) + { + m_mac->update(m_V); + m_mac->update(0x00); + m_mac->update(input, input_len); + m_mac->set_key(m_mac->final()); + + m_mac->update(m_V.data(), m_V.size()); + m_mac->final(m_V.data()); + + if(input_len > 0) + { + m_mac->update(m_V); + m_mac->update(0x01); + m_mac->update(input, input_len); + m_mac->set_key(m_mac->final()); + + m_mac->update(m_V.data(), m_V.size()); + m_mac->final(m_V.data()); + } + } + +void HMAC_DRBG::add_entropy(const uint8_t input[], size_t input_len) + { + update(input, input_len); + + if(8*input_len >= security_level()) + { + reset_reseed_counter(); + } + } + +size_t HMAC_DRBG::security_level() const + { + // security strength of the hash function + // for pre-image resistance (see NIST SP 800-57) + // SHA-160: 128 bits, SHA-224, SHA-512/224: 192 bits, + // SHA-256, SHA-512/256, SHA-384, SHA-512: >= 256 bits + // NIST SP 800-90A only supports up to 256 bits though + if(m_mac->output_length() < 32) + { + return (m_mac->output_length() - 4) * 8; + } + else + { + return 32 * 8; + } + } +} diff --git a/src/libs/3rdparty/botan/src/lib/rng/hmac_drbg/hmac_drbg.h b/src/libs/3rdparty/botan/src/lib/rng/hmac_drbg/hmac_drbg.h new file mode 100644 index 0000000000..edf38b6842 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/rng/hmac_drbg/hmac_drbg.h @@ -0,0 +1,159 @@ +/* +* HMAC_DRBG (SP800-90A) +* (C) 2014,2015,2016 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_HMAC_DRBG_H_ +#define BOTAN_HMAC_DRBG_H_ + +#include +#include + +namespace Botan { + +class Entropy_Sources; + +/** +* HMAC_DRBG from NIST SP800-90A +*/ +class BOTAN_PUBLIC_API(2,0) HMAC_DRBG final : public Stateful_RNG + { + public: + /** + * Initialize an HMAC_DRBG instance with the given MAC as PRF (normally HMAC) + * + * Automatic reseeding is disabled completely, as it has no access to + * any source for seed material. + * + * If a fork is detected, the RNG will be unable to reseed itself + * in response. In this case, an exception will be thrown rather + * than generating duplicated output. + */ + explicit HMAC_DRBG(std::unique_ptr prf); + + /** + * Initialize an HMAC_DRBG instance with the given MAC as PRF (normally HMAC) + * + * Automatic reseeding from @p underlying_rng will take place after + * @p reseed_interval many requests or after a fork was detected. + * + * @param prf MAC to use as a PRF + * @param underlying_rng is a reference to some RNG which will be used + * to perform the periodic reseeding + * @param reseed_interval specifies a limit of how many times + * the RNG will be called before automatic reseeding is performed + * @param max_number_of_bytes_per_request requests that are in size higher + * than max_number_of_bytes_per_request are treated as if multiple single + * requests of max_number_of_bytes_per_request size had been made. + * In theory SP 800-90A requires that we reject any request for a DRBG + * output longer than max_number_of_bytes_per_request. To avoid inconveniencing + * the caller who wants an output larger than max_number_of_bytes_per_request, + * instead treat these requests as if multiple requests of + * max_number_of_bytes_per_request size had been made. NIST requires for + * HMAC_DRBG that every implementation set a value no more than 2**19 bits + * (or 64 KiB). Together with @p reseed_interval = 1 you can enforce that for + * example every 512 bit automatic reseeding occurs. + */ + HMAC_DRBG(std::unique_ptr prf, + RandomNumberGenerator& underlying_rng, + size_t reseed_interval = BOTAN_RNG_DEFAULT_RESEED_INTERVAL, + size_t max_number_of_bytes_per_request = 64 * 1024); + + /** + * Initialize an HMAC_DRBG instance with the given MAC as PRF (normally HMAC) + * + * Automatic reseeding from @p entropy_sources will take place after + * @p reseed_interval many requests or after a fork was detected. + * + * @param prf MAC to use as a PRF + * @param entropy_sources will be polled to perform reseeding periodically + * @param reseed_interval specifies a limit of how many times + * the RNG will be called before automatic reseeding is performed. + * @param max_number_of_bytes_per_request requests that are in size higher + * than max_number_of_bytes_per_request are treated as if multiple single + * requests of max_number_of_bytes_per_request size had been made. + * In theory SP 800-90A requires that we reject any request for a DRBG + * output longer than max_number_of_bytes_per_request. To avoid inconveniencing + * the caller who wants an output larger than max_number_of_bytes_per_request, + * instead treat these requests as if multiple requests of + * max_number_of_bytes_per_request size had been made. NIST requires for + * HMAC_DRBG that every implementation set a value no more than 2**19 bits + * (or 64 KiB). Together with @p reseed_interval = 1 you can enforce that for + * example every 512 bit automatic reseeding occurs. + */ + HMAC_DRBG(std::unique_ptr prf, + Entropy_Sources& entropy_sources, + size_t reseed_interval = BOTAN_RNG_DEFAULT_RESEED_INTERVAL, + size_t max_number_of_bytes_per_request = 64 * 1024); + + /** + * Initialize an HMAC_DRBG instance with the given MAC as PRF (normally HMAC) + * + * Automatic reseeding from @p underlying_rng and @p entropy_sources + * will take place after @p reseed_interval many requests or after + * a fork was detected. + * + * @param prf MAC to use as a PRF + * @param underlying_rng is a reference to some RNG which will be used + * to perform the periodic reseeding + * @param entropy_sources will be polled to perform reseeding periodically + * @param reseed_interval specifies a limit of how many times + * the RNG will be called before automatic reseeding is performed. + * @param max_number_of_bytes_per_request requests that are in size higher + * than max_number_of_bytes_per_request are treated as if multiple single + * requests of max_number_of_bytes_per_request size had been made. + * In theory SP 800-90A requires that we reject any request for a DRBG + * output longer than max_number_of_bytes_per_request. To avoid inconveniencing + * the caller who wants an output larger than max_number_of_bytes_per_request, + * instead treat these requests as if multiple requests of + * max_number_of_bytes_per_request size had been made. NIST requires for + * HMAC_DRBG that every implementation set a value no more than 2**19 bits + * (or 64 KiB). Together with @p reseed_interval = 1 you can enforce that for + * example every 512 bit automatic reseeding occurs. + */ + HMAC_DRBG(std::unique_ptr prf, + RandomNumberGenerator& underlying_rng, + Entropy_Sources& entropy_sources, + size_t reseed_interval = BOTAN_RNG_DEFAULT_RESEED_INTERVAL, + size_t max_number_of_bytes_per_request = 64 * 1024); + + /** + * Constructor taking a string for the hash + */ + explicit HMAC_DRBG(const std::string& hmac_hash) : + Stateful_RNG(), + m_mac(MessageAuthenticationCode::create_or_throw("HMAC(" + hmac_hash + ")")), + m_max_number_of_bytes_per_request(64 * 1024) + { + clear(); + } + + std::string name() const override; + + void clear() override; + + void randomize(uint8_t output[], size_t output_len) override; + + void randomize_with_input(uint8_t output[], size_t output_len, + const uint8_t input[], size_t input_len) override; + + void add_entropy(const uint8_t input[], size_t input_len) override; + + size_t security_level() const override; + + size_t max_number_of_bytes_per_request() const override + { return m_max_number_of_bytes_per_request; } + + private: + void update(const uint8_t input[], size_t input_len); + + std::unique_ptr m_mac; + secure_vector m_V; + const size_t m_max_number_of_bytes_per_request; + }; + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/rng/hmac_drbg/info.txt b/src/libs/3rdparty/botan/src/lib/rng/hmac_drbg/info.txt new file mode 100644 index 0000000000..a8922bdf0e --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/rng/hmac_drbg/info.txt @@ -0,0 +1,8 @@ + +HMAC_DRBG -> 20140319 + + + +hmac +stateful_rng + diff --git a/src/libs/3rdparty/botan/src/lib/rng/info.txt b/src/libs/3rdparty/botan/src/lib/rng/info.txt new file mode 100644 index 0000000000..4c88ba3826 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/rng/info.txt @@ -0,0 +1,3 @@ + +entropy + diff --git a/src/libs/3rdparty/botan/src/lib/rng/rdrand_rng/info.txt b/src/libs/3rdparty/botan/src/lib/rng/rdrand_rng/info.txt new file mode 100644 index 0000000000..0d0fc42a42 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/rng/rdrand_rng/info.txt @@ -0,0 +1,13 @@ + +RDRAND_RNG -> 20160619 + + +need_isa rdrand + + +gcc +clang +icc +msvc + + 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 new file mode 100644 index 0000000000..c365a5f760 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/rng/rdrand_rng/rdrand_rng.cpp @@ -0,0 +1,83 @@ +/* +* RDRAND RNG +* (C) 2016 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include + +#if !defined(BOTAN_USE_GCC_INLINE_ASM) + #include +#endif + +namespace Botan { + +RDRAND_RNG::RDRAND_RNG() + { + if(!CPUID::has_rdrand()) + throw Exception("Current CPU does not support RDRAND instruction"); + } + +//static +uint32_t RDRAND_RNG::rdrand() + { + for(;;) + { + bool ok = false; + uint32_t r = rdrand_status(ok); + if(ok) + return r; + } + } + +//static +BOTAN_FUNC_ISA("rdrnd") +uint32_t RDRAND_RNG::rdrand_status(bool& ok) + { + ok = false; + uint32_t r = 0; + + for(size_t i = 0; i != BOTAN_ENTROPY_RDRAND_RETRIES; ++i) + { +#if defined(BOTAN_USE_GCC_INLINE_ASM) + int cf = 0; + + // Encoding of rdrand %eax + asm(".byte 0x0F, 0xC7, 0xF0; adcl $0,%1" : + "=a" (r), "=r" (cf) : "0" (r), "1" (cf) : "cc"); +#else + int cf = _rdrand32_step(&r); +#endif + if(1 == cf) + { + ok = true; + break; + } + } + + return r; + } + +void RDRAND_RNG::randomize(uint8_t out[], size_t out_len) + { + while(out_len >= 4) + { + uint32_t r = RDRAND_RNG::rdrand(); + + store_le(r, out); + out += 4; + out_len -= 4; + } + + if(out_len) // between 1 and 3 trailing bytes + { + uint32_t r = RDRAND_RNG::rdrand(); + for(size_t i = 0; i != out_len; ++i) + out[i] = get_byte(i, r); + } + } + +} 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 new file mode 100644 index 0000000000..377de419f7 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/rng/rdrand_rng/rdrand_rng.h @@ -0,0 +1,61 @@ +/* +* RDRAND RNG +* (C) 2016 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_RNG_RDRAND_H_ +#define BOTAN_RNG_RDRAND_H_ + +#include + +namespace Botan { + +class BOTAN_PUBLIC_API(2,0) RDRAND_RNG final : public Hardware_RNG + { + public: + /** + * On correctly working hardware, RDRAND is always supposed to + * succeed within a set number of retries. If after that many + * retries RDRAND has still not suceeded, sets ok = false and + * returns 0. + */ + static uint32_t rdrand_status(bool& ok); + + /* + * Calls RDRAND until it succeeds, this could hypothetically + * loop forever on broken hardware. + */ + static uint32_t rdrand(); + + /** + * Constructor will throw if CPU does not have RDRAND bit set + */ + RDRAND_RNG(); + + /** + * Uses RDRAND to produce output + */ + void randomize(uint8_t out[], size_t out_len) override; + + /* + * No way to provide entropy to RDRAND generator, so add_entropy is ignored + */ + void add_entropy(const uint8_t[], size_t) override + { /* no op */ } + + /* + * No way to reseed RDRAND generator, so reseed is ignored + */ + size_t reseed(Entropy_Sources&, size_t, std::chrono::milliseconds) override + { return 0; /* no op */ } + + std::string name() const override { return "RDRAND"; } + + bool is_seeded() const override { return true; } + }; + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/rng/rng.cpp b/src/libs/3rdparty/botan/src/lib/rng/rng.cpp new file mode 100644 index 0000000000..2cf3b7b81e --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/rng/rng.cpp @@ -0,0 +1,74 @@ +/* +* (C) 2016 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include + +#if defined(BOTAN_HAS_AUTO_SEEDING_RNG) + #include +#endif + +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); + + randomize_with_input(output, output_len, additional_input, sizeof(additional_input)); + } + +void RandomNumberGenerator::randomize_with_input(uint8_t output[], size_t output_len, + const uint8_t input[], size_t input_len) + { + this->add_entropy(input, input_len); + this->randomize(output, output_len); + } + +size_t RandomNumberGenerator::reseed(Entropy_Sources& srcs, + size_t poll_bits, + std::chrono::milliseconds poll_timeout) + { + return srcs.poll(*this, poll_bits, poll_timeout); + } + +void RandomNumberGenerator::reseed_from_rng(RandomNumberGenerator& rng, size_t poll_bits) + { + secure_vector buf(poll_bits / 8); + rng.randomize(buf.data(), buf.size()); + this->add_entropy(buf.data(), buf.size()); + } + +RandomNumberGenerator* RandomNumberGenerator::make_rng() + { +#if defined(BOTAN_HAS_AUTO_SEEDING_RNG) + return new AutoSeeded_RNG; +#else + throw Exception("make_rng failed, no AutoSeeded_RNG in this build"); +#endif + } + +#if defined(BOTAN_TARGET_OS_HAS_THREADS) + +#if defined(BOTAN_HAS_AUTO_SEEDING_RNG) +Serialized_RNG::Serialized_RNG() : m_rng(new AutoSeeded_RNG) {} +#else +Serialized_RNG::Serialized_RNG() + { + throw Exception("Serialized_RNG default constructor failed: AutoSeeded_RNG disabled in build"); + } +#endif + +#endif + +} diff --git a/src/libs/3rdparty/botan/src/lib/rng/rng.h b/src/libs/3rdparty/botan/src/lib/rng/rng.h new file mode 100644 index 0000000000..f6fa80df06 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/rng/rng.h @@ -0,0 +1,264 @@ +/* +* Random Number Generator base classes +* (C) 1999-2009,2015,2016 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_RANDOM_NUMBER_GENERATOR_H_ +#define BOTAN_RANDOM_NUMBER_GENERATOR_H_ + +#include +#include +#include +#include +#include + +namespace Botan { + +class Entropy_Sources; + +/** +* An interface to a cryptographic random number generator +*/ +class BOTAN_PUBLIC_API(2,0) RandomNumberGenerator + { + public: + virtual ~RandomNumberGenerator() = default; + + RandomNumberGenerator() = default; + + /* + * Never copy a RNG, create a new one + */ + RandomNumberGenerator(const RandomNumberGenerator& rng) = delete; + RandomNumberGenerator& operator=(const RandomNumberGenerator& rng) = delete; + + /** + * Randomize a byte array. + * @param output the byte array to hold the random output. + * @param length the length of the byte array output in bytes. + */ + virtual void randomize(uint8_t output[], size_t length) = 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. + * A few RNG types do not accept any externally provided input, + * in which case this function is a no-op. + * + * @param input a byte array containg the entropy to be added + * @param length the length of the byte array in + */ + virtual void add_entropy(const uint8_t input[], size_t length) = 0; + + /** + * Incorporate some additional data into the RNG state. + */ + template void add_entropy_T(const T& t) + { + this->add_entropy(reinterpret_cast(&t), sizeof(T)); + } + + /** + * Incorporate entropy into the RNG state then produce output. + * Some RNG types implement this using a single operation, default + * calls add_entropy + randomize in sequence. + * + * Use this to further bind the outputs to your current + * process/protocol state. For instance if generating a new key + * for use in a session, include a session ID or other such + * value. See NIST SP 800-90 A, B, C series for more ideas. + * + * @param output buffer to hold the random output + * @param output_len size of the output buffer in bytes + * @param input entropy buffer to incorporate + * @param input_len size of the input buffer in bytes + */ + virtual void randomize_with_input(uint8_t output[], size_t output_len, + const uint8_t input[], size_t input_len); + + /** + * This calls `randomize_with_input` using some timestamps as extra input. + * + * For a stateful RNG using non-random but potentially unique data the + * extra input can help protect against problems with fork, VM state + * rollback, or other cases where somehow an RNG state is duplicated. If + * both of the duplicated RNG states later incorporate a timestamp (and the + * timestamps don't themselves repeat), their outputs will diverge. + */ + virtual void randomize_with_ts_input(uint8_t output[], size_t output_len); + + /** + * @return the name of this RNG type + */ + virtual std::string name() const = 0; + + /** + * Clear all internally held values of this RNG + * @post is_seeded() == false + */ + virtual void clear() = 0; + + /** + * Check whether this RNG is seeded. + * @return true if this RNG was already seeded, false otherwise. + */ + virtual bool is_seeded() const = 0; + + /** + * Poll provided sources for up to poll_bits bits of entropy + * or until the timeout expires. Returns estimate of the number + * of bits collected. + */ + virtual size_t reseed(Entropy_Sources& srcs, + size_t poll_bits = BOTAN_RNG_RESEED_POLL_BITS, + std::chrono::milliseconds poll_timeout = BOTAN_RNG_RESEED_DEFAULT_TIMEOUT); + + /** + * Reseed by reading specified bits from the RNG + */ + virtual void reseed_from_rng(RandomNumberGenerator& rng, + size_t poll_bits = BOTAN_RNG_RESEED_POLL_BITS); + + // Some utility functions built on the interface above: + + /** + * Return a random vector + * @param bytes number of bytes in the result + * @return randomized vector of length bytes + */ + secure_vector random_vec(size_t bytes) + { + secure_vector output(bytes); + this->randomize(output.data(), output.size()); + return output; + } + + /** + * Return a random byte + * @return random byte + */ + uint8_t next_byte() + { + uint8_t b; + this->randomize(&b, 1); + return b; + } + + /** + * @return a random byte that is greater than zero + */ + uint8_t next_nonzero_byte() + { + uint8_t b = this->next_byte(); + while(b == 0) + b = this->next_byte(); + return b; + } + + /** + * Create a seeded and active RNG object for general application use + * Added in 1.8.0 + * Use AutoSeeded_RNG instead + */ + BOTAN_DEPRECATED("Use AutoSeeded_RNG") + static RandomNumberGenerator* make_rng(); + }; + +/** +* Convenience typedef +*/ +typedef RandomNumberGenerator RNG; + +/** +* Hardware_RNG has no members but exists to tag hardware RNG types +* (PKCS11_RNG, TPM_RNG, RDRAND_RNG) +*/ +class BOTAN_PUBLIC_API(2,0) Hardware_RNG : public RandomNumberGenerator + { + public: + virtual void clear() final override { /* no way to clear state of hardware RNG */ } + }; + +/** +* Null/stub RNG - fails if you try to use it for anything +* This is not generally useful except for in certain tests +*/ +class BOTAN_PUBLIC_API(2,0) Null_RNG final : public RandomNumberGenerator + { + public: + bool is_seeded() const override { return false; } + + void clear() override {} + + void randomize(uint8_t[], size_t) override + { + throw PRNG_Unseeded("Null_RNG called"); + } + + void add_entropy(const uint8_t[], size_t) override {} + + std::string name() const override { return "Null_RNG"; } + }; + +#if defined(BOTAN_TARGET_OS_HAS_THREADS) +/** +* Wraps access to a RNG in a mutex +* Note that most of the time it's much better to use a RNG per thread +* otherwise the RNG will act as an unnecessary contention point +*/ +class BOTAN_PUBLIC_API(2,0) Serialized_RNG final : public RandomNumberGenerator + { + public: + void randomize(uint8_t out[], size_t len) override + { + lock_guard_type lock(m_mutex); + m_rng->randomize(out, len); + } + + bool is_seeded() const override + { + lock_guard_type lock(m_mutex); + return m_rng->is_seeded(); + } + + void clear() override + { + lock_guard_type lock(m_mutex); + m_rng->clear(); + } + + std::string name() const override + { + lock_guard_type lock(m_mutex); + return m_rng->name(); + } + + size_t reseed(Entropy_Sources& src, + size_t poll_bits = BOTAN_RNG_RESEED_POLL_BITS, + std::chrono::milliseconds poll_timeout = BOTAN_RNG_RESEED_DEFAULT_TIMEOUT) override + { + lock_guard_type lock(m_mutex); + return m_rng->reseed(src, poll_bits, poll_timeout); + } + + void add_entropy(const uint8_t in[], size_t len) override + { + lock_guard_type lock(m_mutex); + m_rng->add_entropy(in, len); + } + + BOTAN_DEPRECATED("Use Serialized_RNG(new AutoSeeded_RNG)") Serialized_RNG(); + + explicit Serialized_RNG(RandomNumberGenerator* rng) : m_rng(rng) {} + private: + mutable mutex_type m_mutex; + std::unique_ptr m_rng; + }; +#endif + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/rng/stateful_rng/info.txt b/src/libs/3rdparty/botan/src/lib/rng/stateful_rng/info.txt new file mode 100644 index 0000000000..edc2d91694 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/rng/stateful_rng/info.txt @@ -0,0 +1,3 @@ + +STATEFUL_RNG -> 20160819 + diff --git a/src/libs/3rdparty/botan/src/lib/rng/stateful_rng/stateful_rng.cpp b/src/libs/3rdparty/botan/src/lib/rng/stateful_rng/stateful_rng.cpp new file mode 100644 index 0000000000..dec7917938 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/rng/stateful_rng/stateful_rng.cpp @@ -0,0 +1,112 @@ +/* +* (C) 2016 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include + +namespace Botan { + +void Stateful_RNG::clear() + { + m_reseed_counter = 0; + m_last_pid = 0; + } + +void Stateful_RNG::force_reseed() + { + m_reseed_counter = 0; + } + +bool Stateful_RNG::is_seeded() const + { + return m_reseed_counter > 0; + } + +void Stateful_RNG::initialize_with(const uint8_t input[], size_t len) + { + add_entropy(input, len); + + if(8*len >= security_level()) + { + reset_reseed_counter(); + } + } + +void Stateful_RNG::randomize_with_ts_input(uint8_t output[], size_t output_len) + { + uint8_t additional_input[24] = { 0 }; + store_le(OS::get_system_timestamp_ns(), additional_input); + store_le(OS::get_high_resolution_clock(), additional_input + 8); + store_le(m_last_pid, additional_input + 16); + store_le(static_cast(m_reseed_counter), additional_input + 20); + + randomize_with_input(output, output_len, additional_input, sizeof(additional_input)); + } + +size_t Stateful_RNG::reseed(Entropy_Sources& srcs, + size_t poll_bits, + std::chrono::milliseconds poll_timeout) + { + size_t bits_collected = RandomNumberGenerator::reseed(srcs, poll_bits, poll_timeout); + + if(bits_collected >= security_level()) + { + reset_reseed_counter(); + } + + return bits_collected; + } + +void Stateful_RNG::reseed_from_rng(RandomNumberGenerator& rng, size_t poll_bits) + { + RandomNumberGenerator::reseed_from_rng(rng, poll_bits); + + if(poll_bits >= security_level()) + { + reset_reseed_counter(); + } + } + +void Stateful_RNG::reseed_check() + { + const uint32_t cur_pid = OS::get_process_id(); + + const bool fork_detected = (m_last_pid > 0) && (cur_pid != m_last_pid); + + if(is_seeded() == false || + fork_detected || + (m_reseed_interval > 0 && m_reseed_counter >= m_reseed_interval)) + { + m_reseed_counter = 0; + m_last_pid = cur_pid; + + if(m_underlying_rng) + { + reseed_from_rng(*m_underlying_rng, security_level()); + } + + if(m_entropy_sources) + { + reseed(*m_entropy_sources, security_level()); + } + + if(!is_seeded()) + { + if(fork_detected) + throw Exception("Detected use of fork but cannot reseed DRBG"); + else + throw PRNG_Unseeded(name()); + } + } + else + { + BOTAN_ASSERT(m_reseed_counter != 0, "RNG is seeded"); + m_reseed_counter += 1; + } + } + +} 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 new file mode 100644 index 0000000000..18697ae231 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/rng/stateful_rng/stateful_rng.h @@ -0,0 +1,151 @@ +/* +* (C) 2016 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_STATEFUL_RNG_H_ +#define BOTAN_STATEFUL_RNG_H_ + +#include + +namespace Botan { + +/** +* Inherited by RNGs which maintain in-process state, like HMAC_DRBG. +* On Unix these RNGs are vulnerable to problems with fork, where the +* RNG state is duplicated, and the parent and child process RNGs will +* produce identical output until one of them reseeds. Stateful_RNG +* reseeds itself whenever a fork is detected, or after a set number of +* bytes have been output. +* +* Not implemented by RNGs which access an external RNG, such as the +* system PRNG or a hardware RNG. +*/ +class BOTAN_PUBLIC_API(2,0) Stateful_RNG : public RandomNumberGenerator + { + public: + /** + * @param rng is a reference to some RNG which will be used + * to perform the periodic reseeding + * @param entropy_sources will be polled to perform reseeding periodically + * @param reseed_interval specifies a limit of how many times + * the RNG will be called before automatic reseeding is performed + */ + Stateful_RNG(RandomNumberGenerator& rng, + Entropy_Sources& entropy_sources, + size_t reseed_interval) : + m_underlying_rng(&rng), + m_entropy_sources(&entropy_sources), + m_reseed_interval(reseed_interval) + {} + + /** + * @param rng is a reference to some RNG which will be used + * to perform the periodic reseeding + * @param reseed_interval specifies a limit of how many times + * the RNG will be called before automatic reseeding is performed + */ + Stateful_RNG(RandomNumberGenerator& rng, size_t reseed_interval) : + m_underlying_rng(&rng), + m_reseed_interval(reseed_interval) + {} + + /** + * @param entropy_sources will be polled to perform reseeding periodically + * @param reseed_interval specifies a limit of how many times + * the RNG will be called before automatic reseeding is performed + */ + Stateful_RNG(Entropy_Sources& entropy_sources, size_t reseed_interval) : + m_entropy_sources(&entropy_sources), + m_reseed_interval(reseed_interval) + {} + + /** + * In this case, automatic reseeding is impossible + */ + Stateful_RNG() : m_reseed_interval(0) {} + + /** + * Consume this input and mark the RNG as initialized regardless + * of the length of the input or the current seeded state of + * the RNG. + */ + void initialize_with(const uint8_t input[], size_t length); + + bool is_seeded() const override final; + + /** + * Mark state as requiring a reseed on next use + */ + void force_reseed(); + + void reseed_from_rng(RandomNumberGenerator& rng, + size_t poll_bits = BOTAN_RNG_RESEED_POLL_BITS) override final; + + /** + * Overrides default implementation and also includes the current + * process ID and the reseed counter. + */ + void randomize_with_ts_input(uint8_t output[], size_t output_len) override final; + + /** + * Poll provided sources for up to poll_bits bits of entropy + * or until the timeout expires. Returns estimate of the number + * of bits collected. + */ + size_t reseed(Entropy_Sources& srcs, + size_t poll_bits = BOTAN_RNG_RESEED_POLL_BITS, + std::chrono::milliseconds poll_timeout = BOTAN_RNG_RESEED_DEFAULT_TIMEOUT) override; + + /** + * @return intended security level of this DRBG + */ + virtual size_t security_level() const = 0; + + /** + * Some DRBGs have a notion of the maximum number of bytes per + * request. Longer requests (to randomize) will be treated as + * multiple requests, and may initiate reseeding multiple times, + * depending on the values of max_number_of_bytes_per_request and + * reseed_interval(). This function returns zero if the RNG in + * question does not have such a notion. + * + * @return max number of bytes per request (or zero) + */ + virtual size_t max_number_of_bytes_per_request() const = 0; + + size_t reseed_interval() const { return m_reseed_interval; } + + void clear() override; + + protected: + void reseed_check(); + + /** + * Called by a subclass to notify that a reseed has been + * successfully performed. + */ + void reset_reseed_counter() { m_reseed_counter = 1; } + + private: + // A non-owned and possibly null pointer to shared RNG + RandomNumberGenerator* m_underlying_rng = nullptr; + + // A non-owned and possibly null pointer to a shared Entropy_Source + Entropy_Sources* m_entropy_sources = nullptr; + + const size_t m_reseed_interval; + uint32_t m_last_pid = 0; + + /* + * Set to 1 after a successful seeding, then incremented. Reset + * to 0 by clear() or a fork. This logic is used even if + * automatic reseeding is disabled (via m_reseed_interval = 0) + */ + size_t m_reseed_counter = 0; + }; + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/rng/system_rng/info.txt b/src/libs/3rdparty/botan/src/lib/rng/system_rng/info.txt new file mode 100644 index 0000000000..da4fce4e36 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/rng/system_rng/info.txt @@ -0,0 +1,18 @@ + +SYSTEM_RNG -> 20141202 + + + +dev_random,posix1 +arc4random +rtlgenrandom +crypto_ng + + + +uwp -> bcrypt.lib + + + +rtlgenrandom?dyn_load + 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 new file mode 100644 index 0000000000..c3b37ea9cc --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/rng/system_rng/system_rng.cpp @@ -0,0 +1,231 @@ +/* +* System RNG +* (C) 2014,2015,2017,2018 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include + +#if defined(BOTAN_TARGET_OS_HAS_RTLGENRANDOM) + #include + #define NOMINMAX 1 + #define _WINSOCKAPI_ // stop windows.h including winsock.h + #include + +#elif defined(BOTAN_TARGET_OS_HAS_CRYPTO_NG) + #include + +#elif defined(BOTAN_TARGET_OS_HAS_ARC4RANDOM) + #include + +#elif defined(BOTAN_TARGET_OS_HAS_DEV_RANDOM) + #include + #include + #include + #include + #include +#endif + +namespace Botan { + +namespace { + +#if defined(BOTAN_TARGET_OS_HAS_RTLGENRANDOM) + +class System_RNG_Impl final : public RandomNumberGenerator + { + public: + System_RNG_Impl() : m_advapi("advapi32.dll") + { + // This throws if the function is not found + m_rtlgenrandom = m_advapi.resolve("SystemFunction036"); + } + + void randomize(uint8_t buf[], size_t len) override + { + bool success = m_rtlgenrandom(buf, 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; } + void clear() override { /* not possible */ } + std::string name() const override { return "RtlGenRandom"; } + private: + // Use type BYTE instead of BOOLEAN because of a naming conflict + // https://msdn.microsoft.com/en-us/library/windows/desktop/aa387694(v=vs.85).aspx + // https://msdn.microsoft.com/en-us/library/windows/desktop/aa383751(v=vs.85).aspx + using RtlGenRandom_fptr = BYTE (NTAPI *)(PVOID, ULONG); + + Dynamically_Loaded_Library m_advapi; + RtlGenRandom_fptr m_rtlgenrandom; + }; + +#elif defined(BOTAN_TARGET_OS_HAS_CRYPTO_NG) + +class System_RNG_Impl final : public RandomNumberGenerator + { + public: + System_RNG_Impl() + { + NTSTATUS ret = ::BCryptOpenAlgorithmProvider(&m_prov, + BCRYPT_RNG_ALGORITHM, + MS_PRIMITIVE_PROVIDER, 0); + if(ret != STATUS_SUCCESS) + throw Exception("System_RNG failed to acquire crypto provider"); + } + + ~System_RNG_Impl() + { + ::BCryptCloseAlgorithmProvider(m_prov, 0); + } + + void randomize(uint8_t buf[], size_t len) override + { + NTSTATUS ret = ::BCryptGenRandom(m_prov, static_cast(buf), static_cast(len), 0); + if(ret != STATUS_SUCCESS) + throw Exception("System_RNG call to BCryptGenRandom failed"); + } + + void add_entropy(const uint8_t in[], size_t length) override + { + /* + There is a flag BCRYPT_RNG_USE_ENTROPY_IN_BUFFER to provide + entropy inputs, but it is ignored in Windows 8 and later. + */ + } + + bool is_seeded() const override { return true; } + void clear() override { /* not possible */ } + std::string name() const override { return "crypto_ng"; } + private: + BCRYPT_ALG_HANDLE m_handle; + }; + +#elif defined(BOTAN_TARGET_OS_HAS_ARC4RANDOM) + +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 + { + ::arc4random_buf(buf, len); + } + + 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_DEV_RANDOM) + +// Read a random device + +class System_RNG_Impl final : public RandomNumberGenerator + { + public: + System_RNG_Impl() + { + #ifndef O_NOCTTY + #define O_NOCTTY 0 + #endif + + 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) + m_fd = ::open(BOTAN_SYSTEM_RNG_DEVICE, O_RDONLY | O_NOCTTY); + + if(m_fd < 0) + throw Exception("System_RNG failed to open RNG device"); + } + + ~System_RNG_Impl() + { + ::close(m_fd); + m_fd = -1; + } + + 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; } + void clear() override { /* not possible */ } + std::string name() const override { return BOTAN_SYSTEM_RNG_DEVICE; } + private: + int m_fd; + }; + +void System_RNG_Impl::randomize(uint8_t buf[], size_t len) + { + while(len) + { + ssize_t got = ::read(m_fd, buf, len); + + if(got < 0) + { + if(errno == EINTR) + continue; + throw Exception("System_RNG read failed error " + std::to_string(errno)); + } + if(got == 0) + throw Exception("System_RNG EOF on device"); // ?!? + + buf += got; + len -= got; + } + } + +void System_RNG_Impl::add_entropy(const uint8_t input[], size_t len) + { + while(len) + { + ssize_t got = ::write(m_fd, input, len); + + if(got < 0) + { + if(errno == EINTR) + continue; + + /* + * This is seen on OS X CI, despite the fact that the man page + * for Darwin urandom explicitly states that writing to it is + * supported, and write(2) does not document EPERM at all. + * But in any case EPERM seems indicative of a policy decision + * by the OS or sysadmin that additional entropy is not wanted + * in the system pool, so we accept that and return here, + * since there is no corrective action possible. + * + * In Linux EBADF or EPERM is returned if m_fd is not opened for + * writing. + */ + if(errno == EPERM || errno == EBADF) + return; + + // maybe just ignore any failure here and return? + throw Exception("System_RNG write failed error " + std::to_string(errno)); + } + + input += got; + len -= got; + } + } + +#endif + +} + +RandomNumberGenerator& system_rng() + { + static System_RNG_Impl g_system_rng; + return g_system_rng; + } + +} 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 new file mode 100644 index 0000000000..4e3beaf9fb --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/rng/system_rng/system_rng.h @@ -0,0 +1,41 @@ +/* +* System RNG interface +* (C) 2014,2015 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_SYSTEM_RNG_H_ +#define BOTAN_SYSTEM_RNG_H_ + +#include + +namespace Botan { + +/** +* Return a shared reference to a global PRNG instance provided by the +* operating system. For instance might be instantiated by /dev/urandom +* or CryptGenRandom. +*/ +BOTAN_PUBLIC_API(2,0) RandomNumberGenerator& system_rng(); + +/* +* Instantiable reference to the system RNG. +*/ +class BOTAN_PUBLIC_API(2,0) System_RNG final : public RandomNumberGenerator + { + public: + std::string name() const override { return system_rng().name(); } + + void randomize(uint8_t out[], size_t len) override { system_rng().randomize(out, len); } + + void add_entropy(const uint8_t in[], size_t length) override { system_rng().add_entropy(in, length); } + + bool is_seeded() const override { return system_rng().is_seeded(); } + + void clear() override { system_rng().clear(); } + }; + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/stream/ctr/ctr.cpp b/src/libs/3rdparty/botan/src/lib/stream/ctr/ctr.cpp new file mode 100644 index 0000000000..2616463443 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/stream/ctr/ctr.cpp @@ -0,0 +1,203 @@ +/* +* Counter mode +* (C) 1999-2011,2014 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include + +namespace Botan { + +CTR_BE::CTR_BE(BlockCipher* ciph) : + m_cipher(ciph), + m_block_size(m_cipher->block_size()), + m_ctr_size(m_block_size), + m_ctr_blocks(m_cipher->parallel_bytes() / m_block_size), + m_counter(m_cipher->parallel_bytes()), + m_pad(m_counter.size()), + m_pad_pos(0) + { + } + +CTR_BE::CTR_BE(BlockCipher* cipher, size_t ctr_size) : + m_cipher(cipher), + m_block_size(m_cipher->block_size()), + m_ctr_size(ctr_size), + m_ctr_blocks(m_cipher->parallel_bytes() / m_block_size), + m_counter(m_cipher->parallel_bytes()), + m_pad(m_counter.size()), + m_pad_pos(0) + { + BOTAN_ARG_CHECK(m_ctr_size >= 4 && m_ctr_size <= m_block_size, + "Invalid CTR-BE counter size"); + } + +void CTR_BE::clear() + { + m_cipher->clear(); + zeroise(m_pad); + zeroise(m_counter); + zap(m_iv); + m_pad_pos = 0; + } + +void CTR_BE::key_schedule(const uint8_t key[], size_t key_len) + { + m_cipher->set_key(key, key_len); + + // Set a default all-zeros IV + set_iv(nullptr, 0); + } + +std::string CTR_BE::name() const + { + if(m_ctr_size == m_block_size) + return ("CTR-BE(" + m_cipher->name() + ")"); + else + return ("CTR-BE(" + m_cipher->name() + "," + std::to_string(m_ctr_size) + ")"); + + } + +void CTR_BE::cipher(const uint8_t in[], uint8_t out[], size_t length) + { + verify_key_set(m_iv.empty() == false); + + const uint8_t* pad_bits = &m_pad[0]; + const size_t pad_size = m_pad.size(); + + if(m_pad_pos > 0) + { + const size_t avail = pad_size - m_pad_pos; + const size_t take = std::min(length, avail); + xor_buf(out, in, pad_bits + m_pad_pos, take); + length -= take; + in += take; + out += take; + m_pad_pos += take; + + if(take == avail) + { + add_counter(m_ctr_blocks); + m_cipher->encrypt_n(m_counter.data(), m_pad.data(), m_ctr_blocks); + m_pad_pos = 0; + } + } + + while(length >= pad_size) + { + xor_buf(out, in, pad_bits, pad_size); + length -= pad_size; + in += pad_size; + out += pad_size; + + add_counter(m_ctr_blocks); + m_cipher->encrypt_n(m_counter.data(), m_pad.data(), m_ctr_blocks); + } + + xor_buf(out, in, pad_bits, length); + m_pad_pos += length; + } + +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()); + zeroise(m_iv); + buffer_insert(m_iv, 0, iv, iv_len); + + seek(0); + } + +void CTR_BE::add_counter(const uint64_t counter) + { + const size_t ctr_size = m_ctr_size; + const size_t ctr_blocks = m_ctr_blocks; + const size_t BS = m_block_size; + + if(ctr_size == 4) + { + size_t off = (BS - 4); + for(size_t i = 0; i != ctr_blocks; ++i) + { + uint32_t low32 = load_be(&m_counter[off], 0); + low32 += counter; + store_be(low32, &m_counter[off]); + off += BS; + } + } + else if(ctr_size == 8) + { + size_t off = (BS - 8); + for(size_t i = 0; i != ctr_blocks; ++i) + { + uint64_t low64 = load_be(&m_counter[off], 0); + low64 += counter; + store_be(low64, &m_counter[off]); + off += BS; + } + } + else if(ctr_size == 16) + { + size_t off = (BS - 16); + for(size_t i = 0; i != ctr_blocks; ++i) + { + uint64_t b0 = load_be(&m_counter[off], 0); + uint64_t b1 = load_be(&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; + } + } + else + { + for(size_t i = 0; i != ctr_blocks; ++i) + { + uint64_t local_counter = counter; + uint16_t carry = static_cast(local_counter); + for(size_t j = 0; (carry || local_counter) && j != ctr_size; ++j) + { + const size_t off = i*BS + (BS-1-j); + const uint16_t cnt = static_cast(m_counter[off]) + carry; + m_counter[off] = static_cast(cnt); + local_counter = (local_counter >> 8); + carry = (cnt >> 8) + static_cast(local_counter); + } + } + } + } + +void CTR_BE::seek(uint64_t offset) + { + verify_key_set(m_iv.empty() == false); + + const uint64_t base_counter = m_ctr_blocks * (offset / m_counter.size()); + + zeroise(m_counter); + buffer_insert(m_counter, 0, m_iv); + + 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) + { + 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; + } + + if(base_counter > 0) + add_counter(base_counter); + + m_cipher->encrypt_n(m_counter.data(), m_pad.data(), m_ctr_blocks); + m_pad_pos = offset % m_counter.size(); + } +} diff --git a/src/libs/3rdparty/botan/src/lib/stream/ctr/ctr.h b/src/libs/3rdparty/botan/src/lib/stream/ctr/ctr.h new file mode 100644 index 0000000000..c4c5981616 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/stream/ctr/ctr.h @@ -0,0 +1,66 @@ +/* +* CTR-BE Mode +* (C) 1999-2007 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_CTR_BE_H_ +#define BOTAN_CTR_BE_H_ + +#include +#include + +namespace Botan { + +/** +* CTR-BE (Counter mode, big-endian) +*/ +class BOTAN_PUBLIC_API(2,0) CTR_BE final : public StreamCipher + { + public: + void cipher(const uint8_t in[], uint8_t out[], size_t length) override; + + 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()); } + + Key_Length_Specification key_spec() const override + { + return m_cipher->key_spec(); + } + + std::string name() const override; + + CTR_BE* clone() const override + { return new CTR_BE(m_cipher->clone(), m_ctr_size); } + + void clear() override; + + /** + * @param cipher the block cipher to use + */ + explicit CTR_BE(BlockCipher* cipher); + + CTR_BE(BlockCipher* cipher, size_t ctr_size); + + void seek(uint64_t offset) override; + private: + void key_schedule(const uint8_t key[], size_t key_len) override; + void add_counter(const uint64_t counter); + + std::unique_ptr m_cipher; + + const size_t m_block_size; + const size_t m_ctr_size; + const size_t m_ctr_blocks; + + secure_vector m_counter, m_pad; + std::vector m_iv; + size_t m_pad_pos; + }; + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/stream/ctr/info.txt b/src/libs/3rdparty/botan/src/lib/stream/ctr/info.txt new file mode 100644 index 0000000000..270ceecf8b --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/stream/ctr/info.txt @@ -0,0 +1,7 @@ + +CTR_BE -> 20131128 + + + +block + diff --git a/src/libs/3rdparty/botan/src/lib/stream/info.txt b/src/libs/3rdparty/botan/src/lib/stream/info.txt new file mode 100644 index 0000000000..4f62c5a7c1 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/stream/info.txt @@ -0,0 +1,7 @@ + +STREAM_CIPHER -> 20131128 + + + +stream_cipher.h + diff --git a/src/libs/3rdparty/botan/src/lib/stream/stream_cipher.cpp b/src/libs/3rdparty/botan/src/lib/stream/stream_cipher.cpp new file mode 100644 index 0000000000..692464723c --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/stream/stream_cipher.cpp @@ -0,0 +1,149 @@ +/* +* Stream Ciphers +* (C) 2015,2016 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include + +#if defined(BOTAN_HAS_CHACHA) + #include +#endif + +#if defined(BOTAN_HAS_SALSA20) + #include +#endif + +#if defined(BOTAN_HAS_SHAKE_CIPHER) + #include +#endif + +#if defined(BOTAN_HAS_CTR_BE) + #include +#endif + +#if defined(BOTAN_HAS_OFB) + #include +#endif + +#if defined(BOTAN_HAS_RC4) + #include +#endif + +#if defined(BOTAN_HAS_OPENSSL) + #include +#endif + +namespace Botan { + +std::unique_ptr StreamCipher::create(const std::string& algo_spec, + const std::string& provider) + { + const SCAN_Name req(algo_spec); + +#if defined(BOTAN_HAS_CTR_BE) + if((req.algo_name() == "CTR-BE" || req.algo_name() == "CTR") && req.arg_count_between(1,2)) + { + if(provider.empty() || provider == "base") + { + auto cipher = BlockCipher::create(req.arg(0)); + if(cipher) + { + size_t ctr_size = req.arg_as_integer(1, cipher->block_size()); + return std::unique_ptr(new CTR_BE(cipher.release(), ctr_size)); + } + } + } +#endif + +#if defined(BOTAN_HAS_CHACHA) + if(req.algo_name() == "ChaCha") + { + if(provider.empty() || provider == "base") + return std::unique_ptr(new ChaCha(req.arg_as_integer(0, 20))); + } + + if(req.algo_name() == "ChaCha20") + { + if(provider.empty() || provider == "base") + return std::unique_ptr(new ChaCha(20)); + } +#endif + +#if defined(BOTAN_HAS_SALSA20) + if(req.algo_name() == "Salsa20") + { + if(provider.empty() || provider == "base") + return std::unique_ptr(new Salsa20); + } +#endif + +#if defined(BOTAN_HAS_SHAKE_CIPHER) + if(req.algo_name() == "SHAKE-128") + { + if(provider.empty() || provider == "base") + return std::unique_ptr(new SHAKE_128_Cipher); + } +#endif + +#if defined(BOTAN_HAS_OFB) + if(req.algo_name() == "OFB" && req.arg_count() == 1) + { + if(provider.empty() || provider == "base") + { + if(auto c = BlockCipher::create(req.arg(0))) + return std::unique_ptr(new OFB(c.release())); + } + } +#endif + +#if defined(BOTAN_HAS_RC4) + + if(req.algo_name() == "RC4" || + req.algo_name() == "ARC4" || + req.algo_name() == "MARK-4") + { + const size_t skip = (req.algo_name() == "MARK-4") ? 256 : req.arg_as_integer(0, 0); + +#if defined(BOTAN_HAS_OPENSSL) + if(provider.empty() || provider == "openssl") + { + return std::unique_ptr(make_openssl_rc4(skip)); + } +#endif + + if(provider.empty() || provider == "base") + { + return std::unique_ptr(new RC4(skip)); + } + } + +#endif + + BOTAN_UNUSED(req); + BOTAN_UNUSED(provider); + + return nullptr; + } + +//static +std::unique_ptr +StreamCipher::create_or_throw(const std::string& algo, + const std::string& provider) + { + if(auto sc = StreamCipher::create(algo, provider)) + { + return sc; + } + throw Lookup_Error("Stream cipher", algo, provider); + } + +std::vector StreamCipher::providers(const std::string& algo_spec) + { + return probe_providers_of(algo_spec, {"base", "openssl"}); + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/stream/stream_cipher.h b/src/libs/3rdparty/botan/src/lib/stream/stream_cipher.h new file mode 100644 index 0000000000..03ffcadd04 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/stream/stream_cipher.h @@ -0,0 +1,129 @@ +/* +* Stream Cipher +* (C) 1999-2007 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_STREAM_CIPHER_H_ +#define BOTAN_STREAM_CIPHER_H_ + +#include +#include +#include + +namespace Botan { + +/** +* Base class for all stream ciphers +*/ +class BOTAN_PUBLIC_API(2,0) StreamCipher : public SymmetricAlgorithm + { + public: + virtual ~StreamCipher() = default; + + /** + * 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 use + * @return a null pointer if the algo/provider combination cannot be found + */ + static std::unique_ptr + create(const std::string& algo_spec, + const std::string& provider = ""); + + /** + * 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 use + * Throws a Lookup_Error if the algo/provider combination cannot be found + */ + static std::unique_ptr + 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 providers(const std::string& algo_spec); + + /** + * Encrypt or decrypt a message + * @param in the plaintext + * @param out the byte array to hold the output, i.e. the ciphertext + * @param len the length of both in and out in bytes + */ + virtual void cipher(const uint8_t in[], uint8_t out[], size_t len) = 0; + + /** + * Encrypt or decrypt a message + * The message is encrypted/decrypted in place. + * @param buf the plaintext / ciphertext + * @param len the length of buf in bytes + */ + void cipher1(uint8_t buf[], size_t len) + { cipher(buf, buf, len); } + + /** + * Encrypt a message + * The message is encrypted/decrypted in place. + * @param inout the plaintext / ciphertext + */ + template + void encipher(std::vector& inout) + { cipher(inout.data(), inout.data(), inout.size()); } + + /** + * Encrypt a message + * The message is encrypted in place. + * @param inout the plaintext / ciphertext + */ + template + void encrypt(std::vector& inout) + { cipher(inout.data(), inout.data(), inout.size()); } + + /** + * Decrypt a message in place + * The message is decrypted in place. + * @param inout the plaintext / ciphertext + */ + template + void decrypt(std::vector& inout) + { cipher(inout.data(), inout.data(), inout.size()); } + + /** + * Resync the cipher using the IV + * @param iv the initialization vector + * @param iv_len the length of the IV in bytes + */ + virtual void set_iv(const uint8_t iv[], size_t iv_len) = 0; + + /** + * @param iv_len the length of the IV in bytes + * @return if the length is valid for this algorithm + */ + virtual bool valid_iv_length(size_t iv_len) const { return (iv_len == 0); } + + /** + * @return a new object representing the same algorithm as *this + */ + virtual StreamCipher* clone() const = 0; + + /** + * Set the offset and the state used later to generate the keystream + * @param offset the offset where we begin to generate the keystream + */ + virtual void seek(uint64_t offset) = 0; + + /** + * @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"; } + }; + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/utils/assert.cpp b/src/libs/3rdparty/botan/src/lib/utils/assert.cpp new file mode 100644 index 0000000000..cd957e00d1 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/utils/assert.cpp @@ -0,0 +1,47 @@ +/* +* Runtime assertion checking +* (C) 2010,2012,2018 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include + +namespace Botan { + +void throw_invalid_argument(const char* message, + const char* func, + const char* file) + { + std::ostringstream format; + + format << message << " in " << func << ":" << file; + + throw Invalid_Argument(format.str()); + } + +void assertion_failure(const char* expr_str, + const char* assertion_made, + const char* func, + const char* file, + int line) + { + std::ostringstream format; + + format << "False assertion "; + + if(assertion_made && assertion_made[0] != 0) + format << "'" << assertion_made << "' (expression " << expr_str << ") "; + else + format << expr_str << " "; + + if(func) + format << "in " << func << " "; + + format << "@" << file << ":" << line; + + throw Exception(format.str()); + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/utils/assert.h b/src/libs/3rdparty/botan/src/lib/utils/assert.h new file mode 100644 index 0000000000..a12872f2bc --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/utils/assert.h @@ -0,0 +1,145 @@ +/* +* Runtime assertion checking +* (C) 2010,2018 Jack Lloyd +* 2017 Simon Warta (Kullo GmbH) +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_ASSERTION_CHECKING_H_ +#define BOTAN_ASSERTION_CHECKING_H_ + +#include +#include + +namespace Botan { + +/** +* Called when an assertion fails +* Throws an Exception object +*/ +BOTAN_NORETURN void BOTAN_PUBLIC_API(2,0) + assertion_failure(const char* expr_str, + const char* assertion_made, + const char* func, + const char* file, + int line); + +/** +* Called when an invalid argument is used +* Throws Invalid_Argument +*/ +BOTAN_NORETURN void BOTAN_UNSTABLE_API throw_invalid_argument(const char* message, + const char* func, + const char* file); + + +#define BOTAN_ARG_CHECK(expr, msg) \ + do { if(!(expr)) Botan::throw_invalid_argument(msg, BOTAN_CURRENT_FUNCTION, __FILE__); } while(0) + +/** +* Make an assertion +*/ +#define BOTAN_ASSERT(expr, assertion_made) \ + do { \ + if(!(expr)) \ + Botan::assertion_failure(#expr, \ + assertion_made, \ + BOTAN_CURRENT_FUNCTION, \ + __FILE__, \ + __LINE__); \ + } while(0) + +/** +* Make an assertion +*/ +#define BOTAN_ASSERT_NOMSG(expr) \ + do { \ + if(!(expr)) \ + Botan::assertion_failure(#expr, \ + "", \ + BOTAN_CURRENT_FUNCTION, \ + __FILE__, \ + __LINE__); \ + } while(0) + +/** +* Assert that value1 == value2 +*/ +#define BOTAN_ASSERT_EQUAL(expr1, expr2, assertion_made) \ + do { \ + if((expr1) != (expr2)) \ + Botan::assertion_failure(#expr1 " == " #expr2, \ + assertion_made, \ + BOTAN_CURRENT_FUNCTION, \ + __FILE__, \ + __LINE__); \ + } while(0) + +/** +* Assert that expr1 (if true) implies expr2 is also true +*/ +#define BOTAN_ASSERT_IMPLICATION(expr1, expr2, msg) \ + do { \ + if((expr1) && !(expr2)) \ + Botan::assertion_failure(#expr1 " implies " #expr2, \ + msg, \ + BOTAN_CURRENT_FUNCTION, \ + __FILE__, \ + __LINE__); \ + } while(0) + +/** +* Assert that a pointer is not null +*/ +#define BOTAN_ASSERT_NONNULL(ptr) \ + do { \ + if((ptr) == nullptr) \ + Botan::assertion_failure(#ptr " is not null", \ + "", \ + BOTAN_CURRENT_FUNCTION, \ + __FILE__, \ + __LINE__); \ + } while(0) + +#if defined(BOTAN_ENABLE_DEBUG_ASSERTS) + +#define BOTAN_DEBUG_ASSERT(expr) BOTAN_ASSERT_NOMSG(expr) + +#else + +#define BOTAN_DEBUG_ASSERT(expr) do {} while(0) + +#endif + +/** +* Mark variable as unused. Takes between 1 and 9 arguments and marks all as unused, +* e.g. BOTAN_UNUSED(a); or BOTAN_UNUSED(x, y, z); +*/ +#define _BOTAN_UNUSED_IMPL1(a) static_cast(a) +#define _BOTAN_UNUSED_IMPL2(a, b) static_cast(a); _BOTAN_UNUSED_IMPL1(b) +#define _BOTAN_UNUSED_IMPL3(a, b, c) static_cast(a); _BOTAN_UNUSED_IMPL2(b, c) +#define _BOTAN_UNUSED_IMPL4(a, b, c, d) static_cast(a); _BOTAN_UNUSED_IMPL3(b, c, d) +#define _BOTAN_UNUSED_IMPL5(a, b, c, d, e) static_cast(a); _BOTAN_UNUSED_IMPL4(b, c, d, e) +#define _BOTAN_UNUSED_IMPL6(a, b, c, d, e, f) static_cast(a); _BOTAN_UNUSED_IMPL5(b, c, d, e, f) +#define _BOTAN_UNUSED_IMPL7(a, b, c, d, e, f, g) static_cast(a); _BOTAN_UNUSED_IMPL6(b, c, d, e, f, g) +#define _BOTAN_UNUSED_IMPL8(a, b, c, d, e, f, g, h) static_cast(a); _BOTAN_UNUSED_IMPL7(b, c, d, e, f, g, h) +#define _BOTAN_UNUSED_IMPL9(a, b, c, d, e, f, g, h, i) static_cast(a); _BOTAN_UNUSED_IMPL8(b, c, d, e, f, g, h, i) +#define _BOTAN_UNUSED_GET_IMPL(_1, _2, _3, _4, _5, _6, _7, _8, _9, IMPL_NAME, ...) IMPL_NAME + +#define BOTAN_UNUSED(...) _BOTAN_UNUSED_GET_IMPL(__VA_ARGS__, \ + _BOTAN_UNUSED_IMPL9, \ + _BOTAN_UNUSED_IMPL8, \ + _BOTAN_UNUSED_IMPL7, \ + _BOTAN_UNUSED_IMPL6, \ + _BOTAN_UNUSED_IMPL5, \ + _BOTAN_UNUSED_IMPL4, \ + _BOTAN_UNUSED_IMPL3, \ + _BOTAN_UNUSED_IMPL2, \ + _BOTAN_UNUSED_IMPL1, \ + unused dummy rest value \ + ) /* we got an one of _BOTAN_UNUSED_IMPL*, now call it */ (__VA_ARGS__) + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/utils/bit_ops.h b/src/libs/3rdparty/botan/src/lib/utils/bit_ops.h new file mode 100644 index 0000000000..c7e4014923 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/utils/bit_ops.h @@ -0,0 +1,161 @@ +/* +* Bit/Word Operations +* (C) 1999-2008 Jack Lloyd +* (C) Copyright Projet SECRET, INRIA, Rocquencourt +* (C) Bhaskar Biswas and Nicolas Sendrier +* (C) 2014 cryptosource GmbH +* (C) 2014 Falko Strenzke fstrenzke@cryptosource.de +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_BIT_OPS_H_ +#define BOTAN_BIT_OPS_H_ + +#include + +namespace Botan { + +/** +* Power of 2 test. T should be an unsigned integer type +* @param arg an integer value +* @return true iff arg is 2^n for some n > 0 +*/ +template +inline bool is_power_of_2(T arg) + { + return ((arg != 0 && arg != 1) && ((arg & (arg-1)) == 0)); + } + +/** +* Return the index of the highest set bit +* T is an unsigned integer type +* @param n an integer value +* @return index of the highest set bit in n +*/ +template +inline size_t high_bit(T n) + { + for(size_t i = 8*sizeof(T); i > 0; --i) + if((n >> (i - 1)) & 0x01) + return i; + return 0; + } + +/** +* Return the index of the lowest set bit +* T is an unsigned integer type +* @param n an integer value +* @return index of the lowest set bit in n +*/ +template +inline size_t low_bit(T n) + { + for(size_t i = 0; i != 8*sizeof(T); ++i) + if((n >> i) & 0x01) + return (i + 1); + return 0; + } + +/** +* Return the number of significant bytes in n +* @param n an integer value +* @return number of significant bytes in n +*/ +template +inline size_t significant_bytes(T n) + { + for(size_t i = 0; i != sizeof(T); ++i) + if(get_byte(i, n)) + return sizeof(T)-i; + return 0; + } + +/** +* Compute Hamming weights +* @param n an integer value +* @return number of bits in n set to 1 +*/ +template +inline size_t hamming_weight(T n) + { + const uint8_t NIBBLE_WEIGHTS[] = { + 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 }; + + size_t weight = 0; + for(size_t i = 0; i != 2*sizeof(T); ++i) + weight += NIBBLE_WEIGHTS[(n >> (4*i)) & 0x0F]; + return weight; + } + +/** +* Count the trailing zero bits in n +* @param n an integer value +* @return maximum x st 2^x divides n +*/ +template +inline size_t ctz(T n) + { + for(size_t i = 0; i != 8*sizeof(T); ++i) + if((n >> i) & 0x01) + return i; + return 8*sizeof(T); + } + +#if defined(BOTAN_BUILD_COMPILER_IS_GCC) || defined(BOTAN_BUILD_COMPILER_IS_CLANG) + +template<> +inline size_t ctz(uint32_t n) + { + if(n == 0) + return 32; + return __builtin_ctz(n); + } + +template<> +inline size_t ctz(uint64_t n) + { + if(n == 0) + return 64; + return __builtin_ctzll(n); + } + +template<> +inline size_t high_bit(uint32_t x) + { + if(x == 0) + return 0; + return (32 - __builtin_clz(x)); + } + +template<> +inline size_t high_bit(uint64_t x) + { + if(x == 0) + return 0; + return (64 - __builtin_clzll(x)); + } + +#endif + +template +size_t ceil_log2(T x) + { + if(x >> (sizeof(T)*8-1)) + return sizeof(T)*8; + + size_t result = 0; + T compare = 1; + + while(compare < x) + { + compare <<= 1; + result++; + } + + return result; + } + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/utils/bswap.h b/src/libs/3rdparty/botan/src/lib/utils/bswap.h new file mode 100644 index 0000000000..8d5731f1b0 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/utils/bswap.h @@ -0,0 +1,99 @@ +/* +* Byte Swapping Operations +* (C) 1999-2011 Jack Lloyd +* (C) 2007 Yves Jerschow +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_BYTE_SWAP_H_ +#define BOTAN_BYTE_SWAP_H_ + +#include +#include + +#if defined(BOTAN_BUILD_COMPILER_IS_MSVC) + #include +#endif + +namespace Botan { + +/** +* Swap a 16 bit integer +*/ +inline uint16_t reverse_bytes(uint16_t val) + { + return rotl<8>(val); + } + +/** +* Swap a 32 bit integer +*/ +inline uint32_t reverse_bytes(uint32_t val) + { +#if defined(BOTAN_BUILD_COMPILER_IS_GCC) || defined(BOTAN_BUILD_COMPILER_IS_CLANG) + return __builtin_bswap32(val); + +#elif defined(BOTAN_BUILD_COMPILER_IS_MSVC) + return _byteswap_ulong(val); + +#elif defined(BOTAN_USE_GCC_INLINE_ASM) && defined(BOTAN_TARGET_CPU_IS_X86_FAMILY) + + // GCC-style inline assembly for x86 or x86-64 + asm("bswapl %0" : "=r" (val) : "0" (val)); + return val; + +#else + + // Generic implementation + return (rotr<8>(val) & 0xFF00FF00) | (rotl<8>(val) & 0x00FF00FF); + +#endif + } + +/** +* Swap a 64 bit integer +*/ +inline uint64_t reverse_bytes(uint64_t val) + { +#if defined(BOTAN_BUILD_COMPILER_IS_GCC) || defined(BOTAN_BUILD_COMPILER_IS_CLANG) + return __builtin_bswap64(val); + +#elif defined(BOTAN_BUILD_COMPILER_IS_MSVC) + return _byteswap_uint64(val); + +#elif defined(BOTAN_USE_GCC_INLINE_ASM) && defined(BOTAN_TARGET_ARCH_IS_X86_64) + // GCC-style inline assembly for x86-64 + asm("bswapq %0" : "=r" (val) : "0" (val)); + return val; + +#else + /* Generic implementation. Defined in terms of 32-bit bswap so any + * optimizations in that version can help. + */ + + uint32_t hi = static_cast(val >> 32); + uint32_t lo = static_cast(val); + + hi = reverse_bytes(hi); + lo = reverse_bytes(lo); + + return (static_cast(lo) << 32) | hi; +#endif + } + +/** +* Swap 4 Ts in an array +*/ +template +inline void bswap_4(T x[4]) + { + x[0] = reverse_bytes(x[0]); + x[1] = reverse_bytes(x[1]); + x[2] = reverse_bytes(x[2]); + x[3] = reverse_bytes(x[3]); + } + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/utils/calendar.cpp b/src/libs/3rdparty/botan/src/lib/utils/calendar.cpp new file mode 100644 index 0000000000..fe04f1d239 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/utils/calendar.cpp @@ -0,0 +1,119 @@ +/* +* Calendar Functions +* (C) 1999-2010,2017 Jack Lloyd +* (C) 2015 Simon Warta (Kullo GmbH) +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include +#include +#include + +namespace Botan { + +namespace { + +std::tm do_gmtime(std::time_t time_val) + { + std::tm tm; + +#if defined(BOTAN_TARGET_OS_HAS_WIN32) + ::gmtime_s(&tm, &time_val); // Windows +#elif defined(BOTAN_TARGET_OS_HAS_POSIX1) + ::gmtime_r(&time_val, &tm); // Unix/SUSv2 +#else + std::tm* tm_p = std::gmtime(&time_val); + if (tm_p == nullptr) + throw Encoding_Error("time_t_to_tm could not convert"); + tm = *tm_p; +#endif + + return tm; + } + +/* +Portable replacement for timegm, _mkgmtime, etc + +Algorithm due to Howard Hinnant + +See https://howardhinnant.github.io/date_algorithms.html#days_from_civil +for details and explaination. The code is slightly simplified by our assumption +that the date is at least 1970, which is sufficient for our purposes. +*/ +size_t days_since_epoch(uint32_t year, uint32_t month, uint32_t day) + { + if(month <= 2) + year -= 1; + const uint32_t era = year / 400; + const uint32_t yoe = year - era * 400; // [0, 399] + const uint32_t doy = (153*(month + (month > 2 ? -3 : 9)) + 2)/5 + day-1; // [0, 365] + const uint32_t doe = yoe * 365 + yoe/4 - yoe/100 + doy; // [0, 146096] + return era * 146097 + doe - 719468; + } + +} + +std::chrono::system_clock::time_point calendar_point::to_std_timepoint() const + { + if(get_year() < 1970) + throw Invalid_Argument("calendar_point::to_std_timepoint() does not support years before 1970"); + + // 32 bit time_t ends at January 19, 2038 + // https://msdn.microsoft.com/en-us/library/2093ets1.aspx + // Throw after 2037 if 32 bit time_t is used + if(get_year() > 2037 && sizeof(std::time_t) == 4) + { + throw Invalid_Argument("calendar_point::to_std_timepoint() does not support years after 2037 on this system"); + } + else if(get_year() >= 2400) + { + // This upper bound is somewhat arbitrary + throw Invalid_Argument("calendar_point::to_std_timepoint() does not support years after 2400"); + } + + const uint64_t seconds_64 = (days_since_epoch(get_year(), get_month(), get_day()) * 86400) + + (get_hour() * 60 * 60) + (get_minutes() * 60) + get_seconds(); + + const time_t seconds_time_t = static_cast(seconds_64); + + if(seconds_64 - seconds_time_t != 0) + { + throw Invalid_Argument("calendar_point::to_std_timepoint time_t overflow"); + } + + return std::chrono::system_clock::from_time_t(seconds_time_t); + } + +std::string calendar_point::to_string() const + { + // desired format: --
T:: + std::stringstream output; + output << std::setfill('0') + << std::setw(4) << get_year() << "-" + << std::setw(2) << get_month() << "-" + << std::setw(2) << get_day() << "T" + << std::setw(2) << get_hour() << ":" + << std::setw(2) << get_minutes() << ":" + << std::setw(2) << get_seconds(); + return output.str(); + } + + +calendar_point calendar_value( + const std::chrono::system_clock::time_point& time_point) + { + std::tm tm = do_gmtime(std::chrono::system_clock::to_time_t(time_point)); + + return calendar_point(tm.tm_year + 1900, + tm.tm_mon + 1, + tm.tm_mday, + tm.tm_hour, + tm.tm_min, + tm.tm_sec); + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/utils/calendar.h b/src/libs/3rdparty/botan/src/lib/utils/calendar.h new file mode 100644 index 0000000000..83759070b8 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/utils/calendar.h @@ -0,0 +1,91 @@ +/* +* Calendar Functions +* (C) 1999-2009,2015 Jack Lloyd +* (C) 2015 Simon Warta (Kullo GmbH) +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_CALENDAR_H_ +#define BOTAN_CALENDAR_H_ + +#include +#include +#include + +namespace Botan { + +/** +* Struct representing a particular date and time +*/ +class BOTAN_PUBLIC_API(2,0) calendar_point + { + public: + + /** The year */ + uint32_t get_year() const { return year; } + + /** The month, 1 through 12 for Jan to Dec */ + uint32_t get_month() const { return month; } + + /** The day of the month, 1 through 31 (or 28 or 30 based on month */ + uint32_t get_day() const { return day; } + + /** Hour in 24-hour form, 0 to 23 */ + uint32_t get_hour() const { return hour; } + + /** Minutes in the hour, 0 to 60 */ + uint32_t get_minutes() const { return minutes; } + + /** Seconds in the minute, 0 to 60, but might be slightly + larger to deal with leap seconds on some systems + */ + uint32_t get_seconds() const { return seconds; } + + /** + * Initialize a calendar_point + * @param y the year + * @param mon the month + * @param d the day + * @param h the hour + * @param min the minute + * @param sec the second + */ + calendar_point(uint32_t y, uint32_t mon, uint32_t d, uint32_t h, uint32_t min, uint32_t sec) : + year(y), month(mon), day(d), hour(h), minutes(min), seconds(sec) {} + + /** + * Returns an STL timepoint object + */ + std::chrono::system_clock::time_point to_std_timepoint() const; + + /** + * Returns a human readable string of the struct's components. + * Formatting might change over time. Currently it is RFC339 'iso-date-time'. + */ + std::string to_string() const; + + BOTAN_DEPRECATED_PUBLIC_MEMBER_VARIABLES: + /* + The member variables are public for historical reasons. Use the get_xxx() functions + defined above. These members will be made private in a future major release. + */ + uint32_t year; + uint32_t month; + uint32_t day; + uint32_t hour; + uint32_t minutes; + uint32_t seconds; + }; + +/** +* Convert a time_point to a calendar_point +* @param time_point a time point from the system clock +* @return calendar_point object representing this time point +*/ +BOTAN_PUBLIC_API(2,0) calendar_point calendar_value( + const std::chrono::system_clock::time_point& time_point); + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/utils/charset.cpp b/src/libs/3rdparty/botan/src/lib/utils/charset.cpp new file mode 100644 index 0000000000..ca32c652db --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/utils/charset.cpp @@ -0,0 +1,283 @@ +/* +* Character Set Handling +* (C) 1999-2007 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include + +namespace Botan { + +namespace { + +void append_utf8_for(std::string& s, uint32_t c) + { + if(c >= 0xD800 && c < 0xE000) + throw Decoding_Error("Invalid Unicode character"); + + if(c <= 0x7F) + { + const uint8_t b0 = static_cast(c); + s.push_back(static_cast(b0)); + } + else if(c <= 0x7FF) + { + const uint8_t b0 = 0xC0 | static_cast(c >> 6); + const uint8_t b1 = 0x80 | static_cast(c & 0x3F); + s.push_back(static_cast(b0)); + s.push_back(static_cast(b1)); + } + else if(c <= 0xFFFF) + { + const uint8_t b0 = 0xE0 | static_cast(c >> 12); + const uint8_t b1 = 0x80 | static_cast((c >> 6) & 0x3F); + const uint8_t b2 = 0x80 | static_cast(c & 0x3F); + s.push_back(static_cast(b0)); + s.push_back(static_cast(b1)); + s.push_back(static_cast(b2)); + } + else if(c <= 0x10FFFF) + { + const uint8_t b0 = 0xF0 | static_cast(c >> 18); + const uint8_t b1 = 0x80 | static_cast((c >> 12) & 0x3F); + const uint8_t b2 = 0x80 | static_cast((c >> 6) & 0x3F); + const uint8_t b3 = 0x80 | static_cast(c & 0x3F); + s.push_back(static_cast(b0)); + s.push_back(static_cast(b1)); + s.push_back(static_cast(b2)); + s.push_back(static_cast(b3)); + } + else + throw Decoding_Error("Invalid Unicode character"); + + } + +} + +std::string ucs2_to_utf8(const uint8_t ucs2[], size_t len) + { + if(len % 2 != 0) + throw Decoding_Error("Invalid length for UCS-2 string"); + + const size_t chars = len / 2; + + std::string s; + for(size_t i = 0; i != chars; ++i) + { + const uint16_t c = load_be(ucs2, i); + append_utf8_for(s, c); + } + + return s; + } + +std::string ucs4_to_utf8(const uint8_t ucs4[], size_t len) + { + if(len % 4 != 0) + throw Decoding_Error("Invalid length for UCS-4 string"); + + const size_t chars = len / 4; + + std::string s; + for(size_t i = 0; i != chars; ++i) + { + const uint32_t c = load_be(ucs4, i); + append_utf8_for(s, c); + } + + return s; + } + +/* +* Convert from UTF-8 to ISO 8859-1 +*/ +std::string utf8_to_latin1(const std::string& utf8) + { + std::string iso8859; + + size_t position = 0; + while(position != utf8.size()) + { + const uint8_t c1 = static_cast(utf8[position++]); + + if(c1 <= 0x7F) + { + iso8859 += static_cast(c1); + } + else if(c1 >= 0xC0 && c1 <= 0xC7) + { + if(position == utf8.size()) + throw Decoding_Error("UTF-8: sequence truncated"); + + const uint8_t c2 = static_cast(utf8[position++]); + const uint8_t iso_char = ((c1 & 0x07) << 6) | (c2 & 0x3F); + + if(iso_char <= 0x7F) + throw Decoding_Error("UTF-8: sequence longer than needed"); + + iso8859 += static_cast(iso_char); + } + else + throw Decoding_Error("UTF-8: Unicode chars not in Latin1 used"); + } + + return iso8859; + } + +namespace Charset { + +namespace { + +/* +* Convert from UCS-2 to ISO 8859-1 +*/ +std::string ucs2_to_latin1(const std::string& ucs2) + { + if(ucs2.size() % 2 == 1) + throw Decoding_Error("UCS-2 string has an odd number of bytes"); + + std::string latin1; + + for(size_t i = 0; i != ucs2.size(); i += 2) + { + const uint8_t c1 = ucs2[i]; + const uint8_t c2 = ucs2[i+1]; + + if(c1 != 0) + throw Decoding_Error("UCS-2 has non-Latin1 characters"); + + latin1 += static_cast(c2); + } + + return latin1; + } + +/* +* Convert from ISO 8859-1 to UTF-8 +*/ +std::string latin1_to_utf8(const std::string& iso8859) + { + std::string utf8; + for(size_t i = 0; i != iso8859.size(); ++i) + { + const uint8_t c = static_cast(iso8859[i]); + + if(c <= 0x7F) + utf8 += static_cast(c); + else + { + utf8 += static_cast((0xC0 | (c >> 6))); + utf8 += static_cast((0x80 | (c & 0x3F))); + } + } + return utf8; + } + +} + +/* +* Perform character set transcoding +*/ +std::string transcode(const std::string& str, + Character_Set to, Character_Set from) + { + if(to == LOCAL_CHARSET) + to = LATIN1_CHARSET; + if(from == LOCAL_CHARSET) + from = LATIN1_CHARSET; + + if(to == from) + return str; + + if(from == LATIN1_CHARSET && to == UTF8_CHARSET) + return latin1_to_utf8(str); + if(from == UTF8_CHARSET && to == LATIN1_CHARSET) + return utf8_to_latin1(str); + if(from == UCS2_CHARSET && to == LATIN1_CHARSET) + return ucs2_to_latin1(str); + + throw Invalid_Argument("Unknown transcoding operation from " + + std::to_string(from) + " to " + std::to_string(to)); + } + +/* +* Check if a character represents a digit +*/ +bool is_digit(char c) + { + if(c == '0' || c == '1' || c == '2' || c == '3' || c == '4' || + c == '5' || c == '6' || c == '7' || c == '8' || c == '9') + return true; + return false; + } + +/* +* Check if a character represents whitespace +*/ +bool is_space(char c) + { + if(c == ' ' || c == '\t' || c == '\n' || c == '\r') + return true; + return false; + } + +/* +* Convert a character to a digit +*/ +uint8_t char2digit(char c) + { + switch(c) + { + case '0': return 0; + case '1': return 1; + case '2': return 2; + case '3': return 3; + case '4': return 4; + case '5': return 5; + case '6': return 6; + case '7': return 7; + case '8': return 8; + case '9': return 9; + } + + throw Invalid_Argument("char2digit: Input is not a digit character"); + } + +/* +* Convert a digit to a character +*/ +char digit2char(uint8_t b) + { + switch(b) + { + case 0: return '0'; + case 1: return '1'; + case 2: return '2'; + case 3: return '3'; + case 4: return '4'; + case 5: return '5'; + case 6: return '6'; + case 7: return '7'; + case 8: return '8'; + case 9: return '9'; + } + + throw Invalid_Argument("digit2char: Input is not a digit"); + } + +/* +* Case-insensitive character comparison +*/ +bool caseless_cmp(char a, char b) + { + return (std::tolower(static_cast(a)) == + std::tolower(static_cast(b))); + } + +} + +} diff --git a/src/libs/3rdparty/botan/src/lib/utils/charset.h b/src/libs/3rdparty/botan/src/lib/utils/charset.h new file mode 100644 index 0000000000..4913f0a5aa --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/utils/charset.h @@ -0,0 +1,78 @@ +/* +* Character Set Handling +* (C) 1999-2007 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_CHARSET_H_ +#define BOTAN_CHARSET_H_ + +#include +#include + +namespace Botan { + +/** +* Convert a sequence of UCS-2 (big endian) characters to a UTF-8 string +* This is used for ASN.1 BMPString type +* @param ucs2 the sequence of UCS-2 characters +* @param len length of ucs2 in bytes, must be a multiple of 2 +*/ +std::string BOTAN_UNSTABLE_API ucs2_to_utf8(const uint8_t ucs2[], size_t len); + +/** +* Convert a sequence of UCS-4 (big endian) characters to a UTF-8 string +* This is used for ASN.1 UniversalString type +* @param ucs4 the sequence of UCS-4 characters +* @param len length of ucs4 in bytes, must be a multiple of 4 +*/ +std::string BOTAN_UNSTABLE_API ucs4_to_utf8(const uint8_t ucs4[], size_t len); + +/** +* Convert a UTF-8 string to Latin-1 +* If a character outside the Latin-1 range is encountered, an exception is thrown. +*/ +std::string BOTAN_UNSTABLE_API utf8_to_latin1(const std::string& utf8); + +/** +* The different charsets (nominally) supported by Botan. +*/ +enum Character_Set { + LOCAL_CHARSET, + UCS2_CHARSET, + UTF8_CHARSET, + LATIN1_CHARSET +}; + +namespace Charset { + +/* +* Character set conversion - avoid this. +* For specific conversions, use the functions above like +* ucs2_to_utf8 and utf8_to_latin1 +* +* If you need something more complex than that, use a real library +* such as iconv, Boost.Locale, or ICU +*/ +std::string BOTAN_PUBLIC_API(2,0) + BOTAN_DEPRECATED("Avoid. See comment in header.") + transcode(const std::string& str, + Character_Set to, + Character_Set from); + +/* +* Simple character classifier functions +*/ +bool BOTAN_PUBLIC_API(2,0) is_digit(char c); +bool BOTAN_PUBLIC_API(2,0) is_space(char c); +bool BOTAN_PUBLIC_API(2,0) caseless_cmp(char x, char y); + +uint8_t BOTAN_PUBLIC_API(2,0) char2digit(char c); +char BOTAN_PUBLIC_API(2,0) digit2char(uint8_t b); + +} + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/utils/codec_base.h b/src/libs/3rdparty/botan/src/lib/utils/codec_base.h new file mode 100644 index 0000000000..e7dbc33e4c --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/utils/codec_base.h @@ -0,0 +1,165 @@ +/* +* Base Encoding and Decoding +* (C) 2018 Erwan Chaussy +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_BASE_CODEC_H_ +#define BOTAN_BASE_CODEC_H_ + +#include +#include +#include + +namespace Botan { + +/** +* Perform encoding using the base provided +* @param base object giving access to the encodings specifications +* @param output an array of at least base.encode_max_output bytes +* @param input is some binary data +* @param input_length length of input in bytes +* @param input_consumed is an output parameter which says how many +* bytes of input were actually consumed. If less than +* input_length, then the range input[consumed:length] +* should be passed in later along with more input. +* @param final_inputs true iff this is the last input, in which case + padding chars will be applied if needed +* @return number of bytes written to output +*/ +template +size_t base_encode(Base&& base, + char output[], + const uint8_t input[], + size_t input_length, + size_t& input_consumed, + bool final_inputs) + { + input_consumed = 0; + + const size_t encoding_bytes_in = base.encoding_bytes_in(); + const size_t encoding_bytes_out = base.encoding_bytes_out(); + + size_t input_remaining = input_length; + size_t output_produced = 0; + + while(input_remaining >= encoding_bytes_in) + { + base.encode(output + output_produced, input + input_consumed); + + input_consumed += encoding_bytes_in; + output_produced += encoding_bytes_out; + input_remaining -= encoding_bytes_in; + } + + if(final_inputs && input_remaining) + { + std::vector remainder(encoding_bytes_in, 0); + for(size_t i = 0; i != input_remaining; ++i) + { remainder[i] = input[input_consumed + i]; } + + base.encode(output + output_produced, remainder.data()); + + const size_t bits_consumed = base.bits_consumed(); + const size_t remaining_bits_before_padding = base.remaining_bits_before_padding(); + + size_t empty_bits = 8 * (encoding_bytes_in - input_remaining); + size_t index = output_produced + encoding_bytes_out - 1; + while(empty_bits >= remaining_bits_before_padding) + { + output[index--] = '='; + empty_bits -= bits_consumed; + } + + input_consumed += input_remaining; + output_produced += encoding_bytes_out; + } + + return output_produced; + } + +/** +* Perform decoding using the base provided +* @param base object giving access to the encodings specifications +* @param output an array of at least base.decode_max_output bytes +* @param input some base input +* @param input_length length of input in bytes +* @param input_consumed is an output parameter which says how many +* bytes of input were actually consumed. If less than +* input_length, then the range input[consumed:length] +* should be passed in later along with more input. +* @param final_inputs true iff this is the last input, in which case + padding is allowed +* @param ignore_ws ignore whitespace on input; if false, throw an + exception if whitespace is encountered +* @return number of bytes written to output +*/ +template +size_t base_decode(Base&& base, + uint8_t output[], + const char input[], + size_t input_length, + size_t& input_consumed, + bool final_inputs, + bool ignore_ws = true) + { + const size_t decoding_bytes_in = base.decoding_bytes_in(); + const size_t decoding_bytes_out = base.decoding_bytes_out(); + + uint8_t* out_ptr = output; + std::vector decode_buf(decoding_bytes_in, 0); + size_t decode_buf_pos = 0; + size_t final_truncate = 0; + + clear_mem(output, base.decode_max_output(input_length)); + + for(size_t i = 0; i != input_length; ++i) + { + const uint8_t bin = base.lookup_binary_value(input[i]); + + if(base.check_bad_char(bin, input[i], ignore_ws)) // May throw Invalid_Argument + { + decode_buf[decode_buf_pos] = bin; + ++decode_buf_pos; + } + + /* + * 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 < decoding_bytes_in; ++j) + { decode_buf[j] = 0; } + + final_truncate = decoding_bytes_in - decode_buf_pos; + decode_buf_pos = decoding_bytes_in; + } + } + + if(decode_buf_pos == decoding_bytes_in) + { + base.decode(out_ptr, decode_buf.data()); + + out_ptr += decoding_bytes_out; + decode_buf_pos = 0; + input_consumed = i+1; + } + } + + while(input_consumed < input_length && + base.lookup_binary_value(input[input_consumed]) == 0x80) + { + ++input_consumed; + } + + size_t written = (out_ptr - output) - base.bytes_to_remove(final_truncate); + + return written; + } + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/utils/compiler.h b/src/libs/3rdparty/botan/src/lib/utils/compiler.h new file mode 100644 index 0000000000..202b5cb755 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/utils/compiler.h @@ -0,0 +1,203 @@ +/* +* Define useful compiler-specific macros +* (C) 2016 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +/* This header is included in both C++ and C (via ffi.h) and should only + contain macro definitions. +*/ + +#ifndef BOTAN_UTIL_COMPILER_FLAGS_H_ +#define BOTAN_UTIL_COMPILER_FLAGS_H_ + +/* Should we use GCC-style inline assembler? */ +#if !defined(BOTAN_USE_GCC_INLINE_ASM) && (defined(__GNUC__) || defined(__xlc__) || defined(__SUNPRO_CC)) + #define BOTAN_USE_GCC_INLINE_ASM 1 +#endif + +/** +* Used to annotate API exports which are public and supported. +* These APIs will not be broken/removed unless strictly required for +* functionality or security, and only in new major versions. +* @param maj The major version this public API was released in +* @param min The minor version this public API was released in +*/ +#define BOTAN_PUBLIC_API(maj,min) BOTAN_DLL + +/** +* Used to annotate API exports which are public and can be used by +* applications if needed, but which are intentionally not documented, +* and which may change incompatibly in a future major version. +*/ +#define BOTAN_UNSTABLE_API BOTAN_DLL + +/** +* Used to annotate API exports which are exported but only for the +* purposes of testing. They should not be used by applications and +* may be removed or changed without notice. +*/ +#define BOTAN_TEST_API BOTAN_DLL + +/* +* Define BOTAN_GCC_VERSION +*/ +#ifdef __GNUC__ + #define BOTAN_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__ * 10 + __GNUC_PATCHLEVEL__) +#else + #define BOTAN_GCC_VERSION 0 +#endif + +/* +* Define BOTAN_CLANG_VERSION +*/ +#ifdef __clang__ + #define BOTAN_CLANG_VERSION (__clang_major__ * 10 + __clang_minor__) +#else + #define BOTAN_CLANG_VERSION 0 +#endif + +/* +* Define special macro when building under MSVC 2013 since there are +* many compiler workarounds required for that version. +*/ +#if defined(_MSC_VER) && (_MSC_VER < 1900) + #define BOTAN_BUILD_COMPILER_IS_MSVC_2013 +#endif + +/* +* Define BOTAN_FUNC_ISA +*/ +#if (defined(__GNUG__) && !defined(__clang__)) || (BOTAN_CLANG_VERSION > 38) + #define BOTAN_FUNC_ISA(isa) __attribute__ ((target(isa))) +#else + #define BOTAN_FUNC_ISA(isa) +#endif + +/* +* Define BOTAN_WARN_UNUSED_RESULT +*/ +#if defined(__GNUG__) || defined(__clang__) + #define BOTAN_WARN_UNUSED_RESULT __attribute__ ((warn_unused_result)) +#else + #define BOTAN_WARN_UNUSED_RESULT +#endif + +/* +* Define BOTAN_MALLOC_FN +*/ +#if defined(__GNUG__) || defined(__clang__) + #define BOTAN_MALLOC_FN __attribute__ ((malloc)) +#elif defined(_MSC_VER) + #define BOTAN_MALLOC_FN __declspec(restrict) +#else + #define BOTAN_MALLOC_FN +#endif + +/* +* Define BOTAN_DEPRECATED +*/ +#if !defined(BOTAN_NO_DEPRECATED_WARNINGS) + + #if defined(__clang__) + #define BOTAN_DEPRECATED(msg) __attribute__ ((deprecated)) + + #elif defined(_MSC_VER) + #define BOTAN_DEPRECATED(msg) __declspec(deprecated(msg)) + + #elif defined(__GNUG__) + // msg supported since GCC 4.5, earliest we support is 4.8 + #define BOTAN_DEPRECATED(msg) __attribute__ ((deprecated(msg))) + #endif + +#endif + +#if !defined(BOTAN_DEPRECATED) + #define BOTAN_DEPRECATED(msg) +#endif + +/* +* Define BOTAN_NORETURN +*/ +#if !defined(BOTAN_NORETURN) + + #if defined (__clang__) || defined (__GNUG__) + #define BOTAN_NORETURN __attribute__ ((__noreturn__)) + + #elif defined (_MSC_VER) + #define BOTAN_NORETURN __declspec(noreturn) + + #else + #define BOTAN_NORETURN + #endif + +#endif + +/* +* Define BOTAN_CURRENT_FUNCTION +*/ +#if defined(BOTAN_BUILD_COMPILER_IS_MSVC_2013) + #define BOTAN_CURRENT_FUNCTION __FUNCTION__ +#else + #define BOTAN_CURRENT_FUNCTION __func__ +#endif + +/* +* Define BOTAN_NOEXCEPT (for MSVC 2013) +*/ +#if defined(BOTAN_BUILD_COMPILER_IS_MSVC_2013) + // noexcept is not supported in VS 2013 + #include + #define BOTAN_NOEXCEPT _NOEXCEPT +#else + #define BOTAN_NOEXCEPT noexcept +#endif + +/* +* Define BOTAN_CONSTEXPR (for MSVC 2013) +*/ +#if defined(BOTAN_BUILD_COMPILER_IS_MSVC_2013) + #define BOTAN_CONSTEXPR /**/ +#else + #define BOTAN_CONSTEXPR constexpr +#endif + +/* +* Define BOTAN_ALIGNAS (for MSVC 2013) +*/ +#if defined(BOTAN_BUILD_COMPILER_IS_MSVC_2013) + #define BOTAN_ALIGNAS(n) /**/ +#else + #define BOTAN_ALIGNAS(n) alignas(n) +#endif + +/* +* Define BOTAN_PARALLEL_FOR +*/ +#if !defined(BOTAN_PARALLEL_FOR) + +#if defined(BOTAN_TARGET_HAS_OPENMP) + #define BOTAN_PARALLEL_FOR _Pragma("omp parallel for") for +#else + #define BOTAN_PARALLEL_FOR for +#endif + +#endif + +/* +* Define BOTAN_PARALLEL_SIMD_FOR +*/ +#if !defined(BOTAN_PARALLEL_SIMD_FOR) + +#if defined(BOTAN_TARGET_HAS_OPENMP) + #define BOTAN_PARALLEL_SIMD_FOR _Pragma("omp simd") for +#elif defined(BOTAN_BUILD_COMPILER_IS_GCC) && (BOTAN_GCC_VERSION >= 490) + #define BOTAN_PARALLEL_SIMD_FOR _Pragma("GCC ivdep") for +#else + #define BOTAN_PARALLEL_SIMD_FOR for +#endif + +#endif + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/utils/cpuid/cpuid.cpp b/src/libs/3rdparty/botan/src/lib/utils/cpuid/cpuid.cpp new file mode 100644 index 0000000000..3938c72423 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/utils/cpuid/cpuid.cpp @@ -0,0 +1,179 @@ +/* +* Runtime CPU detection +* (C) 2009,2010,2013,2017 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include +#include + +namespace Botan { + +uint64_t CPUID::g_processor_features = 0; +size_t CPUID::g_cache_line_size = BOTAN_TARGET_CPU_DEFAULT_CACHE_LINE_SIZE; +CPUID::Endian_status CPUID::g_endian_status = ENDIAN_UNKNOWN; + +bool CPUID::has_simd_32() + { +#if defined(BOTAN_TARGET_SUPPORTS_SSE2) + return CPUID::has_sse2(); +#elif defined(BOTAN_TARGET_SUPPORTS_ALTIVEC) + return CPUID::has_altivec(); +#elif defined(BOTAN_TARGET_SUPPORTS_NEON) + return CPUID::has_neon(); +#else + return true; +#endif + } + +//static +std::string CPUID::to_string() + { + std::vector flags; + +#define CPUID_PRINT(flag) do { if(has_##flag()) { flags.push_back(#flag); } } while(0) + +#if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY) + CPUID_PRINT(sse2); + CPUID_PRINT(ssse3); + CPUID_PRINT(sse41); + CPUID_PRINT(sse42); + CPUID_PRINT(avx2); + CPUID_PRINT(avx512f); + + CPUID_PRINT(rdtsc); + CPUID_PRINT(bmi1); + CPUID_PRINT(bmi2); + CPUID_PRINT(adx); + + CPUID_PRINT(aes_ni); + CPUID_PRINT(clmul); + CPUID_PRINT(rdrand); + CPUID_PRINT(rdseed); + CPUID_PRINT(intel_sha); +#endif + +#if defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY) + CPUID_PRINT(altivec); + CPUID_PRINT(ppc_crypto); +#endif + +#if defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY) + CPUID_PRINT(neon); + CPUID_PRINT(arm_sha1); + CPUID_PRINT(arm_sha2); + CPUID_PRINT(arm_aes); + CPUID_PRINT(arm_pmull); +#endif + +#undef CPUID_PRINT + + return string_join(flags, ' '); + } + +//static +void CPUID::print(std::ostream& o) + { + o << "CPUID flags: " << CPUID::to_string() << "\n"; + } + +//static +void CPUID::initialize() + { + g_processor_features = 0; + +#if defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY) || \ + defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY) || \ + defined(BOTAN_TARGET_CPU_IS_X86_FAMILY) + + g_processor_features = CPUID::detect_cpu_features(&g_cache_line_size); + +#endif + + g_endian_status = runtime_check_endian(); + g_processor_features |= CPUID::CPUID_INITIALIZED_BIT; + } + +//static +CPUID::Endian_status CPUID::runtime_check_endian() + { + // Check runtime endian + const uint32_t endian32 = 0x01234567; + const uint8_t* e8 = reinterpret_cast(&endian32); + + Endian_status endian = ENDIAN_UNKNOWN; + + if(e8[0] == 0x01 && e8[1] == 0x23 && e8[2] == 0x45 && e8[3] == 0x67) + { + endian = ENDIAN_BIG; + } + else if(e8[0] == 0x67 && e8[1] == 0x45 && e8[2] == 0x23 && e8[3] == 0x01) + { + endian = ENDIAN_LITTLE; + } + else + { + throw Internal_Error("Unexpected endian at runtime, neither big nor little"); + } + + // If we were compiled with a known endian, verify it matches at runtime +#if defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN) + BOTAN_ASSERT(endian == ENDIAN_LITTLE, "Build and runtime endian match"); +#elif defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN) + BOTAN_ASSERT(endian == ENDIAN_BIG, "Build and runtime endian match"); +#endif + + return endian; + } + +std::vector +CPUID::bit_from_string(const std::string& tok) + { +#if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY) + if(tok == "sse2" || tok == "simd") + return {Botan::CPUID::CPUID_SSE2_BIT}; + if(tok == "ssse3") + return {Botan::CPUID::CPUID_SSSE3_BIT}; + if(tok == "aesni") + return {Botan::CPUID::CPUID_AESNI_BIT}; + if(tok == "clmul") + return {Botan::CPUID::CPUID_CLMUL_BIT}; + if(tok == "avx2") + return {Botan::CPUID::CPUID_AVX2_BIT}; + if(tok == "sha") + return {Botan::CPUID::CPUID_SHA_BIT}; + if(tok == "bmi2") + return {Botan::CPUID::CPUID_BMI2_BIT}; + if(tok == "adx") + return {Botan::CPUID::CPUID_ADX_BIT}; + if(tok == "intel_sha") + return {Botan::CPUID::CPUID_SHA_BIT}; + +#elif defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY) + if(tok == "altivec" || tok == "simd") + return {Botan::CPUID::CPUID_ALTIVEC_BIT}; + +#elif defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY) + if(tok == "neon" || tok == "simd") + return {Botan::CPUID::CPUID_ARM_NEON_BIT}; + if(tok == "armv8sha1") + return {Botan::CPUID::CPUID_ARM_SHA1_BIT}; + if(tok == "armv8sha2") + return {Botan::CPUID::CPUID_ARM_SHA2_BIT}; + if(tok == "armv8aes") + return {Botan::CPUID::CPUID_ARM_AES_BIT}; + if(tok == "armv8pmull") + return {Botan::CPUID::CPUID_ARM_PMULL_BIT}; + +#else + BOTAN_UNUSED(tok); +#endif + + return {}; + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/utils/cpuid/cpuid.h b/src/libs/3rdparty/botan/src/lib/utils/cpuid/cpuid.h new file mode 100644 index 0000000000..633824a6cc --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/utils/cpuid/cpuid.h @@ -0,0 +1,327 @@ +/* +* Runtime CPU detection +* (C) 2009,2010,2013,2017 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_CPUID_H_ +#define BOTAN_CPUID_H_ + +#include +#include +#include +#include + +namespace Botan { + +/** +* A class handling runtime CPU feature detection. It is limited to +* just the features necessary to implement CPU specific code in Botan, +* rather than being a general purpose utility. +* +* This class supports: +* +* - x86 features using CPUID. x86 is also the only processor with +* accurate cache line detection currently. +* +* - PowerPC AltiVec detection on Linux, NetBSD, OpenBSD, and Darwin +* +* - ARM NEON and crypto extensions detection. On Linux and Android +* systems which support getauxval, that is used to access CPU +* feature information. Otherwise a relatively portable but +* thread-unsafe mechanism involving executing probe functions which +* catching SIGILL signal is used. +*/ +class BOTAN_PUBLIC_API(2,1) CPUID final + { + public: + /** + * Probe the CPU and see what extensions are supported + */ + static void initialize(); + + static bool has_simd_32(); + + /** + * Deprecated equivalent to + * o << "CPUID flags: " << CPUID::to_string() << "\n"; + */ + BOTAN_DEPRECATED("Use CPUID::to_string") + static void print(std::ostream& o); + + /** + * Return a possibly empty string containing list of known CPU + * extensions. Each name will be seperated by a space, and the ordering + * will be arbitrary. This list only contains values that are useful to + * Botan (for example FMA instructions are not checked). + * + * Example outputs "sse2 ssse3 rdtsc", "neon arm_aes", "altivec" + */ + static std::string to_string(); + + /** + * Return a best guess of the cache line size + */ + static size_t cache_line_size() + { + if(g_processor_features == 0) + { + initialize(); + } + return g_cache_line_size; + } + + static bool is_little_endian() + { + return endian_status() == ENDIAN_LITTLE; + } + + static bool is_big_endian() + { + return endian_status() == ENDIAN_BIG; + } + + enum CPUID_bits : uint64_t { +#if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY) + // These values have no relation to cpuid bitfields + + // SIMD instruction sets + CPUID_SSE2_BIT = (1ULL << 0), + CPUID_SSSE3_BIT = (1ULL << 1), + CPUID_SSE41_BIT = (1ULL << 2), + CPUID_SSE42_BIT = (1ULL << 3), + CPUID_AVX2_BIT = (1ULL << 4), + CPUID_AVX512F_BIT = (1ULL << 5), + + // Misc useful instructions + CPUID_RDTSC_BIT = (1ULL << 10), + CPUID_BMI2_BIT = (1ULL << 11), + CPUID_ADX_BIT = (1ULL << 12), + CPUID_BMI1_BIT = (1ULL << 13), + + // Crypto-specific ISAs + CPUID_AESNI_BIT = (1ULL << 16), + CPUID_CLMUL_BIT = (1ULL << 17), + CPUID_RDRAND_BIT = (1ULL << 18), + CPUID_RDSEED_BIT = (1ULL << 19), + CPUID_SHA_BIT = (1ULL << 20), +#endif + +#if defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY) + CPUID_ALTIVEC_BIT = (1ULL << 0), + CPUID_PPC_CRYPTO_BIT = (1ULL << 1), +#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), +#endif + + CPUID_INITIALIZED_BIT = (1ULL << 63) + }; + +#if defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY) + /** + * Check if the processor supports AltiVec/VMX + */ + static bool has_altivec() + { return has_cpuid_bit(CPUID_ALTIVEC_BIT); } + + /** + * Check if the processor supports POWER8 crypto extensions + */ + static bool has_ppc_crypto() + { return has_cpuid_bit(CPUID_PPC_CRYPTO_BIT); } + +#endif + +#if defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY) + /** + * Check if the processor supports NEON SIMD + */ + static bool has_neon() + { return has_cpuid_bit(CPUID_ARM_NEON_BIT); } + + /** + * Check if the processor supports ARMv8 SHA1 + */ + static bool has_arm_sha1() + { return has_cpuid_bit(CPUID_ARM_SHA1_BIT); } + + /** + * Check if the processor supports ARMv8 SHA2 + */ + static bool has_arm_sha2() + { return has_cpuid_bit(CPUID_ARM_SHA2_BIT); } + + /** + * Check if the processor supports ARMv8 AES + */ + static bool has_arm_aes() + { return has_cpuid_bit(CPUID_ARM_AES_BIT); } + + /** + * Check if the processor supports ARMv8 PMULL + */ + static bool has_arm_pmull() + { return has_cpuid_bit(CPUID_ARM_PMULL_BIT); } +#endif + +#if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY) + + /** + * Check if the processor supports RDTSC + */ + static bool has_rdtsc() + { return has_cpuid_bit(CPUID_RDTSC_BIT); } + + /** + * Check if the processor supports SSE2 + */ + static bool has_sse2() + { return has_cpuid_bit(CPUID_SSE2_BIT); } + + /** + * Check if the processor supports SSSE3 + */ + static bool has_ssse3() + { return has_cpuid_bit(CPUID_SSSE3_BIT); } + + /** + * Check if the processor supports SSE4.1 + */ + static bool has_sse41() + { return has_cpuid_bit(CPUID_SSE41_BIT); } + + /** + * Check if the processor supports SSE4.2 + */ + static bool has_sse42() + { return has_cpuid_bit(CPUID_SSE42_BIT); } + + /** + * Check if the processor supports AVX2 + */ + static bool has_avx2() + { return has_cpuid_bit(CPUID_AVX2_BIT); } + + /** + * Check if the processor supports AVX-512F + */ + static bool has_avx512f() + { return has_cpuid_bit(CPUID_AVX512F_BIT); } + + /** + * Check if the processor supports BMI1 + */ + static bool has_bmi1() + { return has_cpuid_bit(CPUID_BMI1_BIT); } + + /** + * Check if the processor supports BMI2 + */ + static bool has_bmi2() + { return has_cpuid_bit(CPUID_BMI2_BIT); } + + /** + * Check if the processor supports AES-NI + */ + static bool has_aes_ni() + { return has_cpuid_bit(CPUID_AESNI_BIT); } + + /** + * Check if the processor supports CLMUL + */ + static bool has_clmul() + { return has_cpuid_bit(CPUID_CLMUL_BIT); } + + /** + * Check if the processor supports Intel SHA extension + */ + static bool has_intel_sha() + { return has_cpuid_bit(CPUID_SHA_BIT); } + + /** + * Check if the processor supports ADX extension + */ + static bool has_adx() + { return has_cpuid_bit(CPUID_ADX_BIT); } + + /** + * Check if the processor supports RDRAND + */ + static bool has_rdrand() + { return has_cpuid_bit(CPUID_RDRAND_BIT); } + + /** + * Check if the processor supports RDSEED + */ + static bool has_rdseed() + { return has_cpuid_bit(CPUID_RDSEED_BIT); } +#endif + + /* + * Clear a CPUID bit + * Call CPUID::initialize to reset + * + * This is only exposed for testing, don't use unless you know + * what you are doing. + */ + static void clear_cpuid_bit(CPUID_bits bit) + { + const uint64_t mask = ~(static_cast(bit)); + g_processor_features &= mask; + } + + /* + * Don't call this function, use CPUID::has_xxx above + * It is only exposed for the tests. + */ + static bool has_cpuid_bit(CPUID_bits elem) + { + if(g_processor_features == 0) + initialize(); + + const uint64_t elem64 = static_cast(elem); + return ((g_processor_features & elem64) == elem64); + } + + static std::vector bit_from_string(const std::string& tok); + private: + enum Endian_status : uint32_t { + ENDIAN_UNKNOWN = 0x00000000, + ENDIAN_BIG = 0x01234567, + ENDIAN_LITTLE = 0x67452301, + }; + +#if defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY) || \ + defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY) || \ + defined(BOTAN_TARGET_CPU_IS_X86_FAMILY) + + static uint64_t detect_cpu_features(size_t* cache_line_size); + +#endif + + static Endian_status runtime_check_endian(); + + static Endian_status endian_status() + { + if(g_endian_status == ENDIAN_UNKNOWN) + { + g_endian_status = runtime_check_endian(); + } + return g_endian_status; + } + + static uint64_t g_processor_features; + static size_t g_cache_line_size; + static Endian_status g_endian_status; + }; + +} + +#endif 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 new file mode 100644 index 0000000000..39b6db652e --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/utils/cpuid/cpuid_arm.cpp @@ -0,0 +1,214 @@ +/* +* Runtime CPU detection for ARM +* (C) 2009,2010,2013,2017 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include + +#if defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY) + +#if defined(BOTAN_TARGET_OS_HAS_GETAUXVAL) + #include + +#elif defined(BOTAN_TARGET_OS_IS_IOS) + #include + #include + +#else + #include + +#endif + +#endif + +namespace Botan { + +#if defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY) + +#if defined(BOTAN_TARGET_OS_IS_IOS) + +namespace { + +uint64_t flags_by_ios_machine_type(const std::string& machine) + { + /* + * This relies on a map of known machine names to features. This + * will quickly grow out of date as new products are introduced, but + * is apparently the best we can do for iOS. + */ + + struct version_info { + std::string name; + size_t min_version_neon; + size_t min_version_armv8; + }; + + static const version_info min_versions[] = { + { "iPhone", 2, 6 }, + { "iPad", 1, 4 }, + { "iPod", 4, 7 }, + { "AppleTV", 2, 5 }, + }; + + if(machine.size() < 3) + return 0; + + auto comma = machine.find(','); + + // Simulator, or something we don't know about + if(comma == std::string::npos) + return 0; + + std::string product = machine.substr(0, comma); + + size_t version = 0; + size_t place = 1; + while(product.size() > 1 && ::isdigit(product.back())) + { + const size_t digit = product.back() - '0'; + version += digit * place; + place *= 10; + product.pop_back(); + } + + if(version == 0) + return 0; + + for(const version_info& info : min_versions) + { + if(info.name != product) + continue; + + if(version >= info.min_version_armv8) + { + return CPUID::CPUID_ARM_AES_BIT | + CPUID::CPUID_ARM_PMULL_BIT | + CPUID::CPUID_ARM_SHA1_BIT | + CPUID::CPUID_ARM_SHA2_BIT | + CPUID::CPUID_ARM_NEON_BIT; + } + + if(version >= info.min_version_neon) + return CPUID::CPUID_ARM_NEON_BIT; + } + + // Some other product we don't know about + return 0; + } + +} + +#endif + +uint64_t CPUID::detect_cpu_features(size_t* cache_line_size) + { + uint64_t detected_features = 0; + +#if defined(BOTAN_TARGET_OS_HAS_GETAUXVAL) + /* + * On systems with getauxval these bits should normally be defined + * in bits/auxv.h but some buggy? glibc installs seem to miss them. + * These following values are all fixed, for the Linux ELF format, + * so we just hardcode them in ARM_hwcap_bit enum. + */ + + enum ARM_hwcap_bit { +#if defined(BOTAN_TARGET_ARCH_IS_ARM32) + NEON_bit = (1 << 12), + AES_bit = (1 << 0), + PMULL_bit = (1 << 1), + SHA1_bit = (1 << 2), + SHA2_bit = (1 << 3), + + ARCH_hwcap_neon = 16, // AT_HWCAP + ARCH_hwcap_crypto = 26, // AT_HWCAP2 +#elif defined(BOTAN_TARGET_ARCH_IS_ARM64) + NEON_bit = (1 << 1), + AES_bit = (1 << 3), + PMULL_bit = (1 << 4), + SHA1_bit = (1 << 5), + SHA2_bit = (1 << 6), + + ARCH_hwcap_neon = 16, // AT_HWCAP + ARCH_hwcap_crypto = 16, // AT_HWCAP +#endif + }; + +#if defined(AT_DCACHEBSIZE) + const unsigned long dcache_line = ::getauxval(AT_DCACHEBSIZE); + + // plausibility check + if(dcache_line == 32 || dcache_line == 64 || dcache_line == 128) + *cache_line_size = static_cast(dcache_line); +#endif + + const unsigned long hwcap_neon = ::getauxval(ARM_hwcap_bit::ARCH_hwcap_neon); + if(hwcap_neon & ARM_hwcap_bit::NEON_bit) + detected_features |= CPUID::CPUID_ARM_NEON_BIT; + + /* + On aarch64 this ends up calling getauxval twice with AT_HWCAP + It doesn't seem worth optimizing this out, since getauxval is + just reading a field in the ELF header. + */ + const unsigned long hwcap_crypto = ::getauxval(ARM_hwcap_bit::ARCH_hwcap_crypto); + if(hwcap_crypto & ARM_hwcap_bit::AES_bit) + detected_features |= CPUID::CPUID_ARM_AES_BIT; + if(hwcap_crypto & ARM_hwcap_bit::PMULL_bit) + detected_features |= CPUID::CPUID_ARM_PMULL_BIT; + if(hwcap_crypto & ARM_hwcap_bit::SHA1_bit) + detected_features |= CPUID::CPUID_ARM_SHA1_BIT; + if(hwcap_crypto & ARM_hwcap_bit::SHA2_bit) + detected_features |= CPUID::CPUID_ARM_SHA2_BIT; + +#elif defined(BOTAN_TARGET_OS_IS_IOS) + + char machine[64] = { 0 }; + size_t size = sizeof(machine) - 1; + ::sysctlbyname("hw.machine", machine, &size, nullptr, 0); + + detected_features = flags_by_ios_machine_type(machine); + +#elif defined(BOTAN_USE_GCC_INLINE_ASM) && defined(BOTAN_TARGET_ARCH_IS_ARM64) + + /* + No getauxval API available, fall back on probe functions. We only + bother with Aarch64 here to simplify the code and because going to + extreme contortions to support detect NEON on devices that probably + don't support it doesn't seem worthwhile. + + NEON registers v0-v7 are caller saved in Aarch64 + */ + + auto neon_probe = []() -> int { asm("and v0.16b, v0.16b, v0.16b"); return 1; }; + auto aes_probe = []() -> int { asm(".word 0x4e284800"); return 1; }; + auto pmull_probe = []() -> int { asm(".word 0x0ee0e000"); return 1; }; + auto sha1_probe = []() -> int { asm(".word 0x5e280800"); return 1; }; + auto sha2_probe = []() -> int { asm(".word 0x5e282800"); return 1; }; + + // Only bother running the crypto detection if we found NEON + + if(OS::run_cpu_instruction_probe(neon_probe) == 1) + { + detected_features |= CPUID::CPUID_ARM_NEON_BIT; + + if(OS::run_cpu_instruction_probe(aes_probe) == 1) + detected_features |= CPUID::CPUID_ARM_AES_BIT; + if(OS::run_cpu_instruction_probe(pmull_probe) == 1) + detected_features |= CPUID::CPUID_ARM_PMULL_BIT; + if(OS::run_cpu_instruction_probe(sha1_probe) == 1) + detected_features |= CPUID::CPUID_ARM_SHA1_BIT; + if(OS::run_cpu_instruction_probe(sha2_probe) == 1) + detected_features |= CPUID::CPUID_ARM_SHA2_BIT; + } + +#endif + + return detected_features; + } + +#endif + +} diff --git a/src/libs/3rdparty/botan/src/lib/utils/cpuid/cpuid_ppc.cpp b/src/libs/3rdparty/botan/src/lib/utils/cpuid/cpuid_ppc.cpp new file mode 100644 index 0000000000..43b6847852 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/utils/cpuid/cpuid_ppc.cpp @@ -0,0 +1,129 @@ +/* +* Runtime CPU detection for POWER/PowerPC +* (C) 2009,2010,2013,2017 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include + +#if defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY) + +/* +* On Darwin and OpenBSD ppc, use sysctl to detect AltiVec +*/ +#if defined(BOTAN_TARGET_OS_IS_DARWIN) + #include +#elif defined(BOTAN_TARGET_OS_IS_OPENBSD) + #include + #include + #include +#elif defined(BOTAN_TARGET_OS_HAS_GETAUXVAL) + #include +#endif + +#endif + +namespace Botan { + +#if defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY) + +/* +* PowerPC specific block: check for AltiVec using either +* sysctl or by reading processor version number register. +*/ +uint64_t CPUID::detect_cpu_features(size_t* cache_line_size) + { + BOTAN_UNUSED(cache_line_size); + +#if defined(BOTAN_TARGET_OS_IS_DARWIN) || defined(BOTAN_TARGET_OS_IS_OPENBSD) + // On Darwin/OS X and OpenBSD, use sysctl + + int sels[2] = { +#if defined(BOTAN_TARGET_OS_IS_OPENBSD) + CTL_MACHDEP, CPU_ALTIVEC +#else + CTL_HW, HW_VECTORUNIT +#endif + }; + + int vector_type = 0; + size_t length = sizeof(vector_type); + int error = ::sysctl(sels, 2, &vector_type, &length, NULL, 0); + + if(error == 0 && vector_type > 0) + return CPUID::CPUID_ALTIVEC_BIT; + +#elif defined(BOTAN_TARGET_OS_HAS_GETAUXVAL) && defined(BOTAN_TARGET_ARCH_IS_PPC64) + + enum PPC_hwcap_bit { + ALTIVEC_bit = (1 << 28), + CRYPTO_bit = (1 << 25), + + ARCH_hwcap_altivec = 16, // AT_HWCAP + ARCH_hwcap_crypto = 26, // AT_HWCAP2 + }; + + uint64_t detected_features = 0; + + const unsigned long hwcap_altivec = ::getauxval(PPC_hwcap_bit::ARCH_hwcap_altivec); + if(hwcap_altivec & PPC_hwcap_bit::ALTIVEC_bit) + detected_features |= CPUID::CPUID_ALTIVEC_BIT; + + const unsigned long hwcap_crypto = ::getauxval(PPC_hwcap_bit::ARCH_hwcap_crypto); + if(hwcap_crypto & PPC_hwcap_bit::CRYPTO_bit) + detected_features |= CPUID::CPUID_PPC_CRYPTO_BIT; + + return detected_features; + +#else + + /* + On PowerPC, MSR 287 is PVR, the Processor Version Number + Normally it is only accessible to ring 0, but Linux and NetBSD + (others, too, maybe?) will trap and emulate it for us. + */ + + int pvr = OS::run_cpu_instruction_probe([]() -> int { + uint32_t pvr = 0; + asm volatile("mfspr %0, 287" : "=r" (pvr)); + // Top 16 bits suffice to identify the model + return static_cast(pvr >> 16); + }); + + if(pvr > 0) + { + const uint16_t ALTIVEC_PVR[] = { + 0x003E, // IBM POWER6 + 0x003F, // IBM POWER7 + 0x004A, // IBM POWER7p + 0x004D, // IBM POWER8 + 0x004B, // IBM POWER8E + 0x000C, // G4-7400 + 0x0039, // G5 970 + 0x003C, // G5 970FX + 0x0044, // G5 970MP + 0x0070, // Cell PPU + 0, // end + }; + + for(size_t i = 0; ALTIVEC_PVR[i]; ++i) + { + if(pvr == ALTIVEC_PVR[i]) + return CPUID::CPUID_ALTIVEC_BIT; + } + + return 0; + } + + // TODO try direct instruction probing + +#endif + + return 0; + } + +#endif + +} diff --git a/src/libs/3rdparty/botan/src/lib/utils/cpuid/cpuid_x86.cpp b/src/libs/3rdparty/botan/src/lib/utils/cpuid/cpuid_x86.cpp new file mode 100644 index 0000000000..5387a801ec --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/utils/cpuid/cpuid_x86.cpp @@ -0,0 +1,178 @@ +/* +* Runtime CPU detection for x86 +* (C) 2009,2010,2013,2017 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include + +#if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY) + +#if defined(BOTAN_BUILD_COMPILER_IS_MSVC) + #include +#elif defined(BOTAN_BUILD_COMPILER_IS_INTEL) + #include +#elif defined(BOTAN_BUILD_COMPILER_IS_GCC) || defined(BOTAN_BUILD_COMPILER_IS_CLANG) + #include +#endif + +#endif + +namespace Botan { + +#if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY) + +uint64_t CPUID::detect_cpu_features(size_t* cache_line_size) + { +#if defined(BOTAN_BUILD_COMPILER_IS_MSVC) + #define X86_CPUID(type, out) do { __cpuid((int*)out, type); } while(0) + #define X86_CPUID_SUBLEVEL(type, level, out) do { __cpuidex((int*)out, type, level); } while(0) + +#elif defined(BOTAN_BUILD_COMPILER_IS_INTEL) + #define X86_CPUID(type, out) do { __cpuid(out, type); } while(0) + #define X86_CPUID_SUBLEVEL(type, level, out) do { __cpuidex((int*)out, type, level); } while(0) + +#elif defined(BOTAN_TARGET_ARCH_IS_X86_64) && defined(BOTAN_USE_GCC_INLINE_ASM) + #define X86_CPUID(type, out) \ + asm("cpuid\n\t" : "=a" (out[0]), "=b" (out[1]), "=c" (out[2]), "=d" (out[3]) \ + : "0" (type)) + + #define X86_CPUID_SUBLEVEL(type, level, out) \ + asm("cpuid\n\t" : "=a" (out[0]), "=b" (out[1]), "=c" (out[2]), "=d" (out[3]) \ + : "0" (type), "2" (level)) + +#elif defined(BOTAN_BUILD_COMPILER_IS_GCC) || defined(BOTAN_BUILD_COMPILER_IS_CLANG) + #define X86_CPUID(type, out) do { __get_cpuid(type, out, out+1, out+2, out+3); } while(0) + + #define X86_CPUID_SUBLEVEL(type, level, out) \ + do { __cpuid_count(type, level, out[0], out[1], out[2], out[3]); } while(0) +#else + #warning "No way of calling x86 cpuid instruction for this compiler" + #define X86_CPUID(type, out) do { clear_mem(out, 4); } while(0) + #define X86_CPUID_SUBLEVEL(type, level, out) do { clear_mem(out, 4); } while(0) +#endif + + uint64_t features_detected = 0; + uint32_t cpuid[4] = { 0 }; + + // CPUID 0: vendor identification, max sublevel + X86_CPUID(0, cpuid); + + const uint32_t max_supported_sublevel = cpuid[0]; + + const uint32_t INTEL_CPUID[3] = { 0x756E6547, 0x6C65746E, 0x49656E69 }; + const uint32_t AMD_CPUID[3] = { 0x68747541, 0x444D4163, 0x69746E65 }; + const bool is_intel = same_mem(cpuid + 1, INTEL_CPUID, 3); + const bool is_amd = same_mem(cpuid + 1, AMD_CPUID, 3); + + if(max_supported_sublevel >= 1) + { + // CPUID 1: feature bits + X86_CPUID(1, cpuid); + const uint64_t flags0 = (static_cast(cpuid[2]) << 32) | cpuid[3]; + + enum x86_CPUID_1_bits : uint64_t { + RDTSC = (1ULL << 4), + SSE2 = (1ULL << 26), + CLMUL = (1ULL << 33), + SSSE3 = (1ULL << 41), + SSE41 = (1ULL << 51), + SSE42 = (1ULL << 52), + AESNI = (1ULL << 57), + RDRAND = (1ULL << 62) + }; + + if(flags0 & x86_CPUID_1_bits::RDTSC) + features_detected |= CPUID::CPUID_RDTSC_BIT; + if(flags0 & x86_CPUID_1_bits::SSE2) + features_detected |= CPUID::CPUID_SSE2_BIT; + if(flags0 & x86_CPUID_1_bits::CLMUL) + features_detected |= CPUID::CPUID_CLMUL_BIT; + if(flags0 & x86_CPUID_1_bits::SSSE3) + features_detected |= CPUID::CPUID_SSSE3_BIT; + if(flags0 & x86_CPUID_1_bits::SSE41) + features_detected |= CPUID::CPUID_SSE41_BIT; + if(flags0 & x86_CPUID_1_bits::SSE42) + features_detected |= CPUID::CPUID_SSE42_BIT; + if(flags0 & x86_CPUID_1_bits::AESNI) + features_detected |= CPUID::CPUID_AESNI_BIT; + if(flags0 & x86_CPUID_1_bits::RDRAND) + features_detected |= CPUID::CPUID_RDRAND_BIT; + } + + if(is_intel) + { + // Intel cache line size is in cpuid(1) output + *cache_line_size = 8 * get_byte(2, cpuid[1]); + } + else if(is_amd) + { + // AMD puts it in vendor zone + X86_CPUID(0x80000005, cpuid); + *cache_line_size = get_byte(3, cpuid[2]); + } + + if(max_supported_sublevel >= 7) + { + clear_mem(cpuid, 4); + X86_CPUID_SUBLEVEL(7, 0, cpuid); + + enum x86_CPUID_7_bits : uint64_t { + BMI1 = (1ULL << 3), + AVX2 = (1ULL << 5), + BMI2 = (1ULL << 8), + AVX512F = (1ULL << 16), + RDSEED = (1ULL << 18), + ADX = (1ULL << 19), + SHA = (1ULL << 29), + }; + uint64_t flags7 = (static_cast(cpuid[2]) << 32) | cpuid[1]; + + if(flags7 & x86_CPUID_7_bits::AVX2) + features_detected |= CPUID::CPUID_AVX2_BIT; + if(flags7 & x86_CPUID_7_bits::BMI1) + { + features_detected |= CPUID::CPUID_BMI1_BIT; + /* + We only set the BMI2 bit if BMI1 is also supported, so BMI2 + code can safely use both extensions. No known processor + implements BMI2 but not BMI1. + */ + if(flags7 & x86_CPUID_7_bits::BMI2) + features_detected |= CPUID::CPUID_BMI2_BIT; + } + + if(flags7 & x86_CPUID_7_bits::AVX512F) + features_detected |= CPUID::CPUID_AVX512F_BIT; + if(flags7 & x86_CPUID_7_bits::RDSEED) + features_detected |= CPUID::CPUID_RDSEED_BIT; + if(flags7 & x86_CPUID_7_bits::ADX) + features_detected |= CPUID::CPUID_ADX_BIT; + if(flags7 & x86_CPUID_7_bits::SHA) + features_detected |= CPUID::CPUID_SHA_BIT; + } + +#undef X86_CPUID +#undef X86_CPUID_SUBLEVEL + + /* + * If we don't have access to CPUID, we can still safely assume that + * any x86-64 processor has SSE2 and RDTSC + */ +#if defined(BOTAN_TARGET_ARCH_IS_X86_64) + if(features_detected == 0) + { + features_detected |= CPUID::CPUID_SSE2_BIT; + features_detected |= CPUID::CPUID_RDTSC_BIT; + } +#endif + + return features_detected; + } + +#endif + +} diff --git a/src/libs/3rdparty/botan/src/lib/utils/cpuid/info.txt b/src/libs/3rdparty/botan/src/lib/utils/cpuid/info.txt new file mode 100644 index 0000000000..987d7eae4d --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/utils/cpuid/info.txt @@ -0,0 +1,7 @@ + +CPUID -> 20170917 + + + +cpuid.h + diff --git a/src/libs/3rdparty/botan/src/lib/utils/ct_utils.h b/src/libs/3rdparty/botan/src/lib/utils/ct_utils.h new file mode 100644 index 0000000000..0132678742 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/utils/ct_utils.h @@ -0,0 +1,208 @@ +/* +* Functions for constant time operations on data and testing of +* constant time annotations using valgrind. +* +* For more information about constant time programming see +* Wagner, Molnar, et al "The Program Counter Security Model" +* +* (C) 2010 Falko Strenzke +* (C) 2015,2016 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_TIMING_ATTACK_CM_H_ +#define BOTAN_TIMING_ATTACK_CM_H_ + +#include +#include + +#if defined(BOTAN_HAS_VALGRIND) + #include +#endif + +namespace Botan { + +namespace CT { + +/** +* Use valgrind to mark the contents of memory as being undefined. +* Valgrind will accept operations which manipulate undefined values, +* but will warn if an undefined value is used to decided a conditional +* jump or a load/store address. So if we poison all of our inputs we +* can confirm that the operations in question are truly const time +* when compiled by whatever compiler is in use. +* +* Even better, the VALGRIND_MAKE_MEM_* macros work even when the +* program is not run under valgrind (though with a few cycles of +* overhead, which is unfortunate in final binaries as these +* annotations tend to be used in fairly important loops). +* +* This approach was first used in ctgrind (https://github.com/agl/ctgrind) +* but calling the valgrind mecheck API directly works just as well and +* doesn't require a custom patched valgrind. +*/ +template +inline void poison(const T* p, size_t n) + { +#if defined(BOTAN_HAS_VALGRIND) + VALGRIND_MAKE_MEM_UNDEFINED(p, n * sizeof(T)); +#else + BOTAN_UNUSED(p); + BOTAN_UNUSED(n); +#endif + } + +template +inline void unpoison(const T* p, size_t n) + { +#if defined(BOTAN_HAS_VALGRIND) + VALGRIND_MAKE_MEM_DEFINED(p, n * sizeof(T)); +#else + BOTAN_UNUSED(p); + BOTAN_UNUSED(n); +#endif + } + +template +inline void unpoison(T& p) + { +#if defined(BOTAN_HAS_VALGRIND) + VALGRIND_MAKE_MEM_DEFINED(&p, sizeof(T)); +#else + BOTAN_UNUSED(p); +#endif + } + +/* +* T should be an unsigned machine integer type +* Expand to a mask used for other operations +* @param in an integer +* @return If n is zero, returns zero. Otherwise +* returns a T with all bits set for use as a mask with +* select. +*/ +template +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(r >> i); + } + r &= 1; + r = static_cast(~(r - 1)); + return r; + } + +template +inline T expand_top_bit(T a) + { + return expand_mask(a >> (sizeof(T)*8-1)); + } + +template +inline T select(T mask, T from0, T from1) + { + return static_cast((from0 & mask) | (from1 & ~mask)); + } + +template +inline T select2(T mask0, T val0, T mask1, T val1, T val2) + { + return select(mask0, val0, select(mask1, val1, val2)); + } + +template +inline T select3(T mask0, T val0, T mask1, T val1, T mask2, T val2, T val3) + { + return select2(mask0, val0, mask1, val1, select(mask2, val2, val3)); + } + +template +inline ValT val_or_zero(PredT pred_val, ValT val) + { + return select(CT::expand_mask(pred_val), val, static_cast(0)); + } + +template +inline T is_zero(T x) + { + return static_cast(~expand_mask(x)); + } + +template +inline T is_equal(T x, T y) + { + return is_zero(x ^ y); + } + +template +inline T is_less(T a, T b) + { + return expand_top_bit(a ^ ((a^b) | ((a-b)^a))); + } + +template +inline T is_lte(T a, T b) + { + return CT::is_less(a, b) | CT::is_equal(a, b); + } + +template +inline T conditional_copy_mem(T value, + T* to, + const T* from0, + const T* from1, + size_t elems) + { + const T mask = CT::expand_mask(value); + + for(size_t i = 0; i != elems; ++i) + { + to[i] = CT::select(mask, from0[i], from1[i]); + } + + return mask; + } + +template +inline void cond_zero_mem(T cond, + T* array, + size_t elems) + { + const T mask = CT::expand_mask(cond); + const T zero(0); + + for(size_t i = 0; i != elems; ++i) + { + array[i] = CT::select(mask, zero, array[i]); + } + } + +inline secure_vector strip_leading_zeros(const uint8_t in[], size_t length) + { + size_t leading_zeros = 0; + + uint8_t only_zeros = 0xFF; + + for(size_t i = 0; i != length; ++i) + { + only_zeros = only_zeros & CT::is_zero(in[i]); + leading_zeros += CT::select(only_zeros, 1, 0); + } + + return secure_vector(in + leading_zeros, in + length); + } + +inline secure_vector strip_leading_zeros(const secure_vector& in) + { + return strip_leading_zeros(in.data(), in.size()); + } + +} + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/utils/data_src.cpp b/src/libs/3rdparty/botan/src/lib/utils/data_src.cpp new file mode 100644 index 0000000000..c5689534ff --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/utils/data_src.cpp @@ -0,0 +1,214 @@ +/* +* DataSource +* (C) 1999-2007 Jack Lloyd +* 2005 Matthew Gregan +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include + +#if defined(BOTAN_TARGET_OS_HAS_FILESYSTEM) + #include +#endif + +namespace Botan { + +/* +* Read a single byte from the DataSource +*/ +size_t DataSource::read_byte(uint8_t& out) + { + return read(&out, 1); + } + +/* +* Peek a single byte from the DataSource +*/ +size_t DataSource::peek_byte(uint8_t& out) const + { + return peek(&out, 1, 0); + } + +/* +* Discard the next N bytes of the data +*/ +size_t DataSource::discard_next(size_t n) + { + uint8_t buf[64] = { 0 }; + size_t discarded = 0; + + while(n) + { + const size_t got = this->read(buf, std::min(n, sizeof(buf))); + discarded += got; + n -= got; + + if(got == 0) + break; + } + + return discarded; + } + +/* +* Read from a memory buffer +*/ +size_t DataSource_Memory::read(uint8_t out[], size_t length) + { + const size_t got = std::min(m_source.size() - m_offset, length); + copy_mem(out, m_source.data() + m_offset, got); + m_offset += got; + return got; + } + +bool DataSource_Memory::check_available(size_t n) + { + return (n <= (m_source.size() - m_offset)); + } + +/* +* Peek into a memory buffer +*/ +size_t DataSource_Memory::peek(uint8_t out[], size_t length, + size_t peek_offset) const + { + const size_t bytes_left = m_source.size() - m_offset; + if(peek_offset >= bytes_left) return 0; + + const size_t got = std::min(bytes_left - peek_offset, length); + copy_mem(out, &m_source[m_offset + peek_offset], got); + return got; + } + +/* +* Check if the memory buffer is empty +*/ +bool DataSource_Memory::end_of_data() const + { + return (m_offset == m_source.size()); + } + +/* +* DataSource_Memory Constructor +*/ +DataSource_Memory::DataSource_Memory(const std::string& in) : + m_source(cast_char_ptr_to_uint8(in.data()), + cast_char_ptr_to_uint8(in.data()) + in.length()), + m_offset(0) + { + } + +/* +* Read from a stream +*/ +size_t DataSource_Stream::read(uint8_t out[], size_t length) + { + m_source.read(cast_uint8_ptr_to_char(out), length); + if(m_source.bad()) + throw Stream_IO_Error("DataSource_Stream::read: Source failure"); + + const size_t got = static_cast(m_source.gcount()); + m_total_read += got; + return got; + } + +bool DataSource_Stream::check_available(size_t n) + { + const std::streampos orig_pos = m_source.tellg(); + m_source.seekg(0, std::ios::end); + const size_t avail = static_cast(m_source.tellg() - orig_pos); + m_source.seekg(orig_pos); + return (avail >= n); + } + +/* +* Peek into a stream +*/ +size_t DataSource_Stream::peek(uint8_t out[], size_t length, size_t offset) const + { + if(end_of_data()) + throw Invalid_State("DataSource_Stream: Cannot peek when out of data"); + + size_t got = 0; + + if(offset) + { + secure_vector buf(offset); + m_source.read(cast_uint8_ptr_to_char(buf.data()), buf.size()); + if(m_source.bad()) + throw Stream_IO_Error("DataSource_Stream::peek: Source failure"); + got = static_cast(m_source.gcount()); + } + + if(got == offset) + { + m_source.read(cast_uint8_ptr_to_char(out), length); + if(m_source.bad()) + throw Stream_IO_Error("DataSource_Stream::peek: Source failure"); + got = static_cast(m_source.gcount()); + } + + if(m_source.eof()) + m_source.clear(); + m_source.seekg(m_total_read, std::ios::beg); + + return got; + } + +/* +* Check if the stream is empty or in error +*/ +bool DataSource_Stream::end_of_data() const + { + return (!m_source.good()); + } + +/* +* Return a human-readable ID for this stream +*/ +std::string DataSource_Stream::id() const + { + return m_identifier; + } + +#if defined(BOTAN_TARGET_OS_HAS_FILESYSTEM) + +/* +* DataSource_Stream Constructor +*/ +DataSource_Stream::DataSource_Stream(const std::string& path, + bool use_binary) : + m_identifier(path), + m_source_memory(new std::ifstream(path, use_binary ? std::ios::binary : std::ios::in)), + m_source(*m_source_memory), + m_total_read(0) + { + if(!m_source.good()) + { + throw Stream_IO_Error("DataSource: Failure opening file " + path); + } + } + +#endif + +/* +* DataSource_Stream Constructor +*/ +DataSource_Stream::DataSource_Stream(std::istream& in, + const std::string& name) : + m_identifier(name), + m_source(in), + m_total_read(0) + { + } + +DataSource_Stream::~DataSource_Stream() + { + // for ~unique_ptr + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/utils/data_src.h b/src/libs/3rdparty/botan/src/lib/utils/data_src.h new file mode 100644 index 0000000000..09c1bffdf7 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/utils/data_src.h @@ -0,0 +1,181 @@ +/* +* DataSource +* (C) 1999-2007 Jack Lloyd +* 2012 Markus Wanner +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_DATA_SRC_H_ +#define BOTAN_DATA_SRC_H_ + +#include +#include +#include + +namespace Botan { + +/** +* This class represents an abstract data source object. +*/ +class BOTAN_PUBLIC_API(2,0) DataSource + { + public: + /** + * Read from the source. Moves the internal offset so that every + * call to read will return a new portion of the source. + * + * @param out the byte array to write the result to + * @param length the length of the byte array out + * @return length in bytes that was actually read and put + * into out + */ + virtual size_t read(uint8_t out[], size_t length) BOTAN_WARN_UNUSED_RESULT = 0; + + virtual bool check_available(size_t n) = 0; + + /** + * Read from the source but do not modify the internal + * offset. Consecutive calls to peek() will return portions of + * the source starting at the same position. + * + * @param out the byte array to write the output to + * @param length the length of the byte array out + * @param peek_offset the offset into the stream to read at + * @return length in bytes that was actually read and put + * into out + */ + virtual size_t peek(uint8_t out[], size_t length, size_t peek_offset) const BOTAN_WARN_UNUSED_RESULT = 0; + + /** + * Test whether the source still has data that can be read. + * @return true if there is no more data to read, false otherwise + */ + virtual bool end_of_data() const = 0; + /** + * return the id of this data source + * @return std::string representing the id of this data source + */ + virtual std::string id() const { return ""; } + + /** + * Read one byte. + * @param out the byte to read to + * @return length in bytes that was actually read and put + * into out + */ + size_t read_byte(uint8_t& out); + + /** + * Peek at one byte. + * @param out an output byte + * @return length in bytes that was actually read and put + * into out + */ + size_t peek_byte(uint8_t& out) const; + + /** + * Discard the next N bytes of the data + * @param N the number of bytes to discard + * @return number of bytes actually discarded + */ + size_t discard_next(size_t N); + + /** + * @return number of bytes read so far. + */ + virtual size_t get_bytes_read() const = 0; + + DataSource() = default; + virtual ~DataSource() = default; + DataSource& operator=(const DataSource&) = delete; + DataSource(const DataSource&) = delete; + }; + +/** +* This class represents a Memory-Based DataSource +*/ +class BOTAN_PUBLIC_API(2,0) DataSource_Memory final : public DataSource + { + public: + size_t read(uint8_t[], size_t) override; + size_t peek(uint8_t[], size_t, size_t) const override; + bool check_available(size_t n) override; + bool end_of_data() const override; + + /** + * Construct a memory source that reads from a string + * @param in the string to read from + */ + explicit DataSource_Memory(const std::string& in); + + /** + * Construct a memory source that reads from a byte array + * @param in the byte array to read from + * @param length the length of the byte array + */ + DataSource_Memory(const uint8_t in[], size_t length) : + m_source(in, in + length), m_offset(0) {} + + /** + * Construct a memory source that reads from a secure_vector + * @param in the MemoryRegion to read from + */ + explicit DataSource_Memory(const secure_vector& in) : + m_source(in), m_offset(0) {} + + /** + * Construct a memory source that reads from a std::vector + * @param in the MemoryRegion to read from + */ + explicit DataSource_Memory(const std::vector& in) : + m_source(in.begin(), in.end()), m_offset(0) {} + + size_t get_bytes_read() const override { return m_offset; } + private: + secure_vector m_source; + size_t m_offset; + }; + +/** +* This class represents a Stream-Based DataSource. +*/ +class BOTAN_PUBLIC_API(2,0) DataSource_Stream final : public DataSource + { + public: + size_t read(uint8_t[], size_t) override; + size_t peek(uint8_t[], size_t, size_t) const override; + bool check_available(size_t n) override; + bool end_of_data() const override; + std::string id() const override; + + DataSource_Stream(std::istream&, + const std::string& id = ""); + +#if defined(BOTAN_TARGET_OS_HAS_FILESYSTEM) + /** + * Construct a Stream-Based DataSource from filesystem path + * @param file the path to the file + * @param use_binary whether to treat the file as binary or not + */ + DataSource_Stream(const std::string& file, bool use_binary = false); +#endif + + DataSource_Stream(const DataSource_Stream&) = delete; + + DataSource_Stream& operator=(const DataSource_Stream&) = delete; + + ~DataSource_Stream(); + + size_t get_bytes_read() const override { return m_total_read; } + private: + const std::string m_identifier; + + std::unique_ptr m_source_memory; + std::istream& m_source; + size_t m_total_read; + }; + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/utils/database.h b/src/libs/3rdparty/botan/src/lib/utils/database.h new file mode 100644 index 0000000000..21a207445a --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/utils/database.h @@ -0,0 +1,74 @@ +/* +* SQL database interface +* (C) 2014 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_SQL_DATABASE_H_ +#define BOTAN_SQL_DATABASE_H_ + +#include +#include +#include +#include +#include + +namespace Botan { + +class BOTAN_PUBLIC_API(2,0) SQL_Database + { + public: + + class BOTAN_PUBLIC_API(2,0) SQL_DB_Error final : public Exception + { + public: + explicit SQL_DB_Error(const std::string& what) : Exception("SQL database", what) {} + }; + + class BOTAN_PUBLIC_API(2,0) Statement + { + public: + /* Bind statement parameters */ + virtual void bind(int column, const std::string& str) = 0; + + virtual void bind(int column, size_t i) = 0; + + virtual void bind(int column, std::chrono::system_clock::time_point time) = 0; + + virtual void bind(int column, const std::vector& blob) = 0; + + virtual void bind(int column, const uint8_t* data, size_t len) = 0; + + /* Get output */ + virtual std::pair get_blob(int column) = 0; + + virtual std::string get_str(int column) = 0; + + virtual size_t get_size_t(int column) = 0; + + /* Run to completion */ + virtual size_t spin() = 0; + + /* Maybe update */ + virtual bool step() = 0; + + virtual ~Statement() = default; + }; + + /* + * Create a new statement for execution. + * Use ?1, ?2, ?3, etc for parameters to set later with bind + */ + virtual std::shared_ptr new_statement(const std::string& base_sql) const = 0; + + virtual size_t row_count(const std::string& table_name) = 0; + + virtual void create_table(const std::string& table_schema) = 0; + + virtual ~SQL_Database() = default; +}; + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/utils/donna128.h b/src/libs/3rdparty/botan/src/lib/utils/donna128.h new file mode 100644 index 0000000000..ff571906d8 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/utils/donna128.h @@ -0,0 +1,143 @@ +/* +* A minimal 128-bit integer type for curve25519-donna +* (C) 2014 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_CURVE25519_DONNA128_H_ +#define BOTAN_CURVE25519_DONNA128_H_ + +#include + +namespace Botan { + +class donna128 final + { + public: + donna128(uint64_t ll = 0, uint64_t hh = 0) { l = ll; h = hh; } + + donna128(const donna128&) = default; + donna128& operator=(const donna128&) = default; + + friend donna128 operator>>(const donna128& x, size_t shift) + { + donna128 z = x; + if(shift > 0) + { + const uint64_t carry = z.h << (64 - shift); + z.h = (z.h >> shift); + z.l = (z.l >> shift) | carry; + } + return z; + } + + friend donna128 operator<<(const donna128& x, size_t shift) + { + donna128 z = x; + if(shift > 0) + { + const uint64_t carry = z.l >> (64 - shift); + z.l = (z.l << shift); + z.h = (z.h << shift) | carry; + } + return z; + } + + friend uint64_t operator&(const donna128& x, uint64_t mask) + { + return x.l & mask; + } + + uint64_t operator&=(uint64_t mask) + { + h = 0; + l &= mask; + return l; + } + + donna128& operator+=(const donna128& x) + { + l += x.l; + h += x.h; + + const uint64_t carry = (l < x.l); + h += carry; + return *this; + } + + donna128& operator+=(uint64_t x) + { + l += x; + const uint64_t carry = (l < x); + h += carry; + return *this; + } + + uint64_t lo() const { return l; } + uint64_t hi() const { return h; } + private: + uint64_t h = 0, l = 0; + }; + +inline donna128 operator*(const donna128& x, uint64_t y) + { + BOTAN_ARG_CHECK(x.hi() == 0, "High 64 bits of donna128 set to zero during multiply"); + + uint64_t lo = 0, hi = 0; + mul64x64_128(x.lo(), y, &lo, &hi); + return donna128(lo, hi); + } + +inline donna128 operator*(uint64_t y, const donna128& x) + { + return x * y; + } + +inline donna128 operator+(const donna128& x, const donna128& y) + { + donna128 z = x; + z += y; + return z; + } + +inline donna128 operator+(const donna128& x, uint64_t y) + { + donna128 z = x; + z += y; + return z; + } + +inline donna128 operator|(const donna128& x, const donna128& y) + { + return donna128(x.lo() | y.lo(), x.hi() | y.hi()); + } + +inline uint64_t carry_shift(const donna128& a, size_t shift) + { + return (a >> shift).lo(); + } + +inline uint64_t combine_lower(const donna128& a, size_t s1, + const donna128& b, size_t s2) + { + donna128 z = (a >> s1) | (b << s2); + return z.lo(); + } + +#if defined(BOTAN_TARGET_HAS_NATIVE_UINT128) +inline uint64_t carry_shift(const uint128_t a, size_t shift) + { + return static_cast(a >> shift); + } + +inline uint64_t combine_lower(const uint128_t a, size_t s1, + const uint128_t b, size_t s2) + { + return static_cast((a >> s1) | (b << s2)); + } +#endif + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/utils/dyn_load/dyn_load.cpp b/src/libs/3rdparty/botan/src/lib/utils/dyn_load/dyn_load.cpp new file mode 100644 index 0000000000..1bbcffbdb5 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/utils/dyn_load/dyn_load.cpp @@ -0,0 +1,79 @@ +/* +* Dynamically Loaded Object +* (C) 2010 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include + +#if defined(BOTAN_TARGET_OS_HAS_POSIX1) + #include +#elif defined(BOTAN_TARGET_OS_HAS_WIN32) + #define NOMINMAX 1 + #define _WINSOCKAPI_ // stop windows.h including winsock.h + #include +#endif + +namespace Botan { + +namespace { + +void raise_runtime_loader_exception(const std::string& lib_name, + const char* msg) + { + throw Exception("Failed to load " + lib_name + ": " + + (msg ? msg : "Unknown error")); + } + +} + +Dynamically_Loaded_Library::Dynamically_Loaded_Library( + const std::string& library) : + m_lib_name(library), m_lib(nullptr) + { +#if defined(BOTAN_TARGET_OS_HAS_POSIX1) + m_lib = ::dlopen(m_lib_name.c_str(), RTLD_LAZY); + + if(!m_lib) + raise_runtime_loader_exception(m_lib_name, ::dlerror()); + +#elif defined(BOTAN_TARGET_OS_HAS_WIN32) + m_lib = ::LoadLibraryA(m_lib_name.c_str()); + + if(!m_lib) + raise_runtime_loader_exception(m_lib_name, "LoadLibrary failed"); +#endif + + if(!m_lib) + raise_runtime_loader_exception(m_lib_name, "Dynamic load not supported"); + } + +Dynamically_Loaded_Library::~Dynamically_Loaded_Library() + { +#if defined(BOTAN_TARGET_OS_HAS_POSIX1) + ::dlclose(m_lib); +#elif defined(BOTAN_TARGET_OS_HAS_WIN32) + ::FreeLibrary((HMODULE)m_lib); +#endif + } + +void* Dynamically_Loaded_Library::resolve_symbol(const std::string& symbol) + { + void* addr = nullptr; + +#if defined(BOTAN_TARGET_OS_HAS_POSIX1) + addr = ::dlsym(m_lib, symbol.c_str()); +#elif defined(BOTAN_TARGET_OS_HAS_WIN32) + addr = reinterpret_cast(::GetProcAddress((HMODULE)m_lib, symbol.c_str())); +#endif + + if(!addr) + throw Exception("Failed to resolve symbol " + symbol + + " in " + m_lib_name); + + return addr; + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/utils/dyn_load/dyn_load.h b/src/libs/3rdparty/botan/src/lib/utils/dyn_load/dyn_load.h new file mode 100644 index 0000000000..3caf65f277 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/utils/dyn_load/dyn_load.h @@ -0,0 +1,68 @@ +/* +* Dynamically Loaded Object +* (C) 2010 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_DYNAMIC_LOADER_H_ +#define BOTAN_DYNAMIC_LOADER_H_ + +#include +#include + +namespace Botan { + +/** +* Represents a DLL or shared object +*/ +class BOTAN_PUBLIC_API(2,0) Dynamically_Loaded_Library final + { + public: + /** + * Load a DLL (or fail with an exception) + * @param lib_name name or path to a library + * + * If you don't use a full path, the search order will be defined + * by whatever the system linker does by default. Always using fully + * qualified pathnames can help prevent code injection attacks (eg + * via manipulation of LD_LIBRARY_PATH on Linux) + */ + Dynamically_Loaded_Library(const std::string& lib_name); + + /** + * Unload the DLL + * @warning Any pointers returned by resolve()/resolve_symbol() + * should not be used after this destructor runs. + */ + ~Dynamically_Loaded_Library(); + + /** + * Load a symbol (or fail with an exception) + * @param symbol names the symbol to load + * @return address of the loaded symbol + */ + void* resolve_symbol(const std::string& symbol); + + /** + * Convenience function for casting symbol to the right type + * @param symbol names the symbol to load + * @return address of the loaded symbol + */ + template + T resolve(const std::string& symbol) + { + return reinterpret_cast(resolve_symbol(symbol)); + } + + private: + Dynamically_Loaded_Library(const Dynamically_Loaded_Library&); + Dynamically_Loaded_Library& operator=(const Dynamically_Loaded_Library&); + + std::string m_lib_name; + void* m_lib; + }; + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/utils/dyn_load/info.txt b/src/libs/3rdparty/botan/src/lib/utils/dyn_load/info.txt new file mode 100644 index 0000000000..4dd4932a00 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/utils/dyn_load/info.txt @@ -0,0 +1,17 @@ + +DYNAMIC_LOADER -> 20160310 + + +load_on dep + + +posix1 +win32 + + + +android -> dl +linux -> dl +solaris -> dl +darwin -> dl + diff --git a/src/libs/3rdparty/botan/src/lib/utils/exceptn.cpp b/src/libs/3rdparty/botan/src/lib/utils/exceptn.cpp new file mode 100644 index 0000000000..a72e45ba4c --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/utils/exceptn.cpp @@ -0,0 +1,105 @@ +/* +* (C) 2017 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include + +namespace Botan { + +Exception::Exception(const std::string& msg) : m_msg(msg) + {} + +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) + {} + +Invalid_Argument::Invalid_Argument(const std::string& msg, const std::string& where) : + Exception("Invalid argument", msg + " in " + where) + {} + +Lookup_Error::Lookup_Error(const std::string& type, + const std::string& algo, + const std::string& provider) : + Exception("Unavailable " + type + " " + algo + + (provider.empty() ? std::string("") : (" for provider " + provider))) + {} + +Internal_Error::Internal_Error(const std::string& err) : + Exception("Internal error: " + err) + {} + +Invalid_Key_Length::Invalid_Key_Length(const std::string& name, size_t length) : + Invalid_Argument(name + " cannot accept a key of length " + + std::to_string(length)) + {} + +Invalid_IV_Length::Invalid_IV_Length(const std::string& mode, size_t bad_len) : + Invalid_Argument("IV length " + std::to_string(bad_len) + + " is invalid for " + mode) + {} + +Key_Not_Set::Key_Not_Set(const std::string& algo) : + Invalid_State("Key not set in " + algo) + {} + +Policy_Violation::Policy_Violation(const std::string& err) : + Invalid_State("Policy violation: " + err) {} + +PRNG_Unseeded::PRNG_Unseeded(const std::string& algo) : + Invalid_State("PRNG not seeded: " + algo) + {} + +Algorithm_Not_Found::Algorithm_Not_Found(const std::string& name) : + Lookup_Error("Could not find any algorithm named \"" + name + "\"") + {} + +No_Provider_Found::No_Provider_Found(const std::string& name) : + Exception("Could not find any provider for algorithm named \"" + name + "\"") + {} + +Provider_Not_Found::Provider_Not_Found(const std::string& algo, const std::string& provider) : + Lookup_Error("Could not find provider '" + provider + "' for " + algo) + {} + +Invalid_Algorithm_Name::Invalid_Algorithm_Name(const std::string& name): + Invalid_Argument("Invalid algorithm name: " + name) + {} + +Encoding_Error::Encoding_Error(const std::string& name) : + Invalid_Argument("Encoding error: " + name) + {} + +Decoding_Error::Decoding_Error(const std::string& name) : + Invalid_Argument("Decoding error: " + name) + {} + +Decoding_Error::Decoding_Error(const std::string& name, const char* exception_message) : + Invalid_Argument("Decoding error: " + name + " failed with exception " + exception_message) {} + +Integrity_Failure::Integrity_Failure(const std::string& msg) : + Exception("Integrity failure: " + msg) + {} + +Invalid_OID::Invalid_OID(const std::string& oid) : + Decoding_Error("Invalid ASN.1 OID: " + oid) + {} + +Stream_IO_Error::Stream_IO_Error(const std::string& err) : + Exception("I/O error: " + err) + {} + +Self_Test_Failure::Self_Test_Failure(const std::string& err) : + Internal_Error("Self test failed: " + err) + {} + +Not_Implemented::Not_Implemented(const std::string& err) : + Exception("Not implemented", err) + {} + +} diff --git a/src/libs/3rdparty/botan/src/lib/utils/exceptn.h b/src/libs/3rdparty/botan/src/lib/utils/exceptn.h new file mode 100644 index 0000000000..f2896aa83b --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/utils/exceptn.h @@ -0,0 +1,230 @@ +/* +* Exceptions +* (C) 1999-2009 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_EXCEPTION_H_ +#define BOTAN_EXCEPTION_H_ + +#include +#include +#include + +namespace Botan { + +/** +* Base class for all exceptions thrown by the library +*/ +class BOTAN_PUBLIC_API(2,0) Exception : public std::exception + { + public: + 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(); } + private: + std::string m_msg; + }; + +/** +* An invalid argument +*/ +class BOTAN_PUBLIC_API(2,0) Invalid_Argument : public Exception + { + public: + explicit Invalid_Argument(const std::string& msg); + + explicit Invalid_Argument(const std::string& msg, const std::string& where); +}; + +/** +* Unsupported_Argument Exception +* +* An argument that is invalid because it is not supported by Botan. +* It might or might not be valid in another context like a standard. +*/ +class BOTAN_PUBLIC_API(2,0) Unsupported_Argument final : public Invalid_Argument + { + public: + explicit Unsupported_Argument(const std::string& msg) : Invalid_Argument(msg) {} + }; + +/** +* Invalid_State Exception +*/ +class BOTAN_PUBLIC_API(2,0) Invalid_State : public Exception + { + public: + explicit Invalid_State(const std::string& err) : Exception(err) {} + }; + +class BOTAN_PUBLIC_API(2,4) Key_Not_Set : public Invalid_State + { + public: + explicit Key_Not_Set(const std::string& algo); + }; + +/** +* Lookup_Error Exception +*/ +class BOTAN_PUBLIC_API(2,0) Lookup_Error : public Exception + { + public: + explicit Lookup_Error(const std::string& err) : Exception(err) {} + + Lookup_Error(const std::string& type, + const std::string& algo, + const std::string& provider); + }; + +/** +* Internal_Error Exception +*/ +class BOTAN_PUBLIC_API(2,0) Internal_Error : public Exception + { + public: + explicit Internal_Error(const std::string& err); + }; + +/** +* Invalid_Key_Length Exception +*/ +class BOTAN_PUBLIC_API(2,0) Invalid_Key_Length final : public Invalid_Argument + { + public: + Invalid_Key_Length(const std::string& name, size_t length); + }; + +/** +* Invalid_IV_Length Exception +*/ +class BOTAN_PUBLIC_API(2,0) Invalid_IV_Length final : public Invalid_Argument + { + public: + Invalid_IV_Length(const std::string& mode, size_t bad_len); + }; + +/** +* PRNG_Unseeded Exception +*/ +class BOTAN_PUBLIC_API(2,0) PRNG_Unseeded final : public Invalid_State + { + public: + explicit PRNG_Unseeded(const std::string& algo); + }; + +/** +* Policy_Violation Exception +*/ +class BOTAN_PUBLIC_API(2,0) Policy_Violation final : public Invalid_State + { + public: + BOTAN_DEPRECATED("deprecated") explicit Policy_Violation(const std::string& err); + }; + +/** +* Algorithm_Not_Found Exception +*/ +class BOTAN_PUBLIC_API(2,0) Algorithm_Not_Found final : public Lookup_Error + { + public: + explicit Algorithm_Not_Found(const std::string& name); + }; + +/** +* No_Provider_Found Exception +*/ +class BOTAN_PUBLIC_API(2,0) No_Provider_Found final : public Exception + { + public: + BOTAN_DEPRECATED("deprecated") explicit No_Provider_Found(const std::string& name); + }; + +/** +* Provider_Not_Found is thrown when a specific provider was requested +* but that provider is not available. +*/ +class BOTAN_PUBLIC_API(2,0) Provider_Not_Found final : public Lookup_Error + { + public: + Provider_Not_Found(const std::string& algo, const std::string& provider); + }; + +/** +* Invalid_Algorithm_Name Exception +*/ +class BOTAN_PUBLIC_API(2,0) Invalid_Algorithm_Name final : public Invalid_Argument + { + public: + explicit Invalid_Algorithm_Name(const std::string& name); + }; + +/** +* Encoding_Error Exception +*/ +class BOTAN_PUBLIC_API(2,0) Encoding_Error final : public Invalid_Argument + { + public: + explicit Encoding_Error(const std::string& name); + }; + +/** +* Decoding_Error Exception +*/ +class BOTAN_PUBLIC_API(2,0) Decoding_Error : public Invalid_Argument + { + public: + explicit Decoding_Error(const std::string& name); + + Decoding_Error(const std::string& name, const char* exception_message); + }; + +/** +* Integrity_Failure Exception +*/ +class BOTAN_PUBLIC_API(2,0) Integrity_Failure final : public Exception + { + public: + explicit Integrity_Failure(const std::string& msg); + }; + +/** +* Invalid_OID Exception +*/ +class BOTAN_PUBLIC_API(2,0) Invalid_OID final : public Decoding_Error + { + public: + explicit Invalid_OID(const std::string& oid); + }; + +/** +* Stream_IO_Error Exception +*/ +class BOTAN_PUBLIC_API(2,0) Stream_IO_Error final : public Exception + { + public: + explicit Stream_IO_Error(const std::string& err); + }; + +/** +* Self Test Failure Exception +*/ +class BOTAN_PUBLIC_API(2,0) Self_Test_Failure final : public Internal_Error + { + public: + BOTAN_DEPRECATED("deprecated") explicit Self_Test_Failure(const std::string& err); + }; + +/** +* Not Implemented Exception +*/ +class BOTAN_PUBLIC_API(2,0) Not_Implemented final : public Exception + { + public: + explicit Not_Implemented(const std::string& err); + }; + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/utils/filesystem.cpp b/src/libs/3rdparty/botan/src/lib/utils/filesystem.cpp new file mode 100644 index 0000000000..053c91e701 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/utils/filesystem.cpp @@ -0,0 +1,204 @@ +/* +* (C) 2015,2017 Jack Lloyd +* (C) 2015 Simon Warta (Kullo GmbH) +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include + +#if defined(BOTAN_TARGET_OS_HAS_STL_FILESYSTEM_MSVC) && defined(BOTAN_BUILD_COMPILER_IS_MSVC) + #include +#elif defined(BOTAN_HAS_BOOST_FILESYSTEM) + #include +#elif defined(BOTAN_TARGET_OS_HAS_POSIX1) + #include + #include + #include + #include + #include + #include +#elif defined(BOTAN_TARGET_OS_HAS_WIN32) + #define NOMINMAX 1 + #define _WINSOCKAPI_ // stop windows.h including winsock.h + #include + #include + #include +#endif + +namespace Botan { + +namespace { + +#if defined(BOTAN_TARGET_OS_HAS_STL_FILESYSTEM_MSVC) && defined(BOTAN_BUILD_COMPILER_IS_MSVC) +std::vector impl_stl_filesystem(const std::string& dir) + { +#if (_MSVC_LANG >= 201703L) + using namespace std::filesystem; +#else + using namespace std::tr2::sys; +#endif + + std::vector out; + + path p(dir); + + if(is_directory(p)) + { + for(recursive_directory_iterator itr(p), end; itr != end; ++itr) + { + if(is_regular_file(itr->path())) + { + out.push_back(itr->path().string()); + } + } + } + + return out; + } + +#elif defined(BOTAN_HAS_BOOST_FILESYSTEM) + +std::vector impl_boost_filesystem(const std::string& dir_path) +{ + namespace fs = boost::filesystem; + + std::vector out; + + for(fs::recursive_directory_iterator dir(dir_path), end; dir != end; ++dir) + { + if(fs::is_regular_file(dir->path())) + { + out.push_back(dir->path().string()); + } + } + + return out; +} + +#elif defined(BOTAN_TARGET_OS_HAS_POSIX1) + +std::vector impl_readdir(const std::string& dir_path) + { + std::vector out; + std::deque dir_list; + dir_list.push_back(dir_path); + + while(!dir_list.empty()) + { + const std::string cur_path = dir_list[0]; + dir_list.pop_front(); + + std::unique_ptr> dir(::opendir(cur_path.c_str()), ::closedir); + + if(dir) + { + while(struct dirent* dirent = ::readdir(dir.get())) + { + const std::string filename = dirent->d_name; + if(filename == "." || filename == "..") + continue; + const std::string full_path = cur_path + "/" + filename; + + struct stat stat_buf; + + if(::stat(full_path.c_str(), &stat_buf) == -1) + continue; + + if(S_ISDIR(stat_buf.st_mode)) + dir_list.push_back(full_path); + else if(S_ISREG(stat_buf.st_mode)) + out.push_back(full_path); + } + } + } + + return out; + } + +#elif defined(BOTAN_TARGET_OS_HAS_WIN32) + +std::vector impl_win32(const std::string& dir_path) + { + std::vector out; + std::deque dir_list; + dir_list.push_back(dir_path); + + while(!dir_list.empty()) + { + const std::string cur_path = dir_list[0]; + dir_list.pop_front(); + + WIN32_FIND_DATAA find_data; + HANDLE dir = ::FindFirstFileA((cur_path + "/*").c_str(), &find_data); + + if(dir != INVALID_HANDLE_VALUE) + { + do + { + const std::string filename = find_data.cFileName; + if(filename == "." || filename == "..") + continue; + const std::string full_path = cur_path + "/" + filename; + + if(find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + { + dir_list.push_back(full_path); + } + else + { + out.push_back(full_path); + } + } + while(::FindNextFileA(dir, &find_data)); + } + + ::FindClose(dir); + } + + return out; +} +#endif + +} + +bool has_filesystem_impl() + { +#if defined(BOTAN_TARGET_OS_HAS_STL_FILESYSTEM_MSVC) && defined(BOTAN_BUILD_COMPILER_IS_MSVC) + return true; +#elif defined(BOTAN_HAS_BOOST_FILESYSTEM) + return true; +#elif defined(BOTAN_TARGET_OS_HAS_POSIX1) + return true; +#elif defined(BOTAN_TARGET_OS_HAS_WIN32) + return true; +#else + return false; +#endif + } + +std::vector get_files_recursive(const std::string& dir) + { + std::vector files; + +#if defined(BOTAN_TARGET_OS_HAS_STL_FILESYSTEM_MSVC) && defined(BOTAN_BUILD_COMPILER_IS_MSVC) + files = impl_stl_filesystem(dir); +#elif defined(BOTAN_HAS_BOOST_FILESYSTEM) + files = impl_boost_filesystem(dir); +#elif defined(BOTAN_TARGET_OS_HAS_POSIX1) + files = impl_readdir(dir); +#elif defined(BOTAN_TARGET_OS_HAS_WIN32) + files = impl_win32(dir); +#else + BOTAN_UNUSED(dir); + throw No_Filesystem_Access(); +#endif + + std::sort(files.begin(), files.end()); + + return files; + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/utils/filesystem.h b/src/libs/3rdparty/botan/src/lib/utils/filesystem.h new file mode 100644 index 0000000000..382da7de34 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/utils/filesystem.h @@ -0,0 +1,33 @@ +/* +* (C) 2015 Jack Lloyd +* (C) 2015 Simon Warta (Kullo GmbH) +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_UTIL_FILESYSTEM_H_ +#define BOTAN_UTIL_FILESYSTEM_H_ + +#include +#include +#include + +namespace Botan { + +/** +* No_Filesystem_Access Exception +*/ +class BOTAN_PUBLIC_API(2,0) No_Filesystem_Access final : public Exception + { + public: + No_Filesystem_Access() : Exception("No filesystem access enabled.") + {} + }; + +BOTAN_TEST_API bool has_filesystem_impl(); + +BOTAN_TEST_API std::vector get_files_recursive(const std::string& dir); + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/utils/info.txt b/src/libs/3rdparty/botan/src/lib/utils/info.txt new file mode 100644 index 0000000000..fb9325f932 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/utils/info.txt @@ -0,0 +1,42 @@ + +UTIL_FUNCTIONS -> 20171003 + + +load_on always + + +assert.h +bswap.h +calendar.h +charset.h +compiler.h +data_src.h +database.h +exceptn.h +loadstor.h +mem_ops.h +mul128.h +mutex.h +parsing.h +rotate.h +types.h +version.h +stl_compatibility.h + + + +bit_ops.h +codec_base.h +ct_utils.h +donna128.h +filesystem.h +os_utils.h +prefetch.h +rounding.h +safeint.h +stl_util.h + + + +cpuid + diff --git a/src/libs/3rdparty/botan/src/lib/utils/loadstor.h b/src/libs/3rdparty/botan/src/lib/utils/loadstor.h new file mode 100644 index 0000000000..70ad20591c --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/utils/loadstor.h @@ -0,0 +1,697 @@ +/* +* Load/Store Operators +* (C) 1999-2007,2015,2017 Jack Lloyd +* 2007 Yves Jerschow +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_LOAD_STORE_H_ +#define BOTAN_LOAD_STORE_H_ + +#include +#include +#include +#include + +#if defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN) + #define BOTAN_ENDIAN_N2L(x) reverse_bytes(x) + #define BOTAN_ENDIAN_L2N(x) reverse_bytes(x) + #define BOTAN_ENDIAN_N2B(x) (x) + #define BOTAN_ENDIAN_B2N(x) (x) + +#elif defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN) + #define BOTAN_ENDIAN_N2L(x) (x) + #define BOTAN_ENDIAN_L2N(x) (x) + #define BOTAN_ENDIAN_N2B(x) reverse_bytes(x) + #define BOTAN_ENDIAN_B2N(x) reverse_bytes(x) + +#endif + +namespace Botan { + +/** +* Byte extraction +* @param byte_num which byte to extract, 0 == highest byte +* @param input the value to extract from +* @return byte byte_num of input +*/ +template inline uint8_t get_byte(size_t byte_num, T input) + { + return static_cast( + input >> (((~byte_num)&(sizeof(T)-1)) << 3) + ); + } + +/** +* Make a uint16_t from two bytes +* @param i0 the first byte +* @param i1 the second byte +* @return i0 || i1 +*/ +inline uint16_t make_uint16(uint8_t i0, uint8_t i1) + { + return static_cast((static_cast(i0) << 8) | i1); + } + +/** +* Make a uint32_t from four bytes +* @param i0 the first byte +* @param i1 the second byte +* @param i2 the third byte +* @param i3 the fourth byte +* @return i0 || i1 || i2 || i3 +*/ +inline uint32_t make_uint32(uint8_t i0, uint8_t i1, uint8_t i2, uint8_t i3) + { + return ((static_cast(i0) << 24) | + (static_cast(i1) << 16) | + (static_cast(i2) << 8) | + (static_cast(i3))); + } + +/** +* Make a uint32_t from eight bytes +* @param i0 the first byte +* @param i1 the second byte +* @param i2 the third byte +* @param i3 the fourth byte +* @param i4 the fifth byte +* @param i5 the sixth byte +* @param i6 the seventh byte +* @param i7 the eighth byte +* @return i0 || i1 || i2 || i3 || i4 || i5 || i6 || i7 +*/ +inline uint64_t make_uint64(uint8_t i0, uint8_t i1, uint8_t i2, uint8_t i3, + uint8_t i4, uint8_t i5, uint8_t i6, uint8_t i7) + { + return ((static_cast(i0) << 56) | + (static_cast(i1) << 48) | + (static_cast(i2) << 40) | + (static_cast(i3) << 32) | + (static_cast(i4) << 24) | + (static_cast(i5) << 16) | + (static_cast(i6) << 8) | + (static_cast(i7))); + } + +/** +* Load a big-endian word +* @param in a pointer to some bytes +* @param off an offset into the array +* @return off'th T of in, as a big-endian value +*/ +template +inline T load_be(const uint8_t in[], size_t off) + { + in += off * sizeof(T); + T out = 0; + for(size_t i = 0; i != sizeof(T); ++i) + out = static_cast((out << 8) | in[i]); + return out; + } + +/** +* Load a little-endian word +* @param in a pointer to some bytes +* @param off an offset into the array +* @return off'th T of in, as a litte-endian value +*/ +template +inline T load_le(const uint8_t in[], size_t off) + { + in += off * sizeof(T); + T out = 0; + for(size_t i = 0; i != sizeof(T); ++i) + out = (out << 8) | in[sizeof(T)-1-i]; + return out; + } + +/** +* Load a big-endian uint16_t +* @param in a pointer to some bytes +* @param off an offset into the array +* @return off'th uint16_t of in, as a big-endian value +*/ +template<> +inline uint16_t load_be(const uint8_t in[], size_t off) + { + in += off * sizeof(uint16_t); + +#if defined(BOTAN_ENDIAN_N2B) + uint16_t x; + std::memcpy(&x, in, sizeof(x)); + return BOTAN_ENDIAN_N2B(x); +#else + return make_uint16(in[0], in[1]); +#endif + } + +/** +* Load a little-endian uint16_t +* @param in a pointer to some bytes +* @param off an offset into the array +* @return off'th uint16_t of in, as a little-endian value +*/ +template<> +inline uint16_t load_le(const uint8_t in[], size_t off) + { + in += off * sizeof(uint16_t); + +#if defined(BOTAN_ENDIAN_N2L) + uint16_t x; + std::memcpy(&x, in, sizeof(x)); + return BOTAN_ENDIAN_N2L(x); +#else + return make_uint16(in[1], in[0]); +#endif + } + +/** +* Load a big-endian uint32_t +* @param in a pointer to some bytes +* @param off an offset into the array +* @return off'th uint32_t of in, as a big-endian value +*/ +template<> +inline uint32_t load_be(const uint8_t in[], size_t off) + { + in += off * sizeof(uint32_t); +#if defined(BOTAN_ENDIAN_N2B) + uint32_t x; + std::memcpy(&x, in, sizeof(x)); + return BOTAN_ENDIAN_N2B(x); +#else + return make_uint32(in[0], in[1], in[2], in[3]); +#endif + } + +/** +* Load a little-endian uint32_t +* @param in a pointer to some bytes +* @param off an offset into the array +* @return off'th uint32_t of in, as a little-endian value +*/ +template<> +inline uint32_t load_le(const uint8_t in[], size_t off) + { + in += off * sizeof(uint32_t); +#if defined(BOTAN_ENDIAN_N2L) + uint32_t x; + std::memcpy(&x, in, sizeof(x)); + return BOTAN_ENDIAN_N2L(x); +#else + return make_uint32(in[3], in[2], in[1], in[0]); +#endif + } + +/** +* Load a big-endian uint64_t +* @param in a pointer to some bytes +* @param off an offset into the array +* @return off'th uint64_t of in, as a big-endian value +*/ +template<> +inline uint64_t load_be(const uint8_t in[], size_t off) + { + in += off * sizeof(uint64_t); +#if defined(BOTAN_ENDIAN_N2B) + uint64_t x; + std::memcpy(&x, in, sizeof(x)); + return BOTAN_ENDIAN_N2B(x); +#else + return make_uint64(in[0], in[1], in[2], in[3], + in[4], in[5], in[6], in[7]); +#endif + } + +/** +* Load a little-endian uint64_t +* @param in a pointer to some bytes +* @param off an offset into the array +* @return off'th uint64_t of in, as a little-endian value +*/ +template<> +inline uint64_t load_le(const uint8_t in[], size_t off) + { + in += off * sizeof(uint64_t); +#if defined(BOTAN_ENDIAN_N2L) + uint64_t x; + std::memcpy(&x, in, sizeof(x)); + return BOTAN_ENDIAN_N2L(x); +#else + return make_uint64(in[7], in[6], in[5], in[4], + in[3], in[2], in[1], in[0]); +#endif + } + +/** +* Load two little-endian words +* @param in a pointer to some bytes +* @param x0 where the first word will be written +* @param x1 where the second word will be written +*/ +template +inline void load_le(const uint8_t in[], T& x0, T& x1) + { + x0 = load_le(in, 0); + x1 = load_le(in, 1); + } + +/** +* Load four little-endian words +* @param in a pointer to some bytes +* @param x0 where the first word will be written +* @param x1 where the second word will be written +* @param x2 where the third word will be written +* @param x3 where the fourth word will be written +*/ +template +inline void load_le(const uint8_t in[], + T& x0, T& x1, T& x2, T& x3) + { + x0 = load_le(in, 0); + x1 = load_le(in, 1); + x2 = load_le(in, 2); + x3 = load_le(in, 3); + } + +/** +* Load eight little-endian words +* @param in a pointer to some bytes +* @param x0 where the first word will be written +* @param x1 where the second word will be written +* @param x2 where the third word will be written +* @param x3 where the fourth word will be written +* @param x4 where the fifth word will be written +* @param x5 where the sixth word will be written +* @param x6 where the seventh word will be written +* @param x7 where the eighth word will be written +*/ +template +inline void load_le(const uint8_t in[], + T& x0, T& x1, T& x2, T& x3, + T& x4, T& x5, T& x6, T& x7) + { + x0 = load_le(in, 0); + x1 = load_le(in, 1); + x2 = load_le(in, 2); + x3 = load_le(in, 3); + x4 = load_le(in, 4); + x5 = load_le(in, 5); + x6 = load_le(in, 6); + x7 = load_le(in, 7); + } + +/** +* Load a variable number of little-endian words +* @param out the output array of words +* @param in the input array of bytes +* @param count how many words are in in +*/ +template +inline void load_le(T out[], + const uint8_t in[], + size_t count) + { + if(count > 0) + { +#if defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN) + std::memcpy(out, in, sizeof(T)*count); +#elif defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN) + std::memcpy(out, in, sizeof(T)*count); + const size_t blocks = count - (count % 4); + const size_t left = count - blocks; + + for(size_t i = 0; i != blocks; i += 4) + bswap_4(out + i); + + for(size_t i = 0; i != left; ++i) + out[blocks+i] = reverse_bytes(out[blocks+i]); +#else + for(size_t i = 0; i != count; ++i) + out[i] = load_le(in, i); +#endif + } + } + +/** +* Load two big-endian words +* @param in a pointer to some bytes +* @param x0 where the first word will be written +* @param x1 where the second word will be written +*/ +template +inline void load_be(const uint8_t in[], T& x0, T& x1) + { + x0 = load_be(in, 0); + x1 = load_be(in, 1); + } + +/** +* Load four big-endian words +* @param in a pointer to some bytes +* @param x0 where the first word will be written +* @param x1 where the second word will be written +* @param x2 where the third word will be written +* @param x3 where the fourth word will be written +*/ +template +inline void load_be(const uint8_t in[], + T& x0, T& x1, T& x2, T& x3) + { + x0 = load_be(in, 0); + x1 = load_be(in, 1); + x2 = load_be(in, 2); + x3 = load_be(in, 3); + } + +/** +* Load eight big-endian words +* @param in a pointer to some bytes +* @param x0 where the first word will be written +* @param x1 where the second word will be written +* @param x2 where the third word will be written +* @param x3 where the fourth word will be written +* @param x4 where the fifth word will be written +* @param x5 where the sixth word will be written +* @param x6 where the seventh word will be written +* @param x7 where the eighth word will be written +*/ +template +inline void load_be(const uint8_t in[], + T& x0, T& x1, T& x2, T& x3, + T& x4, T& x5, T& x6, T& x7) + { + x0 = load_be(in, 0); + x1 = load_be(in, 1); + x2 = load_be(in, 2); + x3 = load_be(in, 3); + x4 = load_be(in, 4); + x5 = load_be(in, 5); + x6 = load_be(in, 6); + x7 = load_be(in, 7); + } + +/** +* Load a variable number of big-endian words +* @param out the output array of words +* @param in the input array of bytes +* @param count how many words are in in +*/ +template +inline void load_be(T out[], + const uint8_t in[], + size_t count) + { + if(count > 0) + { +#if defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN) + std::memcpy(out, in, sizeof(T)*count); + +#elif defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN) + std::memcpy(out, in, sizeof(T)*count); + const size_t blocks = count - (count % 4); + const size_t left = count - blocks; + + for(size_t i = 0; i != blocks; i += 4) + bswap_4(out + i); + + for(size_t i = 0; i != left; ++i) + out[blocks+i] = reverse_bytes(out[blocks+i]); +#else + for(size_t i = 0; i != count; ++i) + out[i] = load_be(in, i); +#endif + } + } + +/** +* Store a big-endian uint16_t +* @param in the input uint16_t +* @param out the byte array to write to +*/ +inline void store_be(uint16_t in, uint8_t out[2]) + { +#if defined(BOTAN_ENDIAN_N2B) + uint16_t o = BOTAN_ENDIAN_N2B(in); + std::memcpy(out, &o, sizeof(o)); +#else + out[0] = get_byte(0, in); + out[1] = get_byte(1, in); +#endif + } + +/** +* Store a little-endian uint16_t +* @param in the input uint16_t +* @param out the byte array to write to +*/ +inline void store_le(uint16_t in, uint8_t out[2]) + { +#if defined(BOTAN_ENDIAN_N2L) + uint16_t o = BOTAN_ENDIAN_N2L(in); + std::memcpy(out, &o, sizeof(o)); +#else + out[0] = get_byte(1, in); + out[1] = get_byte(0, in); +#endif + } + +/** +* Store a big-endian uint32_t +* @param in the input uint32_t +* @param out the byte array to write to +*/ +inline void store_be(uint32_t in, uint8_t out[4]) + { +#if defined(BOTAN_ENDIAN_B2N) + uint32_t o = BOTAN_ENDIAN_B2N(in); + std::memcpy(out, &o, sizeof(o)); +#else + out[0] = get_byte(0, in); + out[1] = get_byte(1, in); + out[2] = get_byte(2, in); + out[3] = get_byte(3, in); +#endif + } + +/** +* Store a little-endian uint32_t +* @param in the input uint32_t +* @param out the byte array to write to +*/ +inline void store_le(uint32_t in, uint8_t out[4]) + { +#if defined(BOTAN_ENDIAN_L2N) + uint32_t o = BOTAN_ENDIAN_L2N(in); + std::memcpy(out, &o, sizeof(o)); +#else + out[0] = get_byte(3, in); + out[1] = get_byte(2, in); + out[2] = get_byte(1, in); + out[3] = get_byte(0, in); +#endif + } + +/** +* Store a big-endian uint64_t +* @param in the input uint64_t +* @param out the byte array to write to +*/ +inline void store_be(uint64_t in, uint8_t out[8]) + { +#if defined(BOTAN_ENDIAN_B2N) + uint64_t o = BOTAN_ENDIAN_B2N(in); + std::memcpy(out, &o, sizeof(o)); +#else + out[0] = get_byte(0, in); + out[1] = get_byte(1, in); + out[2] = get_byte(2, in); + out[3] = get_byte(3, in); + out[4] = get_byte(4, in); + out[5] = get_byte(5, in); + out[6] = get_byte(6, in); + out[7] = get_byte(7, in); +#endif + } + +/** +* Store a little-endian uint64_t +* @param in the input uint64_t +* @param out the byte array to write to +*/ +inline void store_le(uint64_t in, uint8_t out[8]) + { +#if defined(BOTAN_ENDIAN_L2N) + uint64_t o = BOTAN_ENDIAN_L2N(in); + std::memcpy(out, &o, sizeof(o)); +#else + out[0] = get_byte(7, in); + out[1] = get_byte(6, in); + out[2] = get_byte(5, in); + out[3] = get_byte(4, in); + out[4] = get_byte(3, in); + out[5] = get_byte(2, in); + out[6] = get_byte(1, in); + out[7] = get_byte(0, in); +#endif + } + +/** +* Store two little-endian words +* @param out the output byte array +* @param x0 the first word +* @param x1 the second word +*/ +template +inline void store_le(uint8_t out[], T x0, T x1) + { + store_le(x0, out + (0 * sizeof(T))); + store_le(x1, out + (1 * sizeof(T))); + } + +/** +* Store two big-endian words +* @param out the output byte array +* @param x0 the first word +* @param x1 the second word +*/ +template +inline void store_be(uint8_t out[], T x0, T x1) + { + store_be(x0, out + (0 * sizeof(T))); + store_be(x1, out + (1 * sizeof(T))); + } + +/** +* Store four little-endian words +* @param out the output byte array +* @param x0 the first word +* @param x1 the second word +* @param x2 the third word +* @param x3 the fourth word +*/ +template +inline void store_le(uint8_t out[], T x0, T x1, T x2, T x3) + { + store_le(x0, out + (0 * sizeof(T))); + store_le(x1, out + (1 * sizeof(T))); + store_le(x2, out + (2 * sizeof(T))); + store_le(x3, out + (3 * sizeof(T))); + } + +/** +* Store four big-endian words +* @param out the output byte array +* @param x0 the first word +* @param x1 the second word +* @param x2 the third word +* @param x3 the fourth word +*/ +template +inline void store_be(uint8_t out[], T x0, T x1, T x2, T x3) + { + store_be(x0, out + (0 * sizeof(T))); + store_be(x1, out + (1 * sizeof(T))); + store_be(x2, out + (2 * sizeof(T))); + store_be(x3, out + (3 * sizeof(T))); + } + +/** +* Store eight little-endian words +* @param out the output byte array +* @param x0 the first word +* @param x1 the second word +* @param x2 the third word +* @param x3 the fourth word +* @param x4 the fifth word +* @param x5 the sixth word +* @param x6 the seventh word +* @param x7 the eighth word +*/ +template +inline void store_le(uint8_t out[], T x0, T x1, T x2, T x3, + T x4, T x5, T x6, T x7) + { + store_le(x0, out + (0 * sizeof(T))); + store_le(x1, out + (1 * sizeof(T))); + store_le(x2, out + (2 * sizeof(T))); + store_le(x3, out + (3 * sizeof(T))); + store_le(x4, out + (4 * sizeof(T))); + store_le(x5, out + (5 * sizeof(T))); + store_le(x6, out + (6 * sizeof(T))); + store_le(x7, out + (7 * sizeof(T))); + } + +/** +* Store eight big-endian words +* @param out the output byte array +* @param x0 the first word +* @param x1 the second word +* @param x2 the third word +* @param x3 the fourth word +* @param x4 the fifth word +* @param x5 the sixth word +* @param x6 the seventh word +* @param x7 the eighth word +*/ +template +inline void store_be(uint8_t out[], T x0, T x1, T x2, T x3, + T x4, T x5, T x6, T x7) + { + store_be(x0, out + (0 * sizeof(T))); + store_be(x1, out + (1 * sizeof(T))); + store_be(x2, out + (2 * sizeof(T))); + store_be(x3, out + (3 * sizeof(T))); + store_be(x4, out + (4 * sizeof(T))); + store_be(x5, out + (5 * sizeof(T))); + store_be(x6, out + (6 * sizeof(T))); + store_be(x7, out + (7 * sizeof(T))); + } + +template +void copy_out_be(uint8_t out[], size_t out_bytes, const T in[]) + { + while(out_bytes >= sizeof(T)) + { + store_be(in[0], out); + out += sizeof(T); + out_bytes -= sizeof(T); + in += 1; + } + + for(size_t i = 0; i != out_bytes; ++i) + out[i] = get_byte(i%8, in[0]); + } + +template +void copy_out_vec_be(uint8_t out[], size_t out_bytes, const std::vector& in) + { + copy_out_be(out, out_bytes, in.data()); + } + +template +void copy_out_le(uint8_t out[], size_t out_bytes, const T in[]) + { + while(out_bytes >= sizeof(T)) + { + store_le(in[0], out); + out += sizeof(T); + out_bytes -= sizeof(T); + in += 1; + } + + for(size_t i = 0; i != out_bytes; ++i) + out[i] = get_byte(sizeof(T) - 1 - (i % 8), in[0]); + } + +template +void copy_out_vec_le(uint8_t out[], size_t out_bytes, const std::vector& in) + { + copy_out_le(out, out_bytes, in.data()); + } + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/utils/mem_ops.cpp b/src/libs/3rdparty/botan/src/lib/utils/mem_ops.cpp new file mode 100644 index 0000000000..b7ecd53260 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/utils/mem_ops.cpp @@ -0,0 +1,63 @@ +/* +* (C) 2017 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include + +#if defined(BOTAN_HAS_LOCKING_ALLOCATOR) + #include +#endif + +namespace Botan { + +BOTAN_MALLOC_FN void* allocate_memory(size_t elems, size_t elem_size) + { +#if defined(BOTAN_HAS_LOCKING_ALLOCATOR) + if(void* p = mlock_allocator::instance().allocate(elems, elem_size)) + return p; +#endif + + void* ptr = std::calloc(elems, elem_size); + if(!ptr) + throw std::bad_alloc(); + return ptr; + } + +void deallocate_memory(void* p, size_t elems, size_t elem_size) + { + if(p == nullptr) + return; + + secure_scrub_memory(p, elems * elem_size); + +#if defined(BOTAN_HAS_LOCKING_ALLOCATOR) + if(mlock_allocator::instance().deallocate(p, elems, elem_size)) + return; +#endif + + std::free(p); + } + +void initialize_allocator() + { +#if defined(BOTAN_HAS_LOCKING_ALLOCATOR) + mlock_allocator::instance(); +#endif + } + +bool constant_time_compare(const uint8_t x[], + const uint8_t y[], + size_t len) + { + volatile uint8_t difference = 0; + + for(size_t i = 0; i != len; ++i) + difference |= (x[i] ^ y[i]); + + return difference == 0; + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/utils/mem_ops.h b/src/libs/3rdparty/botan/src/lib/utils/mem_ops.h new file mode 100644 index 0000000000..c59c02d5a5 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/utils/mem_ops.h @@ -0,0 +1,272 @@ +/* +* Memory Operations +* (C) 1999-2009,2012,2015 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_MEMORY_OPS_H_ +#define BOTAN_MEMORY_OPS_H_ + +#include +#include +#include + +namespace Botan { + +/** +* Allocate a memory buffer by some method. This should only be used for +* primitive types (uint8_t, uint32_t, etc). +* +* @param elems the number of elements +* @param elem_size the size of each element +* @return pointer to allocated and zeroed memory, or throw std::bad_alloc on failure +*/ +BOTAN_PUBLIC_API(2,3) BOTAN_MALLOC_FN void* allocate_memory(size_t elems, size_t elem_size); + +/** +* Free a pointer returned by allocate_memory +* @param p the pointer returned by allocate_memory +* @param elems the number of elements, as passed to allocate_memory +* @param elem_size the size of each element, as passed to allocate_memory +*/ +BOTAN_PUBLIC_API(2,3) void deallocate_memory(void* p, size_t elems, size_t elem_size); + +/** +* Ensure the allocator is initialized +*/ +void initialize_allocator(); + +class Allocator_Initializer + { + public: + Allocator_Initializer() { initialize_allocator(); } + }; + +/** +* Scrub memory contents in a way that a compiler should not elide, +* using some system specific technique. Note that this function might +* not zero the memory (for example, in some hypothetical +* implementation it might combine the memory contents with the output +* of a system PRNG), but if you can detect any difference in behavior +* at runtime then the clearing is side-effecting and you can just +* use `clear_mem`. +* +* Use this function to scrub memory just before deallocating it, or on +* a stack buffer before returning from the function. +* +* @param ptr a pointer to memory to scrub +* @param n the number of bytes pointed to by ptr +*/ +BOTAN_PUBLIC_API(2,0) void secure_scrub_memory(void* ptr, size_t n); + +/** +* Memory comparison, input insensitive +* @param x a pointer to an array +* @param y a pointer to another array +* @param len the number of Ts in x and y +* @return true iff x[i] == y[i] forall i in [0...n) +*/ +BOTAN_PUBLIC_API(2,3) bool constant_time_compare(const uint8_t x[], + const uint8_t y[], + size_t len); + +/** +* Zero out some bytes +* @param ptr a pointer to memory to zero +* @param bytes the number of bytes to zero in ptr +*/ +inline void clear_bytes(void* ptr, size_t bytes) + { + if(bytes > 0) + { + std::memset(ptr, 0, bytes); + } + } + +/** +* Zero memory before use. This simply calls memset and should not be +* used in cases where the compiler cannot see the call as a +* side-effecting operation (for example, if calling clear_mem before +* deallocating memory, the compiler would be allowed to omit the call +* to memset entirely under the as-if rule.) +* +* @param ptr a pointer to an array of Ts to zero +* @param n the number of Ts pointed to by ptr +*/ +template inline void clear_mem(T* ptr, size_t n) + { + clear_bytes(ptr, sizeof(T)*n); + } + +/** +* Copy memory +* @param out the destination array +* @param in the source array +* @param n the number of elements of in/out +*/ +template inline void copy_mem(T* out, const T* in, size_t n) + { + if(n > 0) + { + std::memmove(out, in, sizeof(T)*n); + } + } + +/** +* Set memory to a fixed value +* @param ptr a pointer to an array +* @param n the number of Ts pointed to by ptr +* @param val the value to set each byte to +*/ +template +inline void set_mem(T* ptr, size_t n, uint8_t val) + { + if(n > 0) + { + std::memset(ptr, val, sizeof(T)*n); + } + } + +inline const uint8_t* cast_char_ptr_to_uint8(const char* s) + { + return reinterpret_cast(s); + } + +inline const char* cast_uint8_ptr_to_char(const uint8_t* b) + { + return reinterpret_cast(b); + } + +inline uint8_t* cast_char_ptr_to_uint8(char* s) + { + return reinterpret_cast(s); + } + +inline char* cast_uint8_ptr_to_char(uint8_t* b) + { + return reinterpret_cast(b); + } + +/** +* Memory comparison, input insensitive +* @param p1 a pointer to an array +* @param p2 a pointer to another array +* @param n the number of Ts in p1 and p2 +* @return true iff p1[i] == p2[i] forall i in [0...n) +*/ +template inline bool same_mem(const T* p1, const T* p2, size_t n) + { + volatile T difference = 0; + + for(size_t i = 0; i != n; ++i) + difference |= (p1[i] ^ p2[i]); + + return difference == 0; + } + +/** +* XOR arrays. Postcondition out[i] = in[i] ^ out[i] forall i = 0...length +* @param out the input/output buffer +* @param in the read-only input buffer +* @param length the length of the buffers +*/ +inline void xor_buf(uint8_t out[], + const uint8_t in[], + size_t length) + { + while(length >= 16) + { + uint64_t x0, x1, y0, y1; + std::memcpy(&x0, in, 8); + std::memcpy(&x1, in + 8, 8); + std::memcpy(&y0, out, 8); + std::memcpy(&y1, out + 8, 8); + + y0 ^= x0; + y1 ^= x1; + std::memcpy(out, &y0, 8); + std::memcpy(out + 8, &y1, 8); + out += 16; in += 16; length -= 16; + } + + while(length > 0) + { + out[0] ^= in[0]; + out += 1; + in += 1; + length -= 1; + } + } + +/** +* XOR arrays. Postcondition out[i] = in[i] ^ in2[i] forall i = 0...length +* @param out the output buffer +* @param in the first input buffer +* @param in2 the second output buffer +* @param length the length of the three buffers +*/ +inline void xor_buf(uint8_t out[], + const uint8_t in[], + const uint8_t in2[], + size_t length) + { + while(length >= 16) + { + uint64_t x0, x1, y0, y1; + std::memcpy(&x0, in, 8); + std::memcpy(&x1, in + 8, 8); + std::memcpy(&y0, in2, 8); + std::memcpy(&y1, in2 + 8, 8); + + x0 ^= y0; + x1 ^= y1; + std::memcpy(out, &x0, 8); + std::memcpy(out + 8, &x1, 8); + out += 16; in += 16; in2 += 16; length -= 16; + } + + for(size_t i = 0; i != length; ++i) + out[i] = in[i] ^ in2[i]; + } + +template +void xor_buf(std::vector& out, + const std::vector& in, + size_t n) + { + xor_buf(out.data(), in.data(), n); + } + +template +void xor_buf(std::vector& out, + const uint8_t* in, + size_t n) + { + xor_buf(out.data(), in, n); + } + +template +void xor_buf(std::vector& out, + const uint8_t* in, + const std::vector& in2, + size_t n) + { + xor_buf(out.data(), in, in2.data(), n); + } + +template +std::vector& +operator^=(std::vector& out, + const std::vector& in) + { + if(out.size() < in.size()) + out.resize(in.size()); + + xor_buf(out.data(), in.data(), in.size()); + return out; + } + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/utils/mul128.h b/src/libs/3rdparty/botan/src/lib/utils/mul128.h new file mode 100644 index 0000000000..1e28082548 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/utils/mul128.h @@ -0,0 +1,123 @@ +/* +* 64x64->128 bit multiply operation +* (C) 2013,2015 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_UTIL_MUL128_H_ +#define BOTAN_UTIL_MUL128_H_ + +#include + +namespace Botan { + +#if defined(__SIZEOF_INT128__) && defined(BOTAN_TARGET_CPU_HAS_NATIVE_64BIT) && !defined(__xlc__) + #define BOTAN_TARGET_HAS_NATIVE_UINT128 + + // Prefer TI mode over __int128 as GCC rejects the latter in pendantic mode + #if defined(__GNUG__) + typedef unsigned int uint128_t __attribute__((mode(TI))); + #else + typedef unsigned __int128 uint128_t; + #endif +#endif + +} + +#if defined(BOTAN_TARGET_HAS_NATIVE_UINT128) + +#define BOTAN_FAST_64X64_MUL(a,b,lo,hi) \ + do { \ + const uint128_t r = static_cast(a) * b; \ + *hi = (r >> 64) & 0xFFFFFFFFFFFFFFFF; \ + *lo = (r ) & 0xFFFFFFFFFFFFFFFF; \ + } while(0) + +#elif defined(BOTAN_BUILD_COMPILER_IS_MSVC) && defined(BOTAN_TARGET_CPU_HAS_NATIVE_64BIT) + +#include +#pragma intrinsic(_umul128) + +#define BOTAN_FAST_64X64_MUL(a,b,lo,hi) \ + do { *lo = _umul128(a, b, hi); } while(0) + +#elif defined(BOTAN_USE_GCC_INLINE_ASM) + +#if defined(BOTAN_TARGET_ARCH_IS_X86_64) + +#define BOTAN_FAST_64X64_MUL(a,b,lo,hi) do { \ + asm("mulq %3" : "=d" (*hi), "=a" (*lo) : "a" (a), "rm" (b) : "cc"); \ + } while(0) + +#elif defined(BOTAN_TARGET_ARCH_IS_ALPHA) + +#define BOTAN_FAST_64X64_MUL(a,b,lo,hi) do { \ + asm("umulh %1,%2,%0" : "=r" (*hi) : "r" (a), "r" (b)); \ + *lo = a * b; \ +} while(0) + +#elif defined(BOTAN_TARGET_ARCH_IS_IA64) + +#define BOTAN_FAST_64X64_MUL(a,b,lo,hi) do { \ + asm("xmpy.hu %0=%1,%2" : "=f" (*hi) : "f" (a), "f" (b)); \ + *lo = a * b; \ +} while(0) + +#elif defined(BOTAN_TARGET_ARCH_IS_PPC64) + +#define BOTAN_FAST_64X64_MUL(a,b,lo,hi) do { \ + asm("mulhdu %0,%1,%2" : "=r" (*hi) : "r" (a), "r" (b) : "cc"); \ + *lo = a * b; \ +} while(0) + +#endif + +#endif + +namespace Botan { + +/** +* Perform a 64x64->128 bit multiplication +*/ +inline void mul64x64_128(uint64_t a, uint64_t b, uint64_t* lo, uint64_t* hi) + { +#if defined(BOTAN_FAST_64X64_MUL) + BOTAN_FAST_64X64_MUL(a, b, lo, hi); +#else + + /* + * Do a 64x64->128 multiply using four 32x32->64 multiplies plus + * some adds and shifts. Last resort for CPUs like UltraSPARC (with + * 64-bit registers/ALU, but no 64x64->128 multiply) or 32-bit CPUs. + */ + const size_t HWORD_BITS = 32; + const uint32_t HWORD_MASK = 0xFFFFFFFF; + + const uint32_t a_hi = (a >> HWORD_BITS); + const uint32_t a_lo = (a & HWORD_MASK); + const uint32_t b_hi = (b >> HWORD_BITS); + const uint32_t b_lo = (b & HWORD_MASK); + + uint64_t x0 = static_cast(a_hi) * b_hi; + uint64_t x1 = static_cast(a_lo) * b_hi; + uint64_t x2 = static_cast(a_hi) * b_lo; + uint64_t x3 = static_cast(a_lo) * b_lo; + + // this cannot overflow as (2^32-1)^2 + 2^32-1 < 2^64-1 + x2 += x3 >> HWORD_BITS; + + // this one can overflow + x2 += x1; + + // propagate the carry if any + x0 += static_cast(static_cast(x2 < x1)) << HWORD_BITS; + + *hi = x0 + (x2 >> HWORD_BITS); + *lo = ((x2 & HWORD_MASK) << HWORD_BITS) + (x3 & HWORD_MASK); +#endif + } + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/utils/mutex.h b/src/libs/3rdparty/botan/src/lib/utils/mutex.h new file mode 100644 index 0000000000..34fed5c81e --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/utils/mutex.h @@ -0,0 +1,58 @@ +/* +* (C) 2016 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_UTIL_MUTEX_H_ +#define BOTAN_UTIL_MUTEX_H_ + +#include + +#if defined(BOTAN_TARGET_OS_HAS_THREADS) + +#include + +namespace Botan { + +template using lock_guard_type = std::lock_guard; +typedef std::mutex mutex_type; + +} + +#else + +// No threads + +namespace Botan { + +template +class lock_guard final + { + public: + explicit lock_guard(Mutex& m) : m_mutex(m) + { m_mutex.lock(); } + + ~lock_guard() { m_mutex.unlock(); } + + lock_guard(const lock_guard& other) = delete; + lock_guard& operator=(const lock_guard& other) = delete; + private: + Mutex& m_mutex; + }; + +class noop_mutex final + { + public: + void lock() {} + void unlock() {} + }; + +typedef noop_mutex mutex_type; +template using lock_guard_type = lock_guard; + +} + +#endif + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/utils/os_utils.cpp b/src/libs/3rdparty/botan/src/lib/utils/os_utils.cpp new file mode 100644 index 0000000000..c7f04a8554 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/utils/os_utils.cpp @@ -0,0 +1,448 @@ +/* +* OS and machine specific utility functions +* (C) 2015,2016,2017 Jack Lloyd +* (C) 2016 Daniel Neus +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include + +#include +#include + +#if defined(BOTAN_TARGET_OS_HAS_EXPLICIT_BZERO) + #include +#endif + +#if defined(BOTAN_TARGET_OS_HAS_POSIX1) + #include + #include + #include + #include + #include + #include + #include +#elif defined(BOTAN_TARGET_OS_HAS_WIN32) + #define NOMINMAX 1 + #include +#endif + +namespace Botan { + +// Not defined in OS namespace for historical reasons +void secure_scrub_memory(void* ptr, size_t n) + { +#if defined(BOTAN_TARGET_OS_HAS_RTLSECUREZEROMEMORY) + ::RtlSecureZeroMemory(ptr, n); + +#elif defined(BOTAN_TARGET_OS_HAS_EXPLICIT_BZERO) + ::explicit_bzero(ptr, n); + +#elif defined(BOTAN_USE_VOLATILE_MEMSET_FOR_ZERO) && (BOTAN_USE_VOLATILE_MEMSET_FOR_ZERO == 1) + /* + Call memset through a static volatile pointer, which the compiler + should not elide. This construct should be safe in conforming + compilers, but who knows. I did confirm that on x86-64 GCC 6.1 and + Clang 3.8 both create code that saves the memset address in the + data segment and uncondtionally loads and jumps to that address. + */ + static void* (*const volatile memset_ptr)(void*, int, size_t) = std::memset; + (memset_ptr)(ptr, 0, n); +#else + + volatile uint8_t* p = reinterpret_cast(ptr); + + for(size_t i = 0; i != n; ++i) + p[i] = 0; +#endif + } + +uint32_t OS::get_process_id() + { +#if defined(BOTAN_TARGET_OS_HAS_POSIX1) + return ::getpid(); +#elif defined(BOTAN_TARGET_OS_HAS_WIN32) + return ::GetCurrentProcessId(); +#elif defined(BOTAN_TARGET_OS_IS_INCLUDEOS) || defined(BOTAN_TARGET_OS_IS_LLVM) + return 0; // truly no meaningful value +#else + #error "Missing get_process_id" +#endif + } + +uint64_t OS::get_processor_timestamp() + { + uint64_t rtc = 0; + +#if defined(BOTAN_TARGET_OS_HAS_WIN32) + LARGE_INTEGER tv; + ::QueryPerformanceCounter(&tv); + rtc = tv.QuadPart; + +#elif defined(BOTAN_USE_GCC_INLINE_ASM) + +#if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY) + + if(CPUID::has_rdtsc()) + { + uint32_t rtc_low = 0, rtc_high = 0; + asm volatile("rdtsc" : "=d" (rtc_high), "=a" (rtc_low)); + rtc = (static_cast(rtc_high) << 32) | rtc_low; + } + +#elif defined(BOTAN_TARGET_ARCH_IS_PPC64) + + for(;;) + { + uint32_t rtc_low = 0, rtc_high = 0, rtc_high2 = 0; + asm volatile("mftbu %0" : "=r" (rtc_high)); + asm volatile("mftb %0" : "=r" (rtc_low)); + asm volatile("mftbu %0" : "=r" (rtc_high2)); + + if(rtc_high == rtc_high2) + { + rtc = (static_cast(rtc_high) << 32) | rtc_low; + break; + } + } + +#elif defined(BOTAN_TARGET_ARCH_IS_ALPHA) + asm volatile("rpcc %0" : "=r" (rtc)); + + // OpenBSD does not trap access to the %tick register +#elif defined(BOTAN_TARGET_ARCH_IS_SPARC64) && !defined(BOTAN_TARGET_OS_IS_OPENBSD) + asm volatile("rd %%tick, %0" : "=r" (rtc)); + +#elif defined(BOTAN_TARGET_ARCH_IS_IA64) + asm volatile("mov %0=ar.itc" : "=r" (rtc)); + +#elif defined(BOTAN_TARGET_ARCH_IS_S390X) + asm volatile("stck 0(%0)" : : "a" (&rtc) : "memory", "cc"); + +#elif defined(BOTAN_TARGET_ARCH_IS_HPPA) + asm volatile("mfctl 16,%0" : "=r" (rtc)); // 64-bit only? + +#else + //#warning "OS::get_processor_timestamp not implemented" +#endif + +#endif + + return rtc; + } + +uint64_t OS::get_high_resolution_clock() + { + if(uint64_t cpu_clock = OS::get_processor_timestamp()) + return cpu_clock; + + /* + If we got here either we either don't have an asm instruction + above, or (for x86) RDTSC is not available at runtime. Try some + clock_gettimes and return the first one that works, or otherwise + fall back to std::chrono. + */ + +#if defined(BOTAN_TARGET_OS_HAS_CLOCK_GETTIME) + + // The ordering here is somewhat arbitrary... + const clockid_t clock_types[] = { +#if defined(CLOCK_MONOTONIC_HR) + CLOCK_MONOTONIC_HR, +#endif +#if defined(CLOCK_MONOTONIC_RAW) + CLOCK_MONOTONIC_RAW, +#endif +#if defined(CLOCK_MONOTONIC) + CLOCK_MONOTONIC, +#endif +#if defined(CLOCK_PROCESS_CPUTIME_ID) + CLOCK_PROCESS_CPUTIME_ID, +#endif +#if defined(CLOCK_THREAD_CPUTIME_ID) + CLOCK_THREAD_CPUTIME_ID, +#endif + }; + + for(clockid_t clock : clock_types) + { + struct timespec ts; + if(::clock_gettime(clock, &ts) == 0) + { + return (static_cast(ts.tv_sec) * 1000000000) + static_cast(ts.tv_nsec); + } + } +#endif + + // Plain C++11 fallback + auto now = std::chrono::high_resolution_clock::now().time_since_epoch(); + return std::chrono::duration_cast(now).count(); + } + +uint64_t OS::get_system_timestamp_ns() + { +#if defined(BOTAN_TARGET_OS_HAS_CLOCK_GETTIME) + struct timespec ts; + if(::clock_gettime(CLOCK_REALTIME, &ts) == 0) + { + return (static_cast(ts.tv_sec) * 1000000000) + static_cast(ts.tv_nsec); + } +#endif + + auto now = std::chrono::system_clock::now().time_since_epoch(); + return std::chrono::duration_cast(now).count(); + } + +size_t OS::system_page_size() + { +#if defined(BOTAN_TARGET_OS_HAS_POSIX1) + long p = ::sysconf(_SC_PAGESIZE); + if(p > 1) + return static_cast(p); + else + return 4096; +#elif defined(BOTAN_TARGET_OS_HAS_VIRTUAL_LOCK) + SYSTEM_INFO sys_info; + ::GetSystemInfo(&sys_info); + return sys_info.dwPageSize; +#endif + + // default value + return 4096; + } + +size_t OS::get_memory_locking_limit() + { +#if defined(BOTAN_TARGET_OS_HAS_POSIX1) + /* + * 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 + * enough to run the entire test suite without spilling to non-mlock + * memory (and thus presumably also enough for many useful + * programs), but small enough that we should not cause problems + * even if many processes are mlocking on the same machine. + */ + size_t mlock_requested = BOTAN_MLOCK_ALLOCATOR_MAX_LOCKED_KB; + + /* + * Allow override via env variable + */ + if(const char* env = std::getenv("BOTAN_MLOCK_POOL_SIZE")) + { + try + { + const size_t user_req = std::stoul(env, nullptr); + mlock_requested = std::min(user_req, mlock_requested); + } + catch(std::exception&) { /* ignore it */ } + } + +#if defined(RLIMIT_MEMLOCK) + if(mlock_requested > 0) + { + struct ::rlimit limits; + + ::getrlimit(RLIMIT_MEMLOCK, &limits); + + if(limits.rlim_cur < limits.rlim_max) + { + limits.rlim_cur = limits.rlim_max; + ::setrlimit(RLIMIT_MEMLOCK, &limits); + ::getrlimit(RLIMIT_MEMLOCK, &limits); + } + + return std::min(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; + if(!::GetProcessWorkingSetSize(::GetCurrentProcess(), &working_min, &working_max)) + { + return 0; + } + + // According to Microsoft MSDN: + // The maximum number of pages that a process can lock is equal to the number of pages in its minimum working set minus a small overhead + // In the book "Windows Internals Part 2": the maximum lockable pages are minimum working set size - 8 pages + // But the information in the book seems to be inaccurate/outdated + // I've tested this on Windows 8.1 x64, Windows 10 x64 and Windows 7 x86 + // On all three OS the value is 11 instead of 8 + size_t overhead = OS::system_page_size() * 11ULL; + if(working_min > overhead) + { + size_t lockable_bytes = working_min - overhead; + if(lockable_bytes < (BOTAN_MLOCK_ALLOCATOR_MAX_LOCKED_KB * 1024ULL)) + { + return lockable_bytes; + } + else + { + return BOTAN_MLOCK_ALLOCATOR_MAX_LOCKED_KB * 1024ULL; + } + } +#endif + + return 0; + } + +void* OS::allocate_locked_pages(size_t length) + { +#if defined(BOTAN_TARGET_OS_HAS_POSIX1) + +#if !defined(MAP_NOCORE) + #define MAP_NOCORE 0 +#endif + +#if !defined(MAP_ANONYMOUS) + #define MAP_ANONYMOUS MAP_ANON +#endif + + void* ptr = ::mmap(nullptr, + length, + PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_SHARED | MAP_NOCORE, + /*fd*/-1, + /*offset*/0); + + if(ptr == MAP_FAILED) + { + return nullptr; + } + +#if defined(MADV_DONTDUMP) + ::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); + + return ptr; +#elif defined(BOTAN_TARGET_OS_HAS_VIRTUAL_LOCK) + LPVOID ptr = ::VirtualAlloc(nullptr, length, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); + if(!ptr) + { + return nullptr; + } + + if(::VirtualLock(ptr, length) == 0) + { + ::VirtualFree(ptr, 0, MEM_RELEASE); + return nullptr; // failed to lock + } + + return ptr; +#else + BOTAN_UNUSED(length); + return nullptr; /* not implemented */ +#endif + } + +void OS::free_locked_pages(void* ptr, size_t length) + { + if(ptr == nullptr || length == 0) + return; + +#if defined(BOTAN_TARGET_OS_HAS_POSIX1) + 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"); +#endif + } + +#if defined(BOTAN_TARGET_OS_HAS_POSIX1) +namespace { + +static ::sigjmp_buf g_sigill_jmp_buf; + +void botan_sigill_handler(int) + { + siglongjmp(g_sigill_jmp_buf, /*non-zero return value*/1); + } + +} +#endif + +int OS::run_cpu_instruction_probe(std::function probe_fn) + { + volatile int probe_result = -3; + +#if defined(BOTAN_TARGET_OS_HAS_POSIX1) + struct sigaction old_sigaction; + struct sigaction sigaction; + + sigaction.sa_handler = botan_sigill_handler; + sigemptyset(&sigaction.sa_mask); + sigaction.sa_flags = 0; + + int rc = ::sigaction(SIGILL, &sigaction, &old_sigaction); + + if(rc != 0) + throw Exception("run_cpu_instruction_probe sigaction failed"); + + rc = sigsetjmp(g_sigill_jmp_buf, /*save sigs*/1); + + if(rc == 0) + { + // first call to sigsetjmp + probe_result = probe_fn(); + } + else if(rc == 1) + { + // non-local return from siglongjmp in signal handler: return error + probe_result = -1; + } + + // Restore old SIGILL handler, if any + rc = ::sigaction(SIGILL, &old_sigaction, nullptr); + if(rc != 0) + throw Exception("run_cpu_instruction_probe sigaction restore failed"); + +#elif defined(BOTAN_TARGET_OS_IS_WINDOWS) && defined(BOTAN_TARGET_COMPILER_IS_MSVC) + + // Windows SEH + __try + { + probe_result = probe_fn(); + } + __except(::GetExceptionCode() == EXCEPTION_ILLEGAL_INSTRUCTION ? + EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) + { + probe_result = -1; + } + +#endif + + return probe_result; + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/utils/os_utils.h b/src/libs/3rdparty/botan/src/lib/utils/os_utils.h new file mode 100644 index 0000000000..5210b2523b --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/utils/os_utils.h @@ -0,0 +1,118 @@ +/* +* OS specific utility functions +* (C) 2015,2016,2017 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_OS_UTILS_H_ +#define BOTAN_OS_UTILS_H_ + +#include +#include + +namespace Botan { + +namespace OS { + +/* +* This header is internal (not installed) and these functions are not +* intended to be called by applications. However they are given public +* visibility (using BOTAN_TEST_API macro) for the tests. This also probably +* allows them to be overridden by the application on ELF systems, but +* this hasn't been tested. +*/ + +/** +* @return process ID assigned by the operating system. +* On Unix and Windows systems, this always returns a result +* On IncludeOS it returns 0 since there is no process ID to speak of +* in a unikernel. +*/ +uint32_t BOTAN_TEST_API get_process_id(); + +/** +* @return CPU processor clock, if available +* +* On Windows, calls QueryPerformanceCounter. +* +* Under GCC or Clang on supported platforms the hardware cycle counter is queried. +* Currently supported processors are x86, PPC, Alpha, SPARC, IA-64, S/390x, and HP-PA. +* If no CPU cycle counter is available on this system, returns zero. +*/ +uint64_t BOTAN_TEST_API get_processor_timestamp(); + +/* +* @return best resolution timestamp available +* +* The epoch and update rate of this clock is arbitrary and depending +* on the hardware it may not tick at a constant rate. +* +* Uses hardware cycle counter, if available. +* On POSIX platforms clock_gettime is used with a monotonic timer +* As a final fallback std::chrono::high_resolution_clock is used. +*/ +uint64_t BOTAN_TEST_API get_high_resolution_clock(); + +/** +* @return system clock (reflecting wall clock) with best resolution +* available, normalized to nanoseconds resolution. +*/ +uint64_t BOTAN_TEST_API get_system_timestamp_ns(); + +/** +* @return maximum amount of memory (in bytes) Botan could/should +* hyptothetically allocate for the memory poool. Reads environment +* variable "BOTAN_MLOCK_POOL_SIZE", set to "0" to disable pool. +*/ +size_t get_memory_locking_limit(); + +/** +* Return the size of a memory page, if that can be derived on the +* current system. Otherwise returns some default value (eg 4096) +*/ +size_t system_page_size(); + +/** +* Request so many bytes of page-aligned RAM locked into memory using +* mlock, VirtualLock, or similar. Returns null on failure. The memory +* returned is zeroed. Free it with free_locked_pages. +* @param length requested allocation in bytes +*/ +void* allocate_locked_pages(size_t length); + +/** +* Free memory allocated by allocate_locked_pages +* @param ptr a pointer returned by allocate_locked_pages +* @param length length passed to allocate_locked_pages +*/ +void free_locked_pages(void* ptr, size_t length); + +/** +* Run a probe instruction to test for support for a CPU instruction. +* Runs in system-specific env that catches illegal instructions; this +* function always fails if the OS doesn't provide this. +* Returns value of probe_fn, if it could run. +* If error occurs, returns negative number. +* This allows probe_fn to indicate errors of its own, if it wants. +* For example the instruction might not only be only available on some +* CPUs, but also buggy on some subset of these - the probe function +* can test to make sure the instruction works properly before +* indicating that the instruction is available. +* +* @warning on Unix systems uses signal handling in a way that is not +* thread safe. It should only be called in a single-threaded context +* (ie, at static init time). +* +* If probe_fn throws an exception the result is undefined. +* +* Return codes: +* -1 illegal instruction detected +*/ +int BOTAN_TEST_API run_cpu_instruction_probe(std::function probe_fn); + +} + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/utils/parsing.cpp b/src/libs/3rdparty/botan/src/lib/utils/parsing.cpp new file mode 100644 index 0000000000..cfae0cb708 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/utils/parsing.cpp @@ -0,0 +1,477 @@ +/* +* Various string utils and parsing functions +* (C) 1999-2007,2013,2014,2015,2018 Jack Lloyd +* (C) 2015 Simon Warta (Kullo GmbH) +* (C) 2017 René Korthaus, Rohde & Schwarz Cybersecurity +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Botan { + +uint16_t to_uint16(const std::string& str) + { + const uint32_t x = to_u32bit(str); + + if(x >> 16) + throw Invalid_Argument("Integer value exceeds 16 bit range"); + + return static_cast(x); + } + +uint32_t to_u32bit(const std::string& str) + { + // std::stoul is not strict enough. Ensure that str is digit only [0-9]* + for(const char chr : str) + { + if(chr < '0' || chr > '9') + { + std::string chrAsString(1, chr); + throw Invalid_Argument("String contains non-digit char: " + chrAsString); + } + } + + const unsigned long int x = std::stoul(str); + + if(sizeof(unsigned long int) > 4) + { + // x might be uint64 + if (x > std::numeric_limits::max()) + { + throw Invalid_Argument("Integer value of " + str + " exceeds 32 bit range"); + } + } + + return static_cast(x); + } + +/* +* Convert a string into a time duration +*/ +uint32_t timespec_to_u32bit(const std::string& timespec) + { + if(timespec.empty()) + return 0; + + const char suffix = timespec[timespec.size()-1]; + std::string value = timespec.substr(0, timespec.size()-1); + + uint32_t scale = 1; + + if(Charset::is_digit(suffix)) + value += suffix; + else if(suffix == 's') + scale = 1; + else if(suffix == 'm') + scale = 60; + else if(suffix == 'h') + scale = 60 * 60; + else if(suffix == 'd') + scale = 24 * 60 * 60; + else if(suffix == 'y') + scale = 365 * 24 * 60 * 60; + else + throw Decoding_Error("timespec_to_u32bit: Bad input " + timespec); + + return scale * to_u32bit(value); + } + +/* +* Parse a SCAN-style algorithm name +*/ +std::vector parse_algorithm_name(const std::string& namex) + { + if(namex.find('(') == std::string::npos && + namex.find(')') == std::string::npos) + return std::vector(1, namex); + + std::string name = namex, substring; + std::vector elems; + size_t level = 0; + + elems.push_back(name.substr(0, name.find('('))); + name = name.substr(name.find('(')); + + for(auto i = name.begin(); i != name.end(); ++i) + { + char c = *i; + + if(c == '(') + ++level; + if(c == ')') + { + if(level == 1 && i == name.end() - 1) + { + if(elems.size() == 1) + elems.push_back(substring.substr(1)); + else + elems.push_back(substring); + return elems; + } + + if(level == 0 || (level == 1 && i != name.end() - 1)) + throw Invalid_Algorithm_Name(namex); + --level; + } + + if(c == ',' && level == 1) + { + if(elems.size() == 1) + elems.push_back(substring.substr(1)); + else + elems.push_back(substring); + substring.clear(); + } + else + substring += c; + } + + if(!substring.empty()) + throw Invalid_Algorithm_Name(namex); + + return elems; + } + +std::vector split_on(const std::string& str, char delim) + { + return split_on_pred(str, [delim](char c) { return c == delim; }); + } + +std::vector split_on_pred(const std::string& str, + std::function pred) + { + std::vector elems; + if(str.empty()) return elems; + + std::string substr; + for(auto i = str.begin(); i != str.end(); ++i) + { + if(pred(*i)) + { + if(!substr.empty()) + elems.push_back(substr); + substr.clear(); + } + else + substr += *i; + } + + if(substr.empty()) + throw Invalid_Argument("Unable to split string: " + str); + elems.push_back(substr); + + return elems; + } + +/* +* Join a string +*/ +std::string string_join(const std::vector& strs, char delim) + { + std::string out = ""; + + for(size_t i = 0; i != strs.size(); ++i) + { + if(i != 0) + out += delim; + out += strs[i]; + } + + return out; + } + +/* +* Parse an ASN.1 OID string +*/ +std::vector parse_asn1_oid(const std::string& oid) + { + std::string substring; + std::vector oid_elems; + + for(auto i = oid.begin(); i != oid.end(); ++i) + { + char c = *i; + + if(c == '.') + { + if(substring.empty()) + throw Invalid_OID(oid); + oid_elems.push_back(to_u32bit(substring)); + substring.clear(); + } + else + substring += c; + } + + if(substring.empty()) + throw Invalid_OID(oid); + oid_elems.push_back(to_u32bit(substring)); + + if(oid_elems.size() < 2) + throw Invalid_OID(oid); + + return oid_elems; + } + +/* +* X.500 String Comparison +*/ +bool x500_name_cmp(const std::string& name1, const std::string& name2) + { + auto p1 = name1.begin(); + auto p2 = name2.begin(); + + while((p1 != name1.end()) && Charset::is_space(*p1)) ++p1; + while((p2 != name2.end()) && Charset::is_space(*p2)) ++p2; + + while(p1 != name1.end() && p2 != name2.end()) + { + if(Charset::is_space(*p1)) + { + if(!Charset::is_space(*p2)) + return false; + + while((p1 != name1.end()) && Charset::is_space(*p1)) ++p1; + while((p2 != name2.end()) && Charset::is_space(*p2)) ++p2; + + if(p1 == name1.end() && p2 == name2.end()) + return true; + if(p1 == name1.end() || p2 == name2.end()) + return false; + } + + if(!Charset::caseless_cmp(*p1, *p2)) + return false; + ++p1; + ++p2; + } + + while((p1 != name1.end()) && Charset::is_space(*p1)) ++p1; + while((p2 != name2.end()) && Charset::is_space(*p2)) ++p2; + + if((p1 != name1.end()) || (p2 != name2.end())) + return false; + return true; + } + +/* +* Convert a decimal-dotted string to binary IP +*/ +uint32_t string_to_ipv4(const std::string& str) + { + std::vector parts = split_on(str, '.'); + + if(parts.size() != 4) + throw Decoding_Error("Invalid IP string " + str); + + uint32_t ip = 0; + + for(auto part = parts.begin(); part != parts.end(); ++part) + { + uint32_t octet = to_u32bit(*part); + + if(octet > 255) + throw Decoding_Error("Invalid IP string " + str); + + ip = (ip << 8) | (octet & 0xFF); + } + + return ip; + } + +/* +* Convert an IP address to decimal-dotted string +*/ +std::string ipv4_to_string(uint32_t ip) + { + std::string str; + + for(size_t i = 0; i != sizeof(ip); ++i) + { + if(i) + str += "."; + str += std::to_string(get_byte(i, ip)); + } + + return str; + } + +std::string erase_chars(const std::string& str, const std::set& chars) + { + std::string out; + + for(auto c: str) + if(chars.count(c) == 0) + out += c; + + return out; + } + +std::string replace_chars(const std::string& str, + const std::set& chars, + char to_char) + { + std::string out = str; + + for(size_t i = 0; i != out.size(); ++i) + if(chars.count(out[i])) + out[i] = to_char; + + return out; + } + +std::string replace_char(const std::string& str, char from_char, char to_char) + { + std::string out = str; + + for(size_t i = 0; i != out.size(); ++i) + if(out[i] == from_char) + out[i] = to_char; + + return out; + } + +namespace { + +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(s[i]))) + s[i] = std::tolower(static_cast(s[i])); + } + return s; + } + +} + +bool host_wildcard_match(const std::string& issued_, const std::string& host_) + { + const std::string issued = tolower_string(issued_); + const std::string host = tolower_string(host_); + + if(host.empty() || issued.empty()) + return false; + + /* + If there are embedded nulls in your issued name + Well I feel bad for you son + */ + if(std::count(issued.begin(), issued.end(), char(0)) > 0) + return false; + + // If more than one wildcard, then issued name is invalid + const size_t stars = std::count(issued.begin(), issued.end(), '*'); + if(stars > 1) + return false; + + // '*' is not a valid character in DNS names so should not appear on the host side + if(std::count(host.begin(), host.end(), '*') != 0) + return false; + + // Similarly a DNS name can't end in . + if(host[host.size() - 1] == '.') + return false; + + // And a host can't have an empty name component, so reject that + if(host.find("..") != std::string::npos) + return false; + + // Exact match: accept + if(issued == host) + { + return true; + } + + /* + Otherwise it might be a wildcard + + If the issued size is strictly longer than the hostname size it + couldn't possibly be a match, even if the issued value is a + wildcard. The only exception is when the wildcard ends up empty + (eg www.example.com matches www*.example.com) + */ + if(issued.size() > host.size() + 1) + { + return false; + } + + // If no * at all then not a wildcard, and so not a match + if(stars != 1) + { + return false; + } + + /* + 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 + space the wildcard takes because it must be exactly `len(host) - + len(issued) + 1 chars`. + + We also verify that the '*' comes in the leftmost component, and + doesn't skip over any '.' in the hostname. + */ + size_t dots_seen = 0; + size_t host_idx = 0; + + for(size_t i = 0; i != issued.size(); ++i) + { + dots_seen += (issued[i] == '.'); + + if(issued[i] == '*') + { + // Fail: wildcard can only come in leftmost component + if(dots_seen > 0) + { + return false; + } + + /* + Since there is only one * we know the tail of the issued and + hostname must be an exact match. In this case advance host_idx + to match. + */ + const size_t advance = (host.size() - issued.size() + 1); + + if(host_idx + advance > host.size()) // shouldn't happen + return false; + + // Can't be any intervening .s that we would have skipped + if(std::count(host.begin() + host_idx, + host.begin() + host_idx + advance, '.') != 0) + return false; + + host_idx += advance; + } + else + { + if(issued[i] != host[host_idx]) + { + return false; + } + + host_idx += 1; + } + } + + // Wildcard issued name must have at least 3 components + if(dots_seen < 2) + { + return false; + } + + return true; + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/utils/parsing.h b/src/libs/3rdparty/botan/src/lib/utils/parsing.h new file mode 100644 index 0000000000..9185cfaadf --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/utils/parsing.h @@ -0,0 +1,153 @@ +/* +* Various string utils and parsing functions +* (C) 1999-2007,2013 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_PARSER_H_ +#define BOTAN_PARSER_H_ + +#include +#include +#include +#include + +#include +#include +#include + +namespace Botan { + +/** +* Parse a SCAN-style algorithm name +* @param scan_name the name +* @return the name components +*/ +BOTAN_PUBLIC_API(2,0) std::vector +parse_algorithm_name(const std::string& scan_name); + +/** +* Split a string +* @param str the input string +* @param delim the delimitor +* @return string split by delim +*/ +BOTAN_PUBLIC_API(2,0) std::vector split_on( + const std::string& str, char delim); + +/** +* Split a string on a character predicate +* @param str the input string +* @param pred the predicate +*/ +BOTAN_PUBLIC_API(2,0) std::vector +split_on_pred(const std::string& str, + std::function pred); + +/** +* Erase characters from a string +*/ +BOTAN_PUBLIC_API(2,0) +BOTAN_DEPRECATED("Unused") +std::string erase_chars(const std::string& str, const std::set& chars); + +/** +* Replace a character in a string +* @param str the input string +* @param from_char the character to replace +* @param to_char the character to replace it with +* @return str with all instances of from_char replaced by to_char +*/ +BOTAN_PUBLIC_API(2,0) +BOTAN_DEPRECATED("Unused") +std::string replace_char(const std::string& str, + char from_char, + char to_char); + +/** +* Replace a character in a string +* @param str the input string +* @param from_chars the characters to replace +* @param to_char the character to replace it with +* @return str with all instances of from_chars replaced by to_char +*/ +BOTAN_PUBLIC_API(2,0) +BOTAN_DEPRECATED("Unused") +std::string replace_chars(const std::string& str, + const std::set& from_chars, + char to_char); + +/** +* Join a string +* @param strs strings to join +* @param delim the delimitor +* @return string joined by delim +*/ +BOTAN_PUBLIC_API(2,0) +std::string string_join(const std::vector& strs, + char delim); + +/** +* Parse an ASN.1 OID +* @param oid the OID in string form +* @return OID components +*/ +BOTAN_PUBLIC_API(2,0) std::vector parse_asn1_oid(const std::string& oid); + +/** +* Compare two names using the X.509 comparison algorithm +* @param name1 the first name +* @param name2 the second name +* @return true if name1 is the same as name2 by the X.509 comparison rules +*/ +BOTAN_PUBLIC_API(2,0) +bool x500_name_cmp(const std::string& name1, + const std::string& name2); + +/** +* Convert a string to a number +* @param str the string to convert +* @return number value of the string +*/ +BOTAN_PUBLIC_API(2,0) uint32_t to_u32bit(const std::string& str); + +/** +* Convert a string to a number +* @param str the string to convert +* @return number value of the string +*/ +BOTAN_PUBLIC_API(2,3) uint16_t to_uint16(const std::string& str); + +/** +* Convert a time specification to a number +* @param timespec the time specification +* @return number of seconds represented by timespec +*/ +BOTAN_PUBLIC_API(2,0) uint32_t BOTAN_DEPRECATED("Not used anymore") +timespec_to_u32bit(const std::string& timespec); + +/** +* Convert a string representation of an IPv4 address to a number +* @param ip_str the string representation +* @return integer IPv4 address +*/ +BOTAN_PUBLIC_API(2,0) uint32_t string_to_ipv4(const std::string& ip_str); + +/** +* Convert an IPv4 address to a string +* @param ip_addr the IPv4 address to convert +* @return string representation of the IPv4 address +*/ +BOTAN_PUBLIC_API(2,0) std::string ipv4_to_string(uint32_t ip_addr); + +std::map BOTAN_PUBLIC_API(2,0) read_cfg(std::istream& is); + +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); + + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/utils/prefetch.h b/src/libs/3rdparty/botan/src/lib/utils/prefetch.h new file mode 100644 index 0000000000..92c41e5738 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/utils/prefetch.h @@ -0,0 +1,39 @@ +/* +* Prefetching Operations +* (C) 2009 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_PREFETCH_H_ +#define BOTAN_PREFETCH_H_ + +#include + +namespace Botan { + +template +inline void prefetch_readonly(const T* addr, size_t length) + { +#if defined(__GNUG__) + const size_t Ts_per_cache_line = CPUID::cache_line_size() / sizeof(T); + + for(size_t i = 0; i <= length; i += Ts_per_cache_line) + __builtin_prefetch(addr + i, 0); +#endif + } + +template +inline void prefetch_readwrite(const T* addr, size_t length) + { +#if defined(__GNUG__) + const size_t Ts_per_cache_line = CPUID::cache_line_size() / sizeof(T); + + for(size_t i = 0; i <= length; i += Ts_per_cache_line) + __builtin_prefetch(addr + i, 1); +#endif + } + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/utils/read_cfg.cpp b/src/libs/3rdparty/botan/src/lib/utils/read_cfg.cpp new file mode 100644 index 0000000000..bf68c04792 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/utils/read_cfg.cpp @@ -0,0 +1,63 @@ +/* +* Simple config/test file reader +* (C) 2013,2014,2015 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include + +namespace Botan { + +std::string clean_ws(const std::string& s) + { + const char* ws = " \t\n"; + auto start = s.find_first_not_of(ws); + auto end = s.find_last_not_of(ws); + + if(start == std::string::npos) + return ""; + + if(end == std::string::npos) + return s.substr(start, end); + else + return s.substr(start, start + end + 1); + } + +std::map read_cfg(std::istream& is) + { + std::map kv; + size_t line = 0; + + while(is.good()) + { + std::string s; + + std::getline(is, s); + + ++line; + + if(s.empty() || s[0] == '#') + continue; + + s = clean_ws(s.substr(0, s.find('#'))); + + if(s.empty()) + continue; + + auto eq = s.find("="); + + if(eq == std::string::npos || eq == 0 || eq == s.size() - 1) + throw Exception("Bad read_cfg input '" + s + "' on line " + std::to_string(line)); + + const std::string key = clean_ws(s.substr(0, eq)); + const std::string val = clean_ws(s.substr(eq + 1, std::string::npos)); + + kv[key] = val; + } + + return kv; + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/utils/rotate.h b/src/libs/3rdparty/botan/src/lib/utils/rotate.h new file mode 100644 index 0000000000..4bb76c9ed4 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/utils/rotate.h @@ -0,0 +1,104 @@ +/* +* Word Rotation Operations +* (C) 1999-2008,2017 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_WORD_ROTATE_H_ +#define BOTAN_WORD_ROTATE_H_ + +#include + +namespace Botan { + +/** +* Bit rotation left by a compile-time constant amount +* @param input the input word +* @return input rotated left by ROT bits +*/ +template +inline T rotl(T input) + { + static_assert(ROT > 0 && ROT < 8*sizeof(T), "Invalid rotation constant"); + return static_cast((input << ROT) | (input >> (8*sizeof(T) - ROT))); + } + +/** +* Bit rotation right by a compile-time constant amount +* @param input the input word +* @return input rotated right by ROT bits +*/ +template +inline T rotr(T input) + { + static_assert(ROT > 0 && ROT < 8*sizeof(T), "Invalid rotation constant"); + return static_cast((input >> ROT) | (input << (8*sizeof(T) - ROT))); + } + +/** +* Bit rotation left, variable rotation amount +* @param input the input word +* @param rot the number of bits to rotate, must be between 0 and sizeof(T)*8-1 +* @return input rotated left by rot bits +*/ +template +inline T rotl_var(T input, size_t rot) + { + return rot ? static_cast((input << rot) | (input >> (sizeof(T)*8 - rot))) : input; + } + +/** +* Bit rotation right, variable rotation amount +* @param input the input word +* @param rot the number of bits to rotate, must be between 0 and sizeof(T)*8-1 +* @return input rotated right by rot bits +*/ +template +inline T rotr_var(T input, size_t rot) + { + return rot ? static_cast((input >> rot) | (input << (sizeof(T)*8 - rot))) : input; + } + +#if BOTAN_USE_GCC_INLINE_ASM + +#if defined(BOTAN_TARGET_ARCH_IS_X86_64) || defined(BOTAN_TARGET_ARCH_IS_X86_32) + +template<> +inline uint32_t rotl_var(uint32_t input, size_t rot) + { + asm("roll %1,%0" : "+r" (input) : "c" (static_cast(rot))); + return input; + } + +template<> +inline uint32_t rotr_var(uint32_t input, size_t rot) + { + asm("rorl %1,%0" : "+r" (input) : "c" (static_cast(rot))); + return input; + } + +#endif + +#endif + + +template +BOTAN_DEPRECATED("Use rotl or rotl_var") +inline T rotate_left(T input, size_t rot) + { + // rotl_var does not reduce + return rotl_var(input, rot % (8 * sizeof(T))); + } + +template +BOTAN_DEPRECATED("Use rotr or rotr_var") +inline T rotate_right(T input, size_t rot) + { + // rotr_var does not reduce + return rotr_var(input, rot % (8 * sizeof(T))); + } + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/utils/rounding.h b/src/libs/3rdparty/botan/src/lib/utils/rounding.h new file mode 100644 index 0000000000..a03e3a4ee2 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/utils/rounding.h @@ -0,0 +1,59 @@ +/* +* Integer Rounding Functions +* (C) 1999-2007 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_ROUNDING_H_ +#define BOTAN_ROUNDING_H_ + +#include + +namespace Botan { + +/** +* Round up +* @param n a non-negative integer +* @param align_to the alignment boundary +* @return n rounded up to a multiple of align_to +*/ +inline size_t round_up(size_t n, size_t align_to) + { + BOTAN_ARG_CHECK(align_to != 0, "align_to must not be 0"); + + if(n % align_to) + n += align_to - (n % align_to); + return n; + } + +/** +* Round down +* @param n an integer +* @param align_to the alignment boundary +* @return n rounded down to a multiple of align_to +*/ +template +inline T round_down(T n, T align_to) + { + if(align_to == 0) + return n; + + return (n - (n % align_to)); + } + +/** +* Clamp +*/ +inline size_t clamp(size_t n, size_t lower_bound, size_t upper_bound) + { + if(n < lower_bound) + return lower_bound; + if(n > upper_bound) + return upper_bound; + return n; + } + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/utils/safeint.h b/src/libs/3rdparty/botan/src/lib/utils/safeint.h new file mode 100644 index 0000000000..377f134187 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/utils/safeint.h @@ -0,0 +1,39 @@ +/* +* Safe(r) Integer Handling +* (C) 2016 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_UTILS_SAFE_INT_H_ +#define BOTAN_UTILS_SAFE_INT_H_ + +#include +#include + +namespace Botan { + +class BOTAN_PUBLIC_API(2,0) Integer_Overflow_Detected final : public Exception + { + public: + Integer_Overflow_Detected(const std::string& file, int line) : + Exception("Integer overflow detected at " + file + ":" + std::to_string(line)) + {} + }; + +inline size_t checked_add(size_t x, size_t y, const char* file, int line) + { + // TODO: use __builtin_x_overflow on GCC and Clang + size_t z = x + y; + if(z < x) + { + throw Integer_Overflow_Detected(file, line); + } + return z; + } + +#define BOTAN_CHECKED_ADD(x,y) checked_add(x,y,__FILE__,__LINE__) + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/utils/simd/info.txt b/src/libs/3rdparty/botan/src/lib/utils/simd/info.txt new file mode 100644 index 0000000000..7784902a60 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/utils/simd/info.txt @@ -0,0 +1,7 @@ + +SIMD_32 -> 20131128 + + + +simd_32.h + 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 new file mode 100644 index 0000000000..8e6ac3639c --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/utils/simd/simd_32.h @@ -0,0 +1,699 @@ +/* +* Lightweight wrappers for SIMD operations +* (C) 2009,2011,2016,2017 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_SIMD_32_H_ +#define BOTAN_SIMD_32_H_ + +#include +#include +#include +#include + +#if defined(BOTAN_TARGET_SUPPORTS_SSE2) + #include + #define BOTAN_SIMD_USE_SSE2 + +#elif defined(BOTAN_TARGET_SUPPORTS_ALTIVEC) + #include + #undef vector + #undef bool + #define BOTAN_SIMD_USE_ALTIVEC + +#elif defined(BOTAN_TARGET_SUPPORTS_NEON) + #include + #define BOTAN_SIMD_USE_NEON +#endif + +namespace Botan { + +/** +* 4x32 bit SIMD register +* +* This class is not a general purpose SIMD type, and only offers +* instructions needed for evaluation of specific crypto primitives. +* For example it does not currently have equality operators of any +* kind. +* +* Implemented for SSE2, VMX (Altivec), and NEON. +*/ +class SIMD_4x32 final + { + public: + + SIMD_4x32& operator=(const SIMD_4x32& other) = default; + SIMD_4x32(const SIMD_4x32& other) = default; + +#if !defined(BOTAN_BUILD_COMPILER_IS_MSVC_2013) + SIMD_4x32& operator=(SIMD_4x32&& other) = default; + SIMD_4x32(SIMD_4x32&& other) = default; +#endif + + /** + * Zero initialize SIMD register with 4 32-bit elements + */ + SIMD_4x32() // zero initialized + { +#if defined(BOTAN_SIMD_USE_SSE2) + m_sse = _mm_setzero_si128(); +#elif defined(BOTAN_SIMD_USE_ALTIVEC) + m_vmx = vec_splat_u32(0); +#elif defined(BOTAN_SIMD_USE_NEON) + m_neon = vdupq_n_u32(0); +#else + m_scalar[0] = 0; + m_scalar[1] = 0; + m_scalar[2] = 0; + m_scalar[3] = 0; +#endif + } + + /** + * Load SIMD register with 4 32-bit elements + */ + explicit SIMD_4x32(const uint32_t B[4]) + { +#if defined(BOTAN_SIMD_USE_SSE2) + m_sse = _mm_loadu_si128(reinterpret_cast(B)); +#elif defined(BOTAN_SIMD_USE_ALTIVEC) + m_vmx = (__vector unsigned int){B[0], B[1], B[2], B[3]}; +#elif defined(BOTAN_SIMD_USE_NEON) + m_neon = vld1q_u32(B); +#else + m_scalar[0] = B[0]; + m_scalar[1] = B[1]; + m_scalar[2] = B[2]; + m_scalar[3] = B[3]; +#endif + } + + /** + * Load SIMD register with 4 32-bit elements + */ + SIMD_4x32(uint32_t B0, uint32_t B1, uint32_t B2, uint32_t B3) + { +#if defined(BOTAN_SIMD_USE_SSE2) + m_sse = _mm_set_epi32(B3, B2, B1, B0); +#elif defined(BOTAN_SIMD_USE_ALTIVEC) + m_vmx = (__vector unsigned int){B0, B1, B2, B3}; +#elif defined(BOTAN_SIMD_USE_NEON) + // Better way to do this? + const uint32_t B[4] = { B0, B1, B2, B3 }; + m_neon = vld1q_u32(B); +#else + m_scalar[0] = B0; + m_scalar[1] = B1; + m_scalar[2] = B2; + m_scalar[3] = B3; +#endif + } + + /** + * Load SIMD register with one 32-bit element repeated + */ + static SIMD_4x32 splat(uint32_t B) + { +#if defined(BOTAN_SIMD_USE_SSE2) + return SIMD_4x32(_mm_set1_epi32(B)); +#elif defined(BOTAN_SIMD_USE_ARM) + return SIMD_4x32(vdupq_n_u32(B)); +#else + return SIMD_4x32(B, B, B, B); +#endif + } + + /** + * Load a SIMD register with little-endian convention + */ + static SIMD_4x32 load_le(const void* in) + { +#if defined(BOTAN_SIMD_USE_SSE2) + return SIMD_4x32(_mm_loadu_si128(reinterpret_cast(in))); +#elif defined(BOTAN_SIMD_USE_ALTIVEC) + + uint32_t R[4]; + Botan::load_le(R, static_cast(in), 4); + return SIMD_4x32(R); + +#elif defined(BOTAN_SIMD_USE_NEON) + + uint32_t in32[4]; + std::memcpy(in32, in, 16); + if(CPUID::is_big_endian()) + { + bswap_4(in32); + } + return SIMD_4x32(vld1q_u32(in32)); + +#else + SIMD_4x32 out; + Botan::load_le(out.m_scalar, static_cast(in), 4); + return out; +#endif + } + + /** + * Load a SIMD register with big-endian convention + */ + static SIMD_4x32 load_be(const void* in) + { +#if defined(BOTAN_SIMD_USE_SSE2) + + return load_le(in).bswap(); + +#elif defined(BOTAN_SIMD_USE_ALTIVEC) + + uint32_t R[4]; + Botan::load_be(R, static_cast(in), 4); + return SIMD_4x32(R); + +#elif defined(BOTAN_SIMD_USE_NEON) + + uint32_t in32[4]; + std::memcpy(in32, in, 16); + if(CPUID::is_little_endian()) + { + bswap_4(in32); + } + return SIMD_4x32(vld1q_u32(in32)); + +#else + SIMD_4x32 out; + Botan::load_be(out.m_scalar, static_cast(in), 4); + return out; +#endif + } + + /** + * Load a SIMD register with little-endian convention + */ + void store_le(uint8_t out[]) const + { +#if defined(BOTAN_SIMD_USE_SSE2) + + _mm_storeu_si128(reinterpret_cast<__m128i*>(out), m_sse); + +#elif defined(BOTAN_SIMD_USE_ALTIVEC) + + union { + __vector unsigned int V; + uint32_t R[4]; + } vec; + vec.V = m_vmx; + Botan::store_le(out, vec.R[0], vec.R[1], vec.R[2], vec.R[3]); + +#elif defined(BOTAN_SIMD_USE_NEON) + + if(CPUID::is_big_endian()) + { + SIMD_4x32 swap = bswap(); + swap.store_be(out); + } + else + { + uint32_t out32[4] = { 0 }; + vst1q_u32(out32, m_neon); + copy_out_le(out, 16, out32); + } +#else + Botan::store_le(out, m_scalar[0], m_scalar[1], m_scalar[2], m_scalar[3]); +#endif + } + + /** + * Load a SIMD register with big-endian convention + */ + void store_be(uint8_t out[]) const + { +#if defined(BOTAN_SIMD_USE_SSE2) + + bswap().store_le(out); + +#elif defined(BOTAN_SIMD_USE_ALTIVEC) + + union { + __vector unsigned int V; + uint32_t R[4]; + } vec; + vec.V = m_vmx; + Botan::store_be(out, vec.R[0], vec.R[1], vec.R[2], vec.R[3]); + +#elif defined(BOTAN_SIMD_USE_NEON) + + if(CPUID::is_little_endian()) + { + SIMD_4x32 swap = bswap(); + swap.store_le(out); + } + else + { + uint32_t out32[4] = { 0 }; + vst1q_u32(out32, m_neon); + copy_out_be(out, 16, out32); + } + +#else + Botan::store_be(out, m_scalar[0], m_scalar[1], m_scalar[2], m_scalar[3]); +#endif + } + + + /* + * This is used for SHA-2/SHACAL2 + * Return rotr(ROT1) ^ rotr(ROT2) ^ rotr(ROT3) + */ + template + 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(32-ROT1)), + _mm_srli_epi32(m_sse, static_cast(ROT1))); + res.m_sse = _mm_xor_si128( + res.m_sse, + _mm_or_si128(_mm_slli_epi32(m_sse, static_cast(32-ROT2)), + _mm_srli_epi32(m_sse, static_cast(ROT2)))); + res.m_sse = _mm_xor_si128( + res.m_sse, + _mm_or_si128(_mm_slli_epi32(m_sse, static_cast(32-ROT3)), + _mm_srli_epi32(m_sse, static_cast(ROT3)))); + +#elif defined(BOTAN_SIMD_USE_ALTIVEC) + + const unsigned int r1 = static_cast(32-ROT1); + const unsigned int r2 = static_cast(32-ROT2); + const unsigned int r3 = static_cast(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(32-ROT1)), + vshrq_n_u32(m_neon, static_cast(ROT1))); + + res.m_neon = veorq_u32( + res.m_neon, + vorrq_u32(vshlq_n_u32(m_neon, static_cast(32-ROT2)), + vshrq_n_u32(m_neon, static_cast(ROT2)))); + + res.m_neon = veorq_u32( + res.m_neon, + vorrq_u32(vshlq_n_u32(m_neon, static_cast(32-ROT3)), + vshrq_n_u32(m_neon, static_cast(ROT3)))); + +#else + + for(size_t i = 0; i != 4; ++i) + { + res.m_scalar[i] = Botan::rotr(m_scalar[i]) ^ + Botan::rotr(m_scalar[i]) ^ + Botan::rotr(m_scalar[i]); + } +#endif + + return res; + } + + /** + * Left rotation by a compile time constant + */ + template + SIMD_4x32 rotl() const + { + static_assert(ROT > 0 && ROT < 32, "Invalid rotation constant"); + +#if defined(BOTAN_SIMD_USE_SSE2) + + return SIMD_4x32(_mm_or_si128(_mm_slli_epi32(m_sse, static_cast(ROT)), + _mm_srli_epi32(m_sse, static_cast(32-ROT)))); + +#elif defined(BOTAN_SIMD_USE_ALTIVEC) + + const unsigned int r = static_cast(ROT); + return SIMD_4x32(vec_rl(m_vmx, (__vector unsigned int){r, r, r, r})); + +#elif defined(BOTAN_SIMD_USE_NEON) + return SIMD_4x32(vorrq_u32(vshlq_n_u32(m_neon, static_cast(ROT)), + vshrq_n_u32(m_neon, static_cast(32-ROT)))); + +#else + return SIMD_4x32(Botan::rotl(m_scalar[0]), + Botan::rotl(m_scalar[1]), + Botan::rotl(m_scalar[2]), + Botan::rotl(m_scalar[3])); +#endif + } + + /** + * Right rotation by a compile time constant + */ + template + SIMD_4x32 rotr() const + { + return this->rotl<32-ROT>(); + } + + /** + * Add elements of a SIMD vector + */ + SIMD_4x32 operator+(const SIMD_4x32& other) const + { + SIMD_4x32 retval(*this); + retval += other; + return retval; + } + + /** + * Subtract elements of a SIMD vector + */ + SIMD_4x32 operator-(const SIMD_4x32& other) const + { + SIMD_4x32 retval(*this); + retval -= other; + return retval; + } + + /** + * XOR elements of a SIMD vector + */ + SIMD_4x32 operator^(const SIMD_4x32& other) const + { + SIMD_4x32 retval(*this); + retval ^= other; + return retval; + } + + /** + * Binary OR elements of a SIMD vector + */ + SIMD_4x32 operator|(const SIMD_4x32& other) const + { + SIMD_4x32 retval(*this); + retval |= other; + return retval; + } + + /** + * Binary AND elements of a SIMD vector + */ + SIMD_4x32 operator&(const SIMD_4x32& other) const + { + SIMD_4x32 retval(*this); + retval &= other; + return retval; + } + + void operator+=(const SIMD_4x32& other) + { +#if defined(BOTAN_SIMD_USE_SSE2) + m_sse = _mm_add_epi32(m_sse, other.m_sse); +#elif defined(BOTAN_SIMD_USE_ALTIVEC) + m_vmx = vec_add(m_vmx, other.m_vmx); +#elif defined(BOTAN_SIMD_USE_NEON) + m_neon = vaddq_u32(m_neon, other.m_neon); +#else + m_scalar[0] += other.m_scalar[0]; + m_scalar[1] += other.m_scalar[1]; + m_scalar[2] += other.m_scalar[2]; + m_scalar[3] += other.m_scalar[3]; +#endif + } + + void operator-=(const SIMD_4x32& other) + { +#if defined(BOTAN_SIMD_USE_SSE2) + m_sse = _mm_sub_epi32(m_sse, other.m_sse); +#elif defined(BOTAN_SIMD_USE_ALTIVEC) + m_vmx = vec_sub(m_vmx, other.m_vmx); +#elif defined(BOTAN_SIMD_USE_NEON) + m_neon = vsubq_u32(m_neon, other.m_neon); +#else + m_scalar[0] -= other.m_scalar[0]; + m_scalar[1] -= other.m_scalar[1]; + m_scalar[2] -= other.m_scalar[2]; + m_scalar[3] -= other.m_scalar[3]; +#endif + } + + void operator^=(const SIMD_4x32& other) + { +#if defined(BOTAN_SIMD_USE_SSE2) + m_sse = _mm_xor_si128(m_sse, other.m_sse); + +#elif defined(BOTAN_SIMD_USE_ALTIVEC) + m_vmx = vec_xor(m_vmx, other.m_vmx); +#elif defined(BOTAN_SIMD_USE_NEON) + m_neon = veorq_u32(m_neon, other.m_neon); +#else + m_scalar[0] ^= other.m_scalar[0]; + m_scalar[1] ^= other.m_scalar[1]; + m_scalar[2] ^= other.m_scalar[2]; + m_scalar[3] ^= other.m_scalar[3]; +#endif + } + + void operator|=(const SIMD_4x32& other) + { +#if defined(BOTAN_SIMD_USE_SSE2) + m_sse = _mm_or_si128(m_sse, other.m_sse); +#elif defined(BOTAN_SIMD_USE_ALTIVEC) + m_vmx = vec_or(m_vmx, other.m_vmx); +#elif defined(BOTAN_SIMD_USE_NEON) + m_neon = vorrq_u32(m_neon, other.m_neon); +#else + m_scalar[0] |= other.m_scalar[0]; + m_scalar[1] |= other.m_scalar[1]; + m_scalar[2] |= other.m_scalar[2]; + m_scalar[3] |= other.m_scalar[3]; +#endif + } + + void operator&=(const SIMD_4x32& other) + { +#if defined(BOTAN_SIMD_USE_SSE2) + m_sse = _mm_and_si128(m_sse, other.m_sse); +#elif defined(BOTAN_SIMD_USE_ALTIVEC) + m_vmx = vec_and(m_vmx, other.m_vmx); +#elif defined(BOTAN_SIMD_USE_NEON) + m_neon = vandq_u32(m_neon, other.m_neon); +#else + m_scalar[0] &= other.m_scalar[0]; + m_scalar[1] &= other.m_scalar[1]; + m_scalar[2] &= other.m_scalar[2]; + m_scalar[3] &= other.m_scalar[3]; +#endif + } + + + template SIMD_4x32 shl() const + { +#if defined(BOTAN_SIMD_USE_SSE2) + return SIMD_4x32(_mm_slli_epi32(m_sse, SHIFT)); + +#elif defined(BOTAN_SIMD_USE_ALTIVEC) + const unsigned int s = static_cast(SHIFT); + return SIMD_4x32(vec_sl(m_vmx, (__vector unsigned int){s, s, s, s})); +#elif defined(BOTAN_SIMD_USE_NEON) + return SIMD_4x32(vshlq_n_u32(m_neon, SHIFT)); +#else + return SIMD_4x32(m_scalar[0] << SHIFT, + m_scalar[1] << SHIFT, + m_scalar[2] << SHIFT, + m_scalar[3] << SHIFT); +#endif + } + + template SIMD_4x32 shr() const + { +#if defined(BOTAN_SIMD_USE_SSE2) + return SIMD_4x32(_mm_srli_epi32(m_sse, SHIFT)); + +#elif defined(BOTAN_SIMD_USE_ALTIVEC) + const unsigned int s = static_cast(SHIFT); + return SIMD_4x32(vec_sr(m_vmx, (__vector unsigned int){s, s, s, s})); +#elif defined(BOTAN_SIMD_USE_NEON) + return SIMD_4x32(vshrq_n_u32(m_neon, SHIFT)); +#else + return SIMD_4x32(m_scalar[0] >> SHIFT, m_scalar[1] >> SHIFT, + m_scalar[2] >> SHIFT, m_scalar[3] >> SHIFT); + +#endif + } + + SIMD_4x32 operator~() const + { +#if defined(BOTAN_SIMD_USE_SSE2) + return SIMD_4x32(_mm_xor_si128(m_sse, _mm_set1_epi32(0xFFFFFFFF))); +#elif defined(BOTAN_SIMD_USE_ALTIVEC) + return SIMD_4x32(vec_nor(m_vmx, m_vmx)); +#elif defined(BOTAN_SIMD_USE_NEON) + return SIMD_4x32(vmvnq_u32(m_neon)); +#else + return SIMD_4x32(~m_scalar[0], ~m_scalar[1], ~m_scalar[2], ~m_scalar[3]); +#endif + } + + // (~reg) & other + SIMD_4x32 andc(const SIMD_4x32& other) const + { +#if defined(BOTAN_SIMD_USE_SSE2) + return SIMD_4x32(_mm_andnot_si128(m_sse, other.m_sse)); +#elif defined(BOTAN_SIMD_USE_ALTIVEC) + /* + AltiVec does arg1 & ~arg2 rather than SSE's ~arg1 & arg2 + so swap the arguments + */ + return SIMD_4x32(vec_andc(other.m_vmx, m_vmx)); +#elif defined(BOTAN_SIMD_USE_NEON) + // NEON is also a & ~b + return SIMD_4x32(vbicq_u32(other.m_neon, m_neon)); +#else + return SIMD_4x32((~m_scalar[0]) & other.m_scalar[0], + (~m_scalar[1]) & other.m_scalar[1], + (~m_scalar[2]) & other.m_scalar[2], + (~m_scalar[3]) & other.m_scalar[3]); +#endif + } + + /** + * Return copy *this with each word byte swapped + */ + SIMD_4x32 bswap() const + { +#if defined(BOTAN_SIMD_USE_SSE2) + + __m128i T = m_sse; + T = _mm_shufflehi_epi16(T, _MM_SHUFFLE(2, 3, 0, 1)); + T = _mm_shufflelo_epi16(T, _MM_SHUFFLE(2, 3, 0, 1)); + return SIMD_4x32(_mm_or_si128(_mm_srli_epi16(T, 8), _mm_slli_epi16(T, 8))); + +#elif defined(BOTAN_SIMD_USE_ALTIVEC) + + union { + __vector unsigned int V; + uint32_t R[4]; + } vec; + + vec.V = m_vmx; + bswap_4(vec.R); + return SIMD_4x32(vec.R[0], vec.R[1], vec.R[2], vec.R[3]); + +#elif defined(BOTAN_SIMD_USE_NEON) + + //return SIMD_4x32(vrev64q_u32(m_neon)); + + // FIXME this is really slow + SIMD_4x32 ror8 = this->rotr<8>(); + SIMD_4x32 rol8 = this->rotl<8>(); + + const SIMD_4x32 mask1 = SIMD_4x32::splat(0xFF00FF00); + const SIMD_4x32 mask2 = SIMD_4x32::splat(0x00FF00FF); + return (ror8 & mask1) | (rol8 & mask2); +#else + // scalar + return SIMD_4x32(reverse_bytes(m_scalar[0]), + reverse_bytes(m_scalar[1]), + reverse_bytes(m_scalar[2]), + reverse_bytes(m_scalar[3])); +#endif + } + + /** + * 4x4 Transposition on SIMD registers + */ + static void transpose(SIMD_4x32& B0, SIMD_4x32& B1, + SIMD_4x32& B2, SIMD_4x32& B3) + { +#if defined(BOTAN_SIMD_USE_SSE2) + const __m128i T0 = _mm_unpacklo_epi32(B0.m_sse, B1.m_sse); + const __m128i T1 = _mm_unpacklo_epi32(B2.m_sse, B3.m_sse); + const __m128i T2 = _mm_unpackhi_epi32(B0.m_sse, B1.m_sse); + const __m128i T3 = _mm_unpackhi_epi32(B2.m_sse, B3.m_sse); + + B0.m_sse = _mm_unpacklo_epi64(T0, T1); + B1.m_sse = _mm_unpackhi_epi64(T0, T1); + B2.m_sse = _mm_unpacklo_epi64(T2, T3); + B3.m_sse = _mm_unpackhi_epi64(T2, T3); +#elif defined(BOTAN_SIMD_USE_ALTIVEC) + const __vector unsigned int T0 = vec_mergeh(B0.m_vmx, B2.m_vmx); + const __vector unsigned int T1 = vec_mergeh(B1.m_vmx, B3.m_vmx); + const __vector unsigned int T2 = vec_mergel(B0.m_vmx, B2.m_vmx); + const __vector unsigned int T3 = vec_mergel(B1.m_vmx, B3.m_vmx); + + B0.m_vmx = vec_mergeh(T0, T1); + B1.m_vmx = vec_mergel(T0, T1); + B2.m_vmx = vec_mergeh(T2, T3); + B3.m_vmx = vec_mergel(T2, T3); +#elif defined(BOTAN_SIMD_USE_NEON) + +#if defined(BOTAN_TARGET_ARCH_IS_ARM32) + + const uint32x4x2_t T0 = vzipq_u32(B0.m_neon, B2.m_neon); + const uint32x4x2_t T1 = vzipq_u32(B1.m_neon, B3.m_neon); + const uint32x4x2_t O0 = vzipq_u32(T0.val[0], T1.val[0]); + const uint32x4x2_t O1 = vzipq_u32(T0.val[1], T1.val[1]); + + B0.m_neon = O0.val[0]; + B1.m_neon = O0.val[1]; + B2.m_neon = O1.val[0]; + B3.m_neon = O1.val[1]; + +#elif defined(BOTAN_TARGET_ARCH_IS_ARM64) + const uint32x4_t T0 = vzip1q_u32(B0.m_neon, B2.m_neon); + const uint32x4_t T2 = vzip2q_u32(B0.m_neon, B2.m_neon); + + const uint32x4_t T1 = vzip1q_u32(B1.m_neon, B3.m_neon); + const uint32x4_t T3 = vzip2q_u32(B1.m_neon, B3.m_neon); + + B0.m_neon = vzip1q_u32(T0, T1); + B1.m_neon = vzip2q_u32(T0, T1); + + B2.m_neon = vzip1q_u32(T2, T3); + B3.m_neon = vzip2q_u32(T2, T3); +#endif + +#else + // scalar + SIMD_4x32 T0(B0.m_scalar[0], B1.m_scalar[0], B2.m_scalar[0], B3.m_scalar[0]); + SIMD_4x32 T1(B0.m_scalar[1], B1.m_scalar[1], B2.m_scalar[1], B3.m_scalar[1]); + SIMD_4x32 T2(B0.m_scalar[2], B1.m_scalar[2], B2.m_scalar[2], B3.m_scalar[2]); + SIMD_4x32 T3(B0.m_scalar[3], B1.m_scalar[3], B2.m_scalar[3], B3.m_scalar[3]); + + B0 = T0; + B1 = T1; + B2 = T2; + B3 = T3; +#endif + } + + private: + +#if defined(BOTAN_SIMD_USE_SSE2) + explicit SIMD_4x32(__m128i in) : m_sse(in) {} +#elif defined(BOTAN_SIMD_USE_ALTIVEC) + explicit SIMD_4x32(__vector unsigned int in) : m_vmx(in) {} +#elif defined(BOTAN_SIMD_USE_NEON) + explicit SIMD_4x32(uint32x4_t in) : m_neon(in) {} +#endif + +#if defined(BOTAN_SIMD_USE_SSE2) + __m128i m_sse; +#elif defined(BOTAN_SIMD_USE_ALTIVEC) + __vector unsigned int m_vmx; +#elif defined(BOTAN_SIMD_USE_NEON) + uint32x4_t m_neon; +#else + uint32_t m_scalar[4]; +#endif + }; + +typedef SIMD_4x32 SIMD_32; + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/utils/stl_compatibility.h b/src/libs/3rdparty/botan/src/lib/utils/stl_compatibility.h new file mode 100644 index 0000000000..099af83b38 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/utils/stl_compatibility.h @@ -0,0 +1,77 @@ +/* +* STL standards compatibility functions +* (C) 2017 Tomasz Frydrych +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_STL_COMPATIBILITY_H_ +#define BOTAN_STL_COMPATIBILITY_H_ + +#include + +#if __cplusplus < 201402L +#include +#include +#include +#endif + +namespace Botan +{ +/* +* std::make_unique functionality similar as we have in C++14. +* C++11 version based on proposal for C++14 implemenatation by Stephan T. Lavavej +* source: https://isocpp.org/files/papers/N3656.txt +*/ +#if __cplusplus >= 201402L +template +constexpr auto make_unique(Args&&... args) + { + return std::make_unique(std::forward(args)...); + } + +template +constexpr auto make_unique(std::size_t size) + { + return std::make_unique(size); + } + +#else +namespace stlCompatibilityDetails +{ +template struct _Unique_if + { + typedef std::unique_ptr _Single_object; + }; + +template struct _Unique_if + { + typedef std::unique_ptr _Unknown_bound; + }; + +template struct _Unique_if + { + typedef void _Known_bound; + }; +} // namespace stlCompatibilityDetails + +template +typename stlCompatibilityDetails::_Unique_if::_Single_object make_unique(Args&&... args) + { + return std::unique_ptr(new T(std::forward(args)...)); + } + +template +typename stlCompatibilityDetails::_Unique_if::_Unknown_bound make_unique(size_t n) + { + typedef typename std::remove_extent::type U; + return std::unique_ptr(new U[n]()); + } + +template +typename stlCompatibilityDetails::_Unique_if::_Known_bound make_unique(Args&&...) = delete; + +#endif + +} // namespace Botan +#endif diff --git a/src/libs/3rdparty/botan/src/lib/utils/stl_util.h b/src/libs/3rdparty/botan/src/lib/utils/stl_util.h new file mode 100644 index 0000000000..d9167bb7db --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/utils/stl_util.h @@ -0,0 +1,110 @@ +/* +* STL Utility Functions +* (C) 1999-2007 Jack Lloyd +* (C) 2015 Simon Warta (Kullo GmbH) +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_STL_UTIL_H_ +#define BOTAN_STL_UTIL_H_ + +#include +#include +#include +#include +#include + +namespace Botan { + +inline std::vector to_byte_vector(const std::string& s) + { + return std::vector(s.cbegin(), s.cend()); + } + +inline std::string to_string(const secure_vector &bytes) + { + return std::string(bytes.cbegin(), bytes.cend()); + } + +/** +* Return the keys of a map as a std::set +*/ +template +std::set map_keys_as_set(const std::map& kv) + { + std::set s; + for(auto&& i : kv) + { + s.insert(i.first); + } + return s; + } + +/* +* Searching through a std::map +* @param mapping the map to search +* @param key is what to look for +* @param null_result is the value to return if key is not in mapping +* @return mapping[key] or null_result +*/ +template +inline V search_map(const std::map& mapping, + const K& key, + const V& null_result = V()) + { + auto i = mapping.find(key); + if(i == mapping.end()) + return null_result; + return i->second; + } + +template +inline R search_map(const std::map& mapping, const K& key, + const R& null_result, const R& found_result) + { + auto i = mapping.find(key); + if(i == mapping.end()) + return null_result; + return found_result; + } + +/* +* Insert a key/value pair into a multimap +*/ +template +void multimap_insert(std::multimap& multimap, + const K& key, const V& value) + { + multimap.insert(std::make_pair(key, value)); + } + +/** +* Existence check for values +*/ +template +bool value_exists(const std::vector& vec, + const T& val) + { + for(size_t i = 0; i != vec.size(); ++i) + if(vec[i] == val) + return true; + return false; + } + +template +void map_remove_if(Pred pred, T& assoc) + { + auto i = assoc.begin(); + while(i != assoc.end()) + { + if(pred(i->first)) + assoc.erase(i++); + else + i++; + } + } + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/utils/types.h b/src/libs/3rdparty/botan/src/lib/utils/types.h new file mode 100644 index 0000000000..51f0e3bc37 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/utils/types.h @@ -0,0 +1,109 @@ +/* +* Low Level Types +* (C) 1999-2007 Jack Lloyd +* (C) 2015 Simon Warta (Kullo GmbH) +* (C) 2016 René Korthaus, Rohde & Schwarz Cybersecurity +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_TYPES_H_ +#define BOTAN_TYPES_H_ + +#include // IWYU pragma: export +#include // IWYU pragma: export +#include // IWYU pragma: export +#include // IWYU pragma: export +#include // IWYU pragma: export + +namespace Botan { + +/** +* @mainpage Botan Crypto Library API Reference +* +*
+*
Abstract Base Classes
+* BlockCipher, HashFunction, KDF, MessageAuthenticationCode, RandomNumberGenerator, +* StreamCipher, SymmetricAlgorithm, AEAD_Mode, Cipher_Mode +*
Public Key Interface Classes
+* PK_Key_Agreement, PK_Signer, PK_Verifier, PK_Encryptor, PK_Decryptor +*
Authenticated Encryption Modes
+* @ref CCM_Mode "CCM", @ref ChaCha20Poly1305_Mode "ChaCha20Poly1305", @ref EAX_Mode "EAX", +* @ref GCM_Mode "GCM", @ref OCB_Mode "OCB", @ref SIV_Mode "SIV" +*
Block Ciphers
+* @ref aria.h "ARIA", @ref aes.h "AES", @ref Blowfish, @ref camellia.h "Camellia", @ref Cascade_Cipher "Cascade", +* @ref CAST_128 "CAST-128", @ref CAST_128 "CAST-256", DES, @ref DESX "DES-X", @ref TripleDES "3DES", +* @ref GOST_28147_89 "GOST 28147-89", IDEA, KASUMI, Lion, MISTY1, Noekeon, SEED, Serpent, SHACAL2, SM4, +* @ref Threefish_512 "Threefish", Twofish, XTEA +*
Stream Ciphers
+* ChaCha, @ref CTR_BE "CTR", OFB, RC4, Salsa20 +*
Hash Functions
+* Blake2b, @ref GOST_34_11 "GOST 34.11", @ref Keccak_1600 "Keccak", MD4, MD5, @ref RIPEMD_160 "RIPEMD-160", +* @ref SHA_160 "SHA-1", @ref SHA_224 "SHA-224", @ref SHA_256 "SHA-256", @ref SHA_384 "SHA-384", +* @ref SHA_512 "SHA-512", @ref Skein_512 "Skein-512", SM3, Streebog, Tiger, Whirlpool +*
Non-Cryptographic Checksums
+* Adler32, CRC24, CRC32 +*
Message Authentication Codes
+* @ref CBC_MAC "CBC-MAC", CMAC, HMAC, Poly1305, SipHash, ANSI_X919_MAC +*
Random Number Generators
+* AutoSeeded_RNG, HMAC_DRBG, RDRAND_RNG, System_RNG +*
Key Derivation
+* HKDF, @ref KDF1 "KDF1 (IEEE 1363)", @ref KDF1_18033 "KDF1 (ISO 18033-2)", @ref KDF2 "KDF2 (IEEE 1363)", +* @ref sp800_108.h "SP800-108", @ref SP800_56C "SP800-56C", @ref PKCS5_PBKDF1 "PBKDF1 (PKCS#5), +* @ref PKCS5_PBKDF2 "PBKDF2 (PKCS#5)" +*
Password Hashing
+* @ref bcrypt.h "bcrypt", @ref passhash9.h "passhash9" +*
Public Key Cryptosystems
+* @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" +*
Public Key Signature Schemes
+* @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" +*
Key Agreement
+* @ref dh.h "DH", @ref ecdh.h "ECDH" +*
Compression
+* @ref bzip2.h "bzip2", @ref lzma.h "lzma", @ref zlib.h "zlib" +*
TLS
+* TLS::Client, TLS::Server, TLS::Policy, TLS::Protocol_Version, TLS::Callbacks, TLS::Ciphersuite, +* TLS::Session, TLS::Session_Manager, Credentials_Manager +*
X.509
+* X509_Certificate, X509_CRL, X509_CA, Certificate_Extension, PKCS10_Request, X509_Cert_Options, +* Certificate_Store, Certificate_Store_In_SQL, Certificate_Store_In_SQLite +*
+*/ + +using std::uint8_t; +using std::uint16_t; +using std::uint32_t; +using std::uint64_t; +using std::int32_t; +using std::int64_t; +using std::size_t; + +/* +* These typedefs are no longer used within the library headers +* or code. They are kept only for compatability with software +* written against older versions. +*/ +using byte = std::uint8_t; +using u16bit = std::uint16_t; +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) + 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 +#endif + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/utils/version.cpp b/src/libs/3rdparty/botan/src/lib/utils/version.cpp new file mode 100644 index 0000000000..ccf83bf6cb --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/utils/version.cpp @@ -0,0 +1,92 @@ +/* +* Version Information +* (C) 1999-2013,2015 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include + +namespace Botan { + +/* + These are intentionally compiled rather than inlined, so an + application running against a shared library can test the true + version they are running against. +*/ + +#define QUOTE(name) #name +#define STR(macro) QUOTE(macro) + +const char* short_version_cstr() + { + return STR(BOTAN_VERSION_MAJOR) "." + STR(BOTAN_VERSION_MINOR) "." + STR(BOTAN_VERSION_PATCH); + } + +const char* version_cstr() + { + + /* + It is intentional that this string is a compile-time constant; + it makes it much easier to find in binaries. + */ + + return "Botan " STR(BOTAN_VERSION_MAJOR) "." + STR(BOTAN_VERSION_MINOR) "." + STR(BOTAN_VERSION_PATCH) " (" +#if defined(BOTAN_UNSAFE_FUZZER_MODE) + "UNSAFE FUZZER MODE BUILD " +#endif + BOTAN_VERSION_RELEASE_TYPE +#if (BOTAN_VERSION_DATESTAMP != 0) + ", dated " STR(BOTAN_VERSION_DATESTAMP) +#endif + ", revision " BOTAN_VERSION_VC_REVISION + ", distribution " BOTAN_DISTRIBUTION_INFO ")"; + } + +#undef STR +#undef QUOTE + +/* +* Return the version as a string +*/ +std::string version_string() + { + return std::string(version_cstr()); + } + +std::string short_version_string() + { + return std::string(short_version_cstr()); + } + +uint32_t version_datestamp() { return BOTAN_VERSION_DATESTAMP; } + +/* +* Return parts of the version as integers +*/ +uint32_t version_major() { return BOTAN_VERSION_MAJOR; } +uint32_t version_minor() { return BOTAN_VERSION_MINOR; } +uint32_t version_patch() { return BOTAN_VERSION_PATCH; } + +std::string runtime_version_check(uint32_t major, + uint32_t minor, + uint32_t patch) + { + if(major != version_major() || minor != version_minor() || patch != version_patch()) + { + std::ostringstream oss; + oss << "Warning: linked version (" << short_version_string() << ")" + << " does not match version built against " + << "(" << major << '.' << minor << '.' << patch << ")\n"; + return oss.str(); + } + + return ""; + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/utils/version.h b/src/libs/3rdparty/botan/src/lib/utils/version.h new file mode 100644 index 0000000000..fe59de625c --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/utils/version.h @@ -0,0 +1,101 @@ +/* +* Version Information +* (C) 1999-2011,2015 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_VERSION_H_ +#define BOTAN_VERSION_H_ + +#include +#include + +namespace Botan { + +/* +* Get information describing the version +*/ + +/** +* Get a human-readable string identifying the version of Botan. +* No particular format should be assumed. +* @return version string +*/ +BOTAN_PUBLIC_API(2,0) std::string version_string(); + +/** +* Same as version_string() except returning a pointer to a statically +* allocated string. +* @return version string +*/ +BOTAN_PUBLIC_API(2,0) const char* version_cstr(); + +/** +* Return a version string of the form "MAJOR.MINOR.PATCH" where +* each of the values is an integer. +*/ +BOTAN_PUBLIC_API(2,4) std::string short_version_string(); + +/** +* Same as version_short_string except returning a pointer to the string. +*/ +BOTAN_PUBLIC_API(2,4) const char* short_version_cstr(); + +/** +* Return the date this version of botan was released, in an integer of +* the form YYYYMMDD. For instance a version released on May 21, 2013 +* would return the integer 20130521. If the currently running version +* is not an official release, this function will return 0 instead. +* +* @return release date, or zero if unreleased +*/ +BOTAN_PUBLIC_API(2,0) uint32_t version_datestamp(); + +/** +* Get the major version number. +* @return major version number +*/ +BOTAN_PUBLIC_API(2,0) uint32_t version_major(); + +/** +* Get the minor version number. +* @return minor version number +*/ +BOTAN_PUBLIC_API(2,0) uint32_t version_minor(); + +/** +* Get the patch number. +* @return patch number +*/ +BOTAN_PUBLIC_API(2,0) uint32_t version_patch(); + +/** +* Usable for checking that the DLL version loaded at runtime exactly +* matches the compile-time version. Call using BOTAN_VERSION_* macro +* values. Returns the empty string if an exact match, otherwise an +* appropriate message. Added with 1.11.26. +*/ +BOTAN_PUBLIC_API(2,0) std::string +runtime_version_check(uint32_t major, + uint32_t minor, + uint32_t patch); + +/* +* Macros for compile-time version checks +*/ +#define BOTAN_VERSION_CODE_FOR(a,b,c) ((a << 16) | (b << 8) | (c)) + +/** +* Compare using BOTAN_VERSION_CODE_FOR, as in +* # if BOTAN_VERSION_CODE < BOTAN_VERSION_CODE_FOR(1,8,0) +* # error "Botan version too old" +* # endif +*/ +#define BOTAN_VERSION_CODE BOTAN_VERSION_CODE_FOR(BOTAN_VERSION_MAJOR, \ + BOTAN_VERSION_MINOR, \ + BOTAN_VERSION_PATCH) + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/x509/asn1_alt_name.cpp b/src/libs/3rdparty/botan/src/lib/x509/asn1_alt_name.cpp new file mode 100644 index 0000000000..4e052ca588 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/x509/asn1_alt_name.cpp @@ -0,0 +1,248 @@ +/* +* AlternativeName +* (C) 1999-2007 Jack Lloyd +* 2007 Yves Jerschow +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace Botan { + +/* +* Create an AlternativeName +*/ +AlternativeName::AlternativeName(const std::string& email_addr, + const std::string& uri, + const std::string& dns, + const std::string& ip) + { + add_attribute("RFC822", email_addr); + add_attribute("DNS", dns); + add_attribute("URI", uri); + add_attribute("IP", ip); + } + +/* +* Add an attribute to an alternative name +*/ +void AlternativeName::add_attribute(const std::string& type, + const std::string& value) + { + if(type.empty() || value.empty()) + return; + + auto range = m_alt_info.equal_range(type); + for(auto j = range.first; j != range.second; ++j) + if(j->second == value) + return; + + multimap_insert(m_alt_info, type, value); + } + +/* +* Add an OtherName field +*/ +void AlternativeName::add_othername(const OID& oid, const std::string& value, + ASN1_Tag type) + { + if(value.empty()) + return; + multimap_insert(m_othernames, oid, ASN1_String(value, type)); + } + +/* +* Return all of the alternative names +*/ +std::multimap AlternativeName::contents() const + { + std::multimap names; + + for(auto i = m_alt_info.begin(); i != m_alt_info.end(); ++i) + multimap_insert(names, i->first, i->second); + + for(auto i = m_othernames.begin(); i != m_othernames.end(); ++i) + multimap_insert(names, OIDS::lookup(i->first), i->second.value()); + + return names; + } + +bool AlternativeName::has_field(const std::string& attr) const + { + auto range = m_alt_info.equal_range(attr); + return (range.first != range.second); + } + +std::string AlternativeName::get_first_attribute(const std::string& attr) const + { + auto i = m_alt_info.lower_bound(attr); + if(i != m_alt_info.end() && i->first == attr) + return i->second; + + return ""; + } + +std::vector AlternativeName::get_attribute(const std::string& attr) const + { + std::vector results; + auto range = m_alt_info.equal_range(attr); + for(auto i = range.first; i != range.second; ++i) + results.push_back(i->second); + return results; + } + +/* +* Return if this object has anything useful +*/ +bool AlternativeName::has_items() const + { + return (m_alt_info.size() > 0 || m_othernames.size() > 0); + } + +namespace { + +/* +* DER encode an AlternativeName entry +*/ +void encode_entries(DER_Encoder& encoder, + const std::multimap& attr, + const std::string& type, ASN1_Tag tagging) + { + auto range = attr.equal_range(type); + + for(auto i = range.first; i != range.second; ++i) + { + if(type == "RFC822" || type == "DNS" || type == "URI") + { + ASN1_String asn1_string(i->second, IA5_STRING); + encoder.add_object(tagging, CONTEXT_SPECIFIC, asn1_string.value()); + } + else if(type == "IP") + { + const uint32_t ip = string_to_ipv4(i->second); + uint8_t ip_buf[4] = { 0 }; + store_be(ip, ip_buf); + encoder.add_object(tagging, CONTEXT_SPECIFIC, ip_buf, 4); + } + else if (type == "DN") + { + std::stringstream ss(i->second); + X509_DN dn; + ss >> dn; + encoder.encode(dn); + } + } + } + +} + +/* +* DER encode an AlternativeName extension +*/ +void AlternativeName::encode_into(DER_Encoder& der) const + { + der.start_cons(SEQUENCE); + + encode_entries(der, m_alt_info, "RFC822", ASN1_Tag(1)); + encode_entries(der, m_alt_info, "DNS", ASN1_Tag(2)); + encode_entries(der, m_alt_info, "DN", ASN1_Tag(4)); + encode_entries(der, m_alt_info, "URI", ASN1_Tag(6)); + encode_entries(der, m_alt_info, "IP", ASN1_Tag(7)); + + for(auto i = m_othernames.begin(); i != m_othernames.end(); ++i) + { + der.start_explicit(0) + .encode(i->first) + .start_explicit(0) + .encode(i->second) + .end_explicit() + .end_explicit(); + } + + der.end_cons(); + } + +/* +* Decode a BER encoded AlternativeName +*/ +void AlternativeName::decode_from(BER_Decoder& source) + { + BER_Decoder names = source.start_cons(SEQUENCE); + + // FIXME this is largely a duplication of GeneralName::decode_from + + while(names.more_items()) + { + BER_Object obj = names.get_next_object(); + + if(obj.is_a(0, CONTEXT_SPECIFIC)) + { + BER_Decoder othername(obj); + + OID oid; + othername.decode(oid); + if(othername.more_items()) + { + BER_Object othername_value_outer = othername.get_next_object(); + othername.verify_end(); + + if(othername_value_outer.is_a(0, ASN1_Tag(CONTEXT_SPECIFIC | CONSTRUCTED)) == false) + throw Decoding_Error("Invalid tags on otherName value"); + + BER_Decoder othername_value_inner(othername_value_outer); + + BER_Object value = othername_value_inner.get_next_object(); + othername_value_inner.verify_end(); + + if(ASN1_String::is_string_type(value.type()) && value.get_class() == UNIVERSAL) + { + add_othername(oid, ASN1::to_string(value), value.type()); + } + } + } + if(obj.is_a(1, CONTEXT_SPECIFIC)) + { + add_attribute("RFC822", ASN1::to_string(obj)); + } + else if(obj.is_a(2, CONTEXT_SPECIFIC)) + { + add_attribute("DNS", ASN1::to_string(obj)); + } + else if(obj.is_a(6, CONTEXT_SPECIFIC)) + { + add_attribute("URI", ASN1::to_string(obj)); + } + else if(obj.is_a(4, ASN1_Tag(CONTEXT_SPECIFIC | CONSTRUCTED))) + { + BER_Decoder dec(obj); + X509_DN dn; + std::stringstream ss; + + dec.decode(dn); + ss << dn; + + add_attribute("DN", ss.str()); + } + else if(obj.is_a(7, CONTEXT_SPECIFIC)) + { + if(obj.length() == 4) + { + const uint32_t ip = load_be(obj.bits(), 0); + add_attribute("IP", ipv4_to_string(ip)); + } + } + + } + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/x509/asn1_alt_name.h b/src/libs/3rdparty/botan/src/lib/x509/asn1_alt_name.h new file mode 100644 index 0000000000..83ac215baa --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/x509/asn1_alt_name.h @@ -0,0 +1,60 @@ +/* +* (C) 1999-2007 Jack Lloyd +* 2007 Yves Jerschow +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_X509_ALT_NAME_H_ +#define BOTAN_X509_ALT_NAME_H_ + +#include +#include +#include +#include + +namespace Botan { + +/** +* Alternative Name +*/ +class BOTAN_PUBLIC_API(2,0) AlternativeName final : public ASN1_Object + { + public: + void encode_into(class DER_Encoder&) const override; + void decode_from(class BER_Decoder&) override; + + std::multimap contents() const; + + bool has_field(const std::string& attr) const; + std::vector get_attribute(const std::string& attr) const; + + std::string get_first_attribute(const std::string& attr) const; + + void add_attribute(const std::string& type, const std::string& value); + void add_othername(const OID& oid, const std::string& value, ASN1_Tag type); + + const std::multimap& get_attributes() const + { + return m_alt_info; + } + + const std::multimap& get_othernames() const + { + return m_othernames; + } + + bool has_items() const; + + AlternativeName(const std::string& email_addr = "", + const std::string& uri = "", + const std::string& dns = "", + const std::string& ip_address = ""); + private: + std::multimap m_alt_info; + std::multimap m_othernames; + }; + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/x509/cert_status.cpp b/src/libs/3rdparty/botan/src/lib/x509/cert_status.cpp new file mode 100644 index 0000000000..79bcd1b074 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/x509/cert_status.cpp @@ -0,0 +1,122 @@ +/* +* (C) 2016 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include + +namespace Botan { + +//static +const char* to_string(Certificate_Status_Code code) + { + switch(code) + { + case Certificate_Status_Code::VERIFIED: + return "Verified"; + case Certificate_Status_Code::OCSP_RESPONSE_GOOD: + return "OCSP response accepted as affirming unrevoked status for certificate"; + case Certificate_Status_Code::OCSP_SIGNATURE_OK: + return "Signature on OCSP response was found valid"; + case Certificate_Status_Code::VALID_CRL_CHECKED: + return "Valid CRL examined"; + + case Certificate_Status_Code::CERT_SERIAL_NEGATIVE: + return "Certificate serial number is negative"; + case Certificate_Status_Code::DN_TOO_LONG: + return "Distinguished name too long"; + case Certificate_Status_Code::OSCP_NO_REVOCATION_URL: + return "OCSP URL not available"; + case Certificate_Status_Code::OSCP_SERVER_NOT_AVAILABLE: + return "OSCP server not available"; + + case Certificate_Status_Code::NO_REVOCATION_DATA: + return "No revocation data"; + case Certificate_Status_Code::SIGNATURE_METHOD_TOO_WEAK: + return "Signature method too weak"; + case Certificate_Status_Code::UNTRUSTED_HASH: + return "Hash function used is considered too weak for security"; + + case Certificate_Status_Code::CERT_NOT_YET_VALID: + return "Certificate is not yet valid"; + case Certificate_Status_Code::CERT_HAS_EXPIRED: + return "Certificate has expired"; + case Certificate_Status_Code::OCSP_NOT_YET_VALID: + return "OCSP is not yet valid"; + case Certificate_Status_Code::OCSP_HAS_EXPIRED: + return "OCSP response has expired"; + case Certificate_Status_Code::CRL_NOT_YET_VALID: + return "CRL response is not yet valid"; + case Certificate_Status_Code::CRL_HAS_EXPIRED: + return "CRL has expired"; + + case Certificate_Status_Code::CERT_ISSUER_NOT_FOUND: + return "Certificate issuer not found"; + case Certificate_Status_Code::CANNOT_ESTABLISH_TRUST: + return "Cannot establish trust"; + case Certificate_Status_Code::CERT_CHAIN_LOOP: + return "Loop in certificate chain"; + case Certificate_Status_Code::CHAIN_LACKS_TRUST_ROOT: + return "Certificate chain does not end in a CA certificate"; + case Certificate_Status_Code::CHAIN_NAME_MISMATCH: + return "Certificate issuer does not match subject of issuing cert"; + + case Certificate_Status_Code::POLICY_ERROR: + return "Certificate policy error"; + case Certificate_Status_Code::DUPLICATE_CERT_POLICY: + return "Certificate contains duplicate policy"; + case Certificate_Status_Code::INVALID_USAGE: + return "Certificate does not allow the requested usage"; + case Certificate_Status_Code::CERT_CHAIN_TOO_LONG: + return "Certificate chain too long"; + case Certificate_Status_Code::CA_CERT_NOT_FOR_CERT_ISSUER: + return "CA certificate not allowed to issue certs"; + case Certificate_Status_Code::CA_CERT_NOT_FOR_CRL_ISSUER: + return "CA certificate not allowed to issue CRLs"; + case Certificate_Status_Code::NO_MATCHING_CRLDP: + return "No CRL with matching distribution point for certificate"; + case Certificate_Status_Code::OCSP_CERT_NOT_LISTED: + return "OCSP cert not listed"; + case Certificate_Status_Code::OCSP_BAD_STATUS: + return "OCSP bad status"; + case Certificate_Status_Code::CERT_NAME_NOMATCH: + return "Certificate does not match provided name"; + case Certificate_Status_Code::NAME_CONSTRAINT_ERROR: + return "Certificate does not pass name constraint"; + case Certificate_Status_Code::UNKNOWN_CRITICAL_EXTENSION: + return "Unknown critical extension encountered"; + case Certificate_Status_Code::DUPLICATE_CERT_EXTENSION: + return "Duplicate certificate extension encountered"; + case Certificate_Status_Code::EXT_IN_V1_V2_CERT: + return "Encountered extension in certificate with version < 3"; + case Certificate_Status_Code::OCSP_SIGNATURE_ERROR: + return "OCSP signature error"; + case Certificate_Status_Code::OCSP_ISSUER_NOT_FOUND: + return "Unable to find certificate issusing OCSP response"; + case Certificate_Status_Code::OCSP_RESPONSE_MISSING_KEYUSAGE: + return "OCSP issuer's keyusage prohibits OCSP"; + case Certificate_Status_Code::OCSP_RESPONSE_INVALID: + return "OCSP parsing valid"; + case Certificate_Status_Code::OCSP_NO_HTTP: + return "OCSP requests not available, no HTTP support compiled in"; + case Certificate_Status_Code::CERT_IS_REVOKED: + return "Certificate is revoked"; + case Certificate_Status_Code::CRL_BAD_SIGNATURE: + return "CRL bad signature"; + case Certificate_Status_Code::SIGNATURE_ERROR: + return "Signature error"; + case Certificate_Status_Code::CERT_PUBKEY_INVALID: + return "Certificate public key invalid"; + case Certificate_Status_Code::SIGNATURE_ALGO_UNKNOWN: + return "Certificate signed with unknown/unavailable algorithm"; + case Certificate_Status_Code::SIGNATURE_ALGO_BAD_PARAMS: + return "Certificate signature has invalid parameters"; + + // intentionally no default so we are warned if new enum values are added + } + + return nullptr; + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/x509/cert_status.h b/src/libs/3rdparty/botan/src/lib/x509/cert_status.h new file mode 100644 index 0000000000..1c3a5de890 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/x509/cert_status.h @@ -0,0 +1,99 @@ +/* +* Path validation result enums +* (C) 2013 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_X509_PATH_RESULT_H_ +#define BOTAN_X509_PATH_RESULT_H_ + +#include + +namespace Botan { + +/** +* Certificate validation status code +*/ +enum class Certificate_Status_Code { + OK = 0, + VERIFIED = 0, + + // Revocation status + OCSP_RESPONSE_GOOD = 1, + OCSP_SIGNATURE_OK = 2, + VALID_CRL_CHECKED = 3, + OCSP_NO_HTTP = 4, + + // Warnings + FIRST_WARNING_STATUS = 500, + CERT_SERIAL_NEGATIVE = 500, + DN_TOO_LONG = 501, + OSCP_NO_REVOCATION_URL = 502, + OSCP_SERVER_NOT_AVAILABLE = 503, + + // Errors + FIRST_ERROR_STATUS = 1000, + + SIGNATURE_METHOD_TOO_WEAK = 1000, + UNTRUSTED_HASH = 1001, + NO_REVOCATION_DATA = 1002, + NO_MATCHING_CRLDP = 1003, + + // Time problems + CERT_NOT_YET_VALID = 2000, + CERT_HAS_EXPIRED = 2001, + OCSP_NOT_YET_VALID = 2002, + OCSP_HAS_EXPIRED = 2003, + CRL_NOT_YET_VALID = 2004, + CRL_HAS_EXPIRED = 2005, + + // Chain generation problems + CERT_ISSUER_NOT_FOUND = 3000, + CANNOT_ESTABLISH_TRUST = 3001, + CERT_CHAIN_LOOP = 3002, + CHAIN_LACKS_TRUST_ROOT = 3003, + CHAIN_NAME_MISMATCH = 3004, + + // Validation errors + POLICY_ERROR = 4000, + INVALID_USAGE = 4001, + CERT_CHAIN_TOO_LONG = 4002, + CA_CERT_NOT_FOR_CERT_ISSUER = 4003, + NAME_CONSTRAINT_ERROR = 4004, + + // Revocation errors + CA_CERT_NOT_FOR_CRL_ISSUER = 4005, + OCSP_CERT_NOT_LISTED = 4006, + OCSP_BAD_STATUS = 4007, + + // Other problems + CERT_NAME_NOMATCH = 4008, + UNKNOWN_CRITICAL_EXTENSION = 4009, + DUPLICATE_CERT_EXTENSION = 4010, + OCSP_SIGNATURE_ERROR = 4501, + OCSP_ISSUER_NOT_FOUND = 4502, + OCSP_RESPONSE_MISSING_KEYUSAGE = 4503, + OCSP_RESPONSE_INVALID = 4504, + EXT_IN_V1_V2_CERT = 4505, + DUPLICATE_CERT_POLICY = 4506, + + // Hard failures + CERT_IS_REVOKED = 5000, + CRL_BAD_SIGNATURE = 5001, + SIGNATURE_ERROR = 5002, + CERT_PUBKEY_INVALID = 5003, + SIGNATURE_ALGO_UNKNOWN = 5004, + SIGNATURE_ALGO_BAD_PARAMS = 5005 +}; + +/** +* Convert a status code to a human readable diagnostic message +* @param code the certifcate status +* @return string literal constant, or nullptr if code unknown +*/ +BOTAN_PUBLIC_API(2,0) const char* to_string(Certificate_Status_Code code); + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/x509/certstor.cpp b/src/libs/3rdparty/botan/src/lib/x509/certstor.cpp new file mode 100644 index 0000000000..2356a70c6c --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/x509/certstor.cpp @@ -0,0 +1,216 @@ +/* +* Certificate Store +* (C) 1999-2010,2013 Jack Lloyd +* (C) 2017 Fabian Weissberg, Rohde & Schwarz Cybersecurity +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include + +namespace Botan { + +std::shared_ptr Certificate_Store::find_crl_for(const X509_Certificate&) const + { + return {}; + } + +void Certificate_Store_In_Memory::add_certificate(const X509_Certificate& cert) + { + for(const auto& c : m_certs) + if(*c == cert) + return; + + m_certs.push_back(std::make_shared(cert)); + } + +void Certificate_Store_In_Memory::add_certificate(std::shared_ptr cert) + { + for(const auto& c : m_certs) + if(*c == *cert) + return; + + m_certs.push_back(cert); + } + +std::vector Certificate_Store_In_Memory::all_subjects() const + { + std::vector subjects; + for(const auto& cert : m_certs) + subjects.push_back(cert->subject_dn()); + return subjects; + } + +std::shared_ptr +Certificate_Store_In_Memory::find_cert(const X509_DN& subject_dn, + const std::vector& key_id) const + { + for(const auto& cert : m_certs) + { + // Only compare key ids if set in both call and in the cert + if(key_id.size()) + { + std::vector skid = cert->subject_key_id(); + + if(skid.size() && skid != key_id) // no match + continue; + } + + if(cert->subject_dn() == subject_dn) + return cert; + } + + return nullptr; + } + +std::vector> Certificate_Store_In_Memory::find_all_certs( + const X509_DN& subject_dn, + const std::vector& key_id) const + { + std::vector> matches; + + for(const auto& cert : m_certs) + { + if(key_id.size()) + { + std::vector skid = cert->subject_key_id(); + + if(skid.size() && skid != key_id) // no match + continue; + } + + if(cert->subject_dn() == subject_dn) + matches.push_back(cert); + } + + return matches; + } + +std::shared_ptr +Certificate_Store_In_Memory::find_cert_by_pubkey_sha1(const std::vector& key_hash) const + { + if(key_hash.size() != 20) + throw Invalid_Argument("Certificate_Store_In_Memory::find_cert_by_pubkey_sha1 invalid hash"); + + std::unique_ptr hash(HashFunction::create("SHA-1")); + + for(const auto& cert : m_certs){ + hash->update(cert->subject_public_key_bitstring()); + if(key_hash == hash->final_stdvec()) //final_stdvec also clears the hash to initial state + return cert; + } + + return nullptr; + } + +std::shared_ptr +Certificate_Store_In_Memory::find_cert_by_raw_subject_dn_sha256(const std::vector& subject_hash) const + { + if(subject_hash.size() != 32) + throw Invalid_Argument("Certificate_Store_In_Memory::find_cert_by_raw_subject_dn_sha256 invalid hash"); + + std::unique_ptr hash(HashFunction::create("SHA-256")); + + for(const auto& cert : m_certs){ + hash->update(cert->raw_subject_dn()); + if(subject_hash == hash->final_stdvec()) //final_stdvec also clears the hash to initial state + return cert; + } + + return nullptr; + } + +void Certificate_Store_In_Memory::add_crl(const X509_CRL& crl) + { + std::shared_ptr crl_s = std::make_shared(crl); + return add_crl(crl_s); + } + +void Certificate_Store_In_Memory::add_crl(std::shared_ptr crl) + { + X509_DN crl_issuer = crl->issuer_dn(); + + for(auto& c : m_crls) + { + // Found an update of a previously existing one; replace it + if(c->issuer_dn() == crl_issuer) + { + if(c->this_update() <= crl->this_update()) + c = crl; + return; + } + } + + // Totally new CRL, add to the list + m_crls.push_back(crl); + } + +std::shared_ptr Certificate_Store_In_Memory::find_crl_for(const X509_Certificate& subject) const + { + const std::vector& key_id = subject.authority_key_id(); + + for(const auto& c : m_crls) + { + // Only compare key ids if set in both call and in the CRL + if(key_id.size()) + { + std::vector akid = c->authority_key_id(); + + if(akid.size() && akid != key_id) // no match + continue; + } + + if(c->issuer_dn() == subject.issuer_dn()) + return c; + } + + return {}; + } + +Certificate_Store_In_Memory::Certificate_Store_In_Memory(const X509_Certificate& cert) + { + add_certificate(cert); + } + +#if defined(BOTAN_TARGET_OS_HAS_FILESYSTEM) +Certificate_Store_In_Memory::Certificate_Store_In_Memory(const std::string& dir) + { + if(dir.empty()) + return; + + std::vector maybe_certs = get_files_recursive(dir); + + if(maybe_certs.empty()) + { + maybe_certs.push_back(dir); + } + + for(auto&& cert_file : maybe_certs) + { + try + { + DataSource_Stream src(cert_file, true); + while(!src.end_of_data()) + { + try + { + m_certs.push_back(std::make_shared(src)); + } + catch(std::exception&) + { + // stop searching for other certificate at first exception + break; + } + } + } + catch(std::exception&) + { + } + } + } +#endif + +} diff --git a/src/libs/3rdparty/botan/src/lib/x509/certstor.h b/src/libs/3rdparty/botan/src/lib/x509/certstor.h new file mode 100644 index 0000000000..36d2e4abdd --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/x509/certstor.h @@ -0,0 +1,163 @@ +/* +* Certificate Store +* (C) 1999-2010,2013 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_CERT_STORE_H_ +#define BOTAN_CERT_STORE_H_ + +#include +#include + +namespace Botan { + +/** +* Certificate Store Interface +*/ +class BOTAN_PUBLIC_API(2,0) Certificate_Store + { + public: + virtual ~Certificate_Store() = default; + + /** + * Find a certificate by Subject DN and (optionally) key identifier + * @param subject_dn the subject's distinguished name + * @param key_id an optional key id + * @return a matching certificate or nullptr otherwise + */ + virtual std::shared_ptr + find_cert(const X509_DN& subject_dn, const std::vector& key_id) const = 0; + + /** + * Find all certificates with a given Subject DN. + * Subject DN and even the key identifier might not be unique. + */ + virtual std::vector> find_all_certs( + const X509_DN& subject_dn, const std::vector& key_id) const = 0; + + + /** + * Find a certificate by searching for one with a matching SHA-1 hash of + * public key. Used for OCSP. + * @param key_hash SHA-1 hash of the subject's public key + * @return a matching certificate or nullptr otherwise + */ + virtual std::shared_ptr + find_cert_by_pubkey_sha1(const std::vector& key_hash) const = 0; + + /** + * Find a certificate by searching for one with a matching SHA-256 hash of + * raw subject name. Used for OCSP. + * @param subject_hash SHA-256 hash of the subject's raw name + * @return a matching certificate or nullptr otherwise + */ + virtual std::shared_ptr + find_cert_by_raw_subject_dn_sha256(const std::vector& subject_hash) const = 0; + + /** + * Finds a CRL for the given certificate + * @param subject the subject certificate + * @return the CRL for subject or nullptr otherwise + */ + virtual std::shared_ptr find_crl_for(const X509_Certificate& subject) const; + + /** + * @return whether the certificate is known + * @param cert certififcate to be searched + */ + bool certificate_known(const X509_Certificate& cert) const + { + return find_cert(cert.subject_dn(), cert.subject_key_id()) != nullptr; + } + + // remove this (used by TLS::Server) + virtual std::vector all_subjects() const = 0; + }; + +/** +* In Memory Certificate Store +*/ +class BOTAN_PUBLIC_API(2,0) Certificate_Store_In_Memory final : public Certificate_Store + { + public: + /** + * Attempt to parse all files in dir (including subdirectories) + * as certificates. Ignores errors. + */ + explicit Certificate_Store_In_Memory(const std::string& dir); + + /** + * Adds given certificate to the store. + */ + explicit Certificate_Store_In_Memory(const X509_Certificate& cert); + + /** + * Create an empty store. + */ + Certificate_Store_In_Memory() = default; + + /** + * Add a certificate to the store. + * @param cert certificate to be added + */ + void add_certificate(const X509_Certificate& cert); + + /** + * Add a certificate already in a shared_ptr to the store. + * @param cert certificate to be added + */ + void add_certificate(std::shared_ptr cert); + + /** + * Add a certificate revocation list (CRL) to the store. + * @param crl CRL to be added + */ + void add_crl(const X509_CRL& crl); + + /** + * Add a certificate revocation list (CRL) to the store as a shared_ptr + * @param crl CRL to be added + */ + void add_crl(std::shared_ptr crl); + + /** + * @return DNs for all certificates managed by the store + */ + std::vector all_subjects() const override; + + /* + * Find a certificate by Subject DN and (optionally) key identifier + * @return the first certificate that matches + */ + std::shared_ptr find_cert( + const X509_DN& subject_dn, + const std::vector& key_id) const override; + + /* + * Find all certificates with a given Subject DN. + * Subject DN and even the key identifier might not be unique. + */ + std::vector> find_all_certs( + const X509_DN& subject_dn, const std::vector& key_id) const override; + + std::shared_ptr + find_cert_by_pubkey_sha1(const std::vector& key_hash) const override; + + std::shared_ptr + find_cert_by_raw_subject_dn_sha256(const std::vector& subject_hash) const override; + + /** + * Finds a CRL for the given certificate + */ + std::shared_ptr find_crl_for(const X509_Certificate& subject) const override; + private: + // TODO: Add indexing on the DN and key id to avoid linear search + std::vector> m_certs; + std::vector> m_crls; + }; + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/x509/crl_ent.cpp b/src/libs/3rdparty/botan/src/lib/x509/crl_ent.cpp new file mode 100644 index 0000000000..38a1963f1b --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/x509/crl_ent.cpp @@ -0,0 +1,140 @@ +/* +* CRL Entry +* (C) 1999-2010 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include +#include +#include + +namespace Botan { + +struct CRL_Entry_Data + { + std::vector m_serial; + X509_Time m_time; + CRL_Code m_reason = UNSPECIFIED; + Extensions m_extensions; + }; + +/* +* Create a CRL_Entry +*/ +CRL_Entry::CRL_Entry(const X509_Certificate& cert, CRL_Code why) + { + m_data.reset(new CRL_Entry_Data); + m_data->m_serial = cert.serial_number(); + m_data->m_time = X509_Time(std::chrono::system_clock::now()); + m_data->m_reason = why; + + if(why != UNSPECIFIED) + { + m_data->m_extensions.add(new Cert_Extension::CRL_ReasonCode(why)); + } + } + +/* +* Compare two CRL_Entrys for equality +*/ +bool operator==(const CRL_Entry& a1, const CRL_Entry& a2) + { + if(a1.serial_number() != a2.serial_number()) + return false; + if(a1.expire_time() != a2.expire_time()) + return false; + if(a1.reason_code() != a2.reason_code()) + return false; + return true; + } + +/* +* Compare two CRL_Entrys for inequality +*/ +bool operator!=(const CRL_Entry& a1, const CRL_Entry& a2) + { + return !(a1 == a2); + } + +/* +* DER encode a CRL_Entry +*/ +void CRL_Entry::encode_into(DER_Encoder& der) const + { + der.start_cons(SEQUENCE) + .encode(BigInt::decode(serial_number())) + .encode(expire_time()) + .start_cons(SEQUENCE) + .encode(extensions()) + .end_cons() + .end_cons(); + } + +/* +* Decode a BER encoded CRL_Entry +*/ +void CRL_Entry::decode_from(BER_Decoder& source) + { + BigInt serial_number_bn; + + std::unique_ptr data(new CRL_Entry_Data); + + BER_Decoder entry = source.start_cons(SEQUENCE); + + entry.decode(serial_number_bn).decode(data->m_time); + data->m_serial = BigInt::encode(serial_number_bn); + + if(entry.more_items()) + { + entry.decode(data->m_extensions); + if(auto ext = data->m_extensions.get_extension_object_as()) + { + data->m_reason = ext->get_reason(); + } + else + { + data->m_reason = UNSPECIFIED; + } + } + + entry.end_cons(); + + m_data.reset(data.release()); + } + +const CRL_Entry_Data& CRL_Entry::data() const + { + if(!m_data) + { + throw Invalid_State("CRL_Entry_Data uninitialized"); + } + + return *m_data.get(); + } + +const std::vector& CRL_Entry::serial_number() const + { + return data().m_serial; + } + +const X509_Time& CRL_Entry::expire_time() const + { + return data().m_time; + } + +CRL_Code CRL_Entry::reason_code() const + { + return data().m_reason; + } + +const Extensions& CRL_Entry::extensions() const + { + return data().m_extensions; + } + + +} diff --git a/src/libs/3rdparty/botan/src/lib/x509/crl_ent.h b/src/libs/3rdparty/botan/src/lib/x509/crl_ent.h new file mode 100644 index 0000000000..27549251f0 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/x509/crl_ent.h @@ -0,0 +1,104 @@ +/* +* CRL Entry +* (C) 1999-2007 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_CRL_ENTRY_H_ +#define BOTAN_CRL_ENTRY_H_ + +#include + +namespace Botan { + +class Extensions; +class X509_Certificate; +struct CRL_Entry_Data; + +/** +* X.509v2 CRL Reason Code. +*/ +enum CRL_Code : uint32_t { + UNSPECIFIED = 0, + KEY_COMPROMISE = 1, + CA_COMPROMISE = 2, + AFFILIATION_CHANGED = 3, + SUPERSEDED = 4, + CESSATION_OF_OPERATION = 5, + CERTIFICATE_HOLD = 6, + REMOVE_FROM_CRL = 8, + PRIVLEDGE_WITHDRAWN = 9, + AA_COMPROMISE = 10, + + DELETE_CRL_ENTRY = 0xFF00, + OCSP_GOOD = 0xFF01, + OCSP_UNKNOWN = 0xFF02 +}; + +/** +* This class represents CRL entries +*/ +class BOTAN_PUBLIC_API(2,0) CRL_Entry final : public ASN1_Object + { + public: + void encode_into(class DER_Encoder&) const override; + void decode_from(class BER_Decoder&) override; + + /** + * Get the serial number of the certificate associated with this entry. + * @return certificate's serial number + */ + const std::vector& serial_number() const; + + /** + * Get the revocation date of the certificate associated with this entry + * @return certificate's revocation date + */ + const X509_Time& expire_time() const; + + /** + * Get the entries reason code + * @return reason code + */ + CRL_Code reason_code() const; + + /** + * Get the extensions on this CRL entry + */ + const Extensions& extensions() const; + + /** + * Create uninitialized CRL_Entry object + */ + CRL_Entry() = default; + + /** + * Construct an CRL entry. + * @param cert the certificate to revoke + * @param reason the reason code to set in the entry + */ + CRL_Entry(const X509_Certificate& cert, + CRL_Code reason = UNSPECIFIED); + + private: + friend class X509_CRL; + + const CRL_Entry_Data& data() const; + + std::shared_ptr m_data; + }; + +/** +* Test two CRL entries for equality in all fields. +*/ +BOTAN_PUBLIC_API(2,0) bool operator==(const CRL_Entry&, const CRL_Entry&); + +/** +* Test two CRL entries for inequality in at least one field. +*/ +BOTAN_PUBLIC_API(2,0) bool operator!=(const CRL_Entry&, const CRL_Entry&); + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/x509/datastor.cpp b/src/libs/3rdparty/botan/src/lib/x509/datastor.cpp new file mode 100644 index 0000000000..2cdd3458ca --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/x509/datastor.cpp @@ -0,0 +1,205 @@ +/* +* Data Store +* (C) 1999-2007 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include +#include + +namespace Botan { + +/* +* Data_Store Equality Comparison +*/ +bool Data_Store::operator==(const Data_Store& other) const + { + return (m_contents == other.m_contents); + } + +/* +* Check if this key has at least one value +*/ +bool Data_Store::has_value(const std::string& key) const + { + return (m_contents.lower_bound(key) != m_contents.end()); + } + +/* +* Search based on an arbitrary predicate +*/ +std::multimap Data_Store::search_for( + std::function predicate) const + { + std::multimap out; + + for(auto i = m_contents.begin(); i != m_contents.end(); ++i) + if(predicate(i->first, i->second)) + out.insert(std::make_pair(i->first, i->second)); + + return out; + } + +/* +* Search based on key equality +*/ +std::vector Data_Store::get(const std::string& looking_for) const + { + std::vector out; + auto range = m_contents.equal_range(looking_for); + for(auto i = range.first; i != range.second; ++i) + out.push_back(i->second); + return out; + } + +/* +* Get a single atom +*/ +std::string Data_Store::get1(const std::string& key) const + { + std::vector vals = get(key); + + if(vals.empty()) + throw Invalid_State("Data_Store::get1: No values set for " + key); + if(vals.size() > 1) + throw Invalid_State("Data_Store::get1: More than one value for " + key); + + return vals[0]; + } + +std::string Data_Store::get1(const std::string& key, + const std::string& default_value) const + { + std::vector vals = get(key); + + if(vals.size() > 1) + throw Invalid_State("Data_Store::get1: More than one value for " + key); + + if(vals.empty()) + return default_value; + + return vals[0]; + } + +/* +* Get a single std::vector atom +*/ +std::vector +Data_Store::get1_memvec(const std::string& key) const + { + std::vector vals = get(key); + + if(vals.empty()) + return std::vector(); + + if(vals.size() > 1) + throw Invalid_State("Data_Store::get1_memvec: Multiple values for " + + key); + + return hex_decode(vals[0]); + } + +/* +* Get a single uint32_t atom +*/ +uint32_t Data_Store::get1_uint32(const std::string& key, + uint32_t default_val) const + { + std::vector vals = get(key); + + if(vals.empty()) + return default_val; + else if(vals.size() > 1) + throw Invalid_State("Data_Store::get1_uint32: Multiple values for " + key); + + return to_u32bit(vals[0]); + } + +/* +* Insert a single key and value +*/ +void Data_Store::add(const std::string& key, const std::string& val) + { + multimap_insert(m_contents, key, val); + } + +/* +* Insert a single key and value +*/ +void Data_Store::add(const std::string& key, uint32_t val) + { + add(key, std::to_string(val)); + } + +/* +* Insert a single key and value +*/ +void Data_Store::add(const std::string& key, const secure_vector& val) + { + add(key, hex_encode(val.data(), val.size())); + } + +void Data_Store::add(const std::string& key, const std::vector& val) + { + add(key, hex_encode(val.data(), val.size())); + } + +/* +* Insert a mapping of key/value pairs +*/ +void Data_Store::add(const std::multimap& in) + { + std::multimap::const_iterator i = in.begin(); + while(i != in.end()) + { + m_contents.insert(*i); + ++i; + } + } + +/* +* Create and populate a X509_DN +*/ +X509_DN create_dn(const Data_Store& info) + { + auto names = info.search_for( + [](const std::string& key, const std::string&) + { + return (key.find("X520.") != std::string::npos); + }); + + X509_DN dn; + + for(auto i = names.begin(); i != names.end(); ++i) + dn.add_attribute(i->first, i->second); + + return dn; + } + +/* +* Create and populate an AlternativeName +*/ +AlternativeName create_alt_name(const Data_Store& info) + { + auto names = info.search_for( + [](const std::string& key, const std::string&) + { + return (key == "RFC822" || + key == "DNS" || + key == "URI" || + key == "IP"); + }); + + AlternativeName alt_name; + + for(auto i = names.begin(); i != names.end(); ++i) + alt_name.add_attribute(i->first, i->second); + + return alt_name; + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/x509/datastor.h b/src/libs/3rdparty/botan/src/lib/x509/datastor.h new file mode 100644 index 0000000000..ec3c5189bd --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/x509/datastor.h @@ -0,0 +1,84 @@ +/* +* Data Store +* (C) 1999-2007 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_DATA_STORE_H_ +#define BOTAN_DATA_STORE_H_ + +#include +#include +#include +#include +#include +#include + +namespace Botan { + +/** +* Data Store +* +* This class is used internally by the library, and exposed for ABI +* reasons. There is no reason for applications to use this type directly. +* It will be removed in a future major release. +*/ +class BOTAN_UNSTABLE_API Data_Store final + { + public: + /** + * A search function + */ + bool operator==(const Data_Store&) const; + + std::multimap search_for( + std::function predicate) const; + + std::vector get(const std::string&) const; + + std::string get1(const std::string& key) const; + + std::string get1(const std::string& key, + const std::string& default_value) const; + + std::vector get1_memvec(const std::string&) const; + uint32_t get1_uint32(const std::string&, uint32_t = 0) const; + + bool has_value(const std::string&) const; + + void add(const std::multimap&); + void add(const std::string&, const std::string&); + void add(const std::string&, uint32_t); + void add(const std::string&, const secure_vector&); + void add(const std::string&, const std::vector&); + private: + std::multimap m_contents; + }; + +/* +* Data Store Extraction Operations +*/ + +/* +* Create and populate a X509_DN +* @param info data store containing DN information +* @return DN containing attributes from data store +*/ +BOTAN_PUBLIC_API(2,0) X509_DN +BOTAN_DEPRECATED("Avoid roundtripping names through Data_Store") +create_dn(const Data_Store& info); + +/* +* Create and populate an AlternativeName +* @param info data store containing AlternativeName information +* @return AlternativeName containing attributes from data store +*/ +BOTAN_PUBLIC_API(2,0) AlternativeName +BOTAN_DEPRECATED("Avoid roundtripping names through Data_Store") +create_alt_name(const Data_Store& info); + + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/x509/info.txt b/src/libs/3rdparty/botan/src/lib/x509/info.txt new file mode 100644 index 0000000000..6b136cbcf2 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/x509/info.txt @@ -0,0 +1,11 @@ + +X509_CERTIFICATES -> 20151023 +OCSP -> 20161118 + + + +asn1 +pubkey +sha1 +sha2_32 + diff --git a/src/libs/3rdparty/botan/src/lib/x509/key_constraint.cpp b/src/libs/3rdparty/botan/src/lib/x509/key_constraint.cpp new file mode 100644 index 0000000000..dfadedac59 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/x509/key_constraint.cpp @@ -0,0 +1,100 @@ +/* +* KeyUsage +* (C) 1999-2007,2016 Jack Lloyd +* (C) 2016 René Korthaus, Rohde & Schwarz Cybersecurity +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include + +namespace Botan { + +std::string key_constraints_to_string(Key_Constraints constraints) + { + std::vector str; + + if(constraints == NO_CONSTRAINTS) + return "no_constraints"; + + if(constraints & DIGITAL_SIGNATURE) + str.push_back("digital_signature"); + + if(constraints & NON_REPUDIATION) + str.push_back("non_repudiation"); + + if(constraints & KEY_ENCIPHERMENT) + str.push_back("key_encipherment"); + + if(constraints & DATA_ENCIPHERMENT) + str.push_back("data_encipherment"); + + if(constraints & KEY_AGREEMENT) + str.push_back("key_agreement"); + + if(constraints & KEY_CERT_SIGN) + str.push_back("key_cert_sign"); + + if(constraints & CRL_SIGN) + str.push_back("crl_sign"); + + if(constraints & ENCIPHER_ONLY) + str.push_back("encipher_only"); + + if(constraints & DECIPHER_ONLY) + str.push_back("decipher_only"); + + // Not 0 (checked at start) but nothing matched above! + if(str.empty()) + return "other_unknown_constraints"; + + if(str.size() == 1) + return str[0]; + + std::string out; + for(size_t i = 0; i < str.size() - 1; ++i) + { + out += str[i]; + out += ','; + } + out += str[str.size() - 1]; + + return out; + } + +/* +* Make sure the given key constraints are permitted for the given key type +*/ +void verify_cert_constraints_valid_for_key_type(const Public_Key& pub_key, + Key_Constraints constraints) + { + const std::string name = pub_key.algo_name(); + + size_t permitted = 0; + + if(name == "DH" || name == "ECDH") + { + permitted |= KEY_AGREEMENT | ENCIPHER_ONLY | DECIPHER_ONLY; + } + + if(name == "RSA" || name == "ElGamal") + { + permitted |= KEY_ENCIPHERMENT | DATA_ENCIPHERMENT; + } + + if(name == "RSA" || name == "DSA" || + name == "ECDSA" || name == "ECGDSA" || name == "ECKCDSA" || name == "GOST-34.10" || + name == "Ed25519") + { + permitted |= DIGITAL_SIGNATURE | NON_REPUDIATION | KEY_CERT_SIGN | CRL_SIGN; + } + + if((constraints & permitted) != constraints) + { + throw Exception("Invalid " + name + " constraints " + key_constraints_to_string(constraints)); + } + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/x509/key_constraint.h b/src/libs/3rdparty/botan/src/lib/x509/key_constraint.h new file mode 100644 index 0000000000..3d456f6c44 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/x509/key_constraint.h @@ -0,0 +1,49 @@ +/* +* Enumerations +* (C) 1999-2007 Jack Lloyd +* (C) 2016 René Korthaus, Rohde & Schwarz Cybersecurity +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_ENUMS_H_ +#define BOTAN_ENUMS_H_ + +#include +#include + +namespace Botan { + +/** +* X.509v3 Key Constraints. +* If updating update copy in ffi.h +*/ +enum Key_Constraints { + NO_CONSTRAINTS = 0, + DIGITAL_SIGNATURE = 1 << 15, + NON_REPUDIATION = 1 << 14, + KEY_ENCIPHERMENT = 1 << 13, + DATA_ENCIPHERMENT = 1 << 12, + KEY_AGREEMENT = 1 << 11, + KEY_CERT_SIGN = 1 << 10, + CRL_SIGN = 1 << 9, + ENCIPHER_ONLY = 1 << 8, + DECIPHER_ONLY = 1 << 7 +}; + +class Public_Key; + +/** +* Check that key constraints are permitted for a specific public key. +* @param pub_key the public key on which the constraints shall be enforced on +* @param constraints the constraints that shall be enforced on the key +* @throw Exception if the given constraints are not permitted for this key +*/ +BOTAN_PUBLIC_API(2,0) void verify_cert_constraints_valid_for_key_type(const Public_Key& pub_key, + Key_Constraints constraints); + +std::string BOTAN_PUBLIC_API(2,0) key_constraints_to_string(Key_Constraints); + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/x509/name_constraint.cpp b/src/libs/3rdparty/botan/src/lib/x509/name_constraint.cpp new file mode 100644 index 0000000000..b64e04d29d --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/x509/name_constraint.cpp @@ -0,0 +1,269 @@ +/* +* X.509 Name Constraint +* (C) 2015 Kai Michaelis +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Botan { + +class DER_Encoder; + +GeneralName::GeneralName(const std::string& str) : GeneralName() + { + size_t p = str.find(':'); + + if(p != std::string::npos) + { + m_type = str.substr(0, p); + m_name = str.substr(p + 1, std::string::npos); + } + else + { + throw Invalid_Argument("Failed to decode Name Constraint"); + } + } + +void GeneralName::encode_into(DER_Encoder&) const + { + throw Not_Implemented("GeneralName encoding"); + } + +void GeneralName::decode_from(class BER_Decoder& ber) + { + BER_Object obj = ber.get_next_object(); + + if(obj.is_a(1, CONTEXT_SPECIFIC)) + { + m_type = "RFC822"; + m_name = ASN1::to_string(obj); + } + else if(obj.is_a(2, CONTEXT_SPECIFIC)) + { + m_type = "DNS"; + m_name = ASN1::to_string(obj); + } + else if(obj.is_a(6, CONTEXT_SPECIFIC)) + { + m_type = "URI"; + m_name = ASN1::to_string(obj); + } + else if(obj.is_a(4, ASN1_Tag(CONTEXT_SPECIFIC | CONSTRUCTED))) + { + m_type = "DN"; + X509_DN dn; + BER_Decoder dec(obj); + std::stringstream ss; + + dn.decode_from(dec); + ss << dn; + + m_name = ss.str(); + } + else if(obj.is_a(7, CONTEXT_SPECIFIC)) + { + if(obj.length() == 8) + { + m_type = "IP"; + m_name = ipv4_to_string(load_be(obj.bits(), 0)) + "/" + + ipv4_to_string(load_be(obj.bits(), 1)); + } + else if(obj.length() == 32) + { + throw Decoding_Error("Unsupported IPv6 name constraint"); + } + else + { + throw Decoding_Error("Invalid IP name constraint size " + std::to_string(obj.length())); + } + } + else + { + throw Decoding_Error("Found unknown GeneralName type"); + } + } + +GeneralName::MatchResult GeneralName::matches(const X509_Certificate& cert) const + { + std::vector nam; + std::function match_fn; + + const X509_DN& dn = cert.subject_dn(); + const AlternativeName& alt_name = cert.subject_alt_name(); + + if(type() == "DNS") + { + match_fn = std::mem_fn(&GeneralName::matches_dns); + + nam = alt_name.get_attribute("DNS"); + + if(nam.empty()) + { + nam = dn.get_attribute("CN"); + } + } + else if(type() == "DN") + { + match_fn = std::mem_fn(&GeneralName::matches_dn); + + std::stringstream ss; + ss << dn; + nam.push_back(ss.str()); + } + else if(type() == "IP") + { + match_fn = std::mem_fn(&GeneralName::matches_ip); + nam = alt_name.get_attribute("IP"); + } + else + { + return MatchResult::UnknownType; + } + + if(nam.empty()) + { + return MatchResult::NotFound; + } + + bool some = false; + bool all = true; + + for(const std::string& n: nam) + { + bool m = match_fn(this, n); + + some |= m; + all &= m; + } + + if(all) + { + return MatchResult::All; + } + else if(some) + { + return MatchResult::Some; + } + else + { + return MatchResult::None; + } + } + +bool GeneralName::matches_dns(const std::string& nam) const + { + if(nam.size() == name().size()) + { + return nam == name(); + } + else if(name().size() > nam.size()) + { + return false; + } + else // name.size() < nam.size() + { + std::string constr = name().front() == '.' ? name() : "." + name(); + // constr is suffix of nam + return constr == nam.substr(nam.size() - constr.size(), constr.size()); + } + } + +bool GeneralName::matches_dn(const std::string& nam) const + { + std::stringstream ss(nam); + std::stringstream tt(name()); + X509_DN nam_dn, my_dn; + + ss >> nam_dn; + tt >> my_dn; + + auto attr = nam_dn.get_attributes(); + bool ret = true; + size_t trys = 0; + + for(const auto& c: my_dn.dn_info()) + { + auto i = attr.equal_range(c.first); + + if(i.first != i.second) + { + trys += 1; + ret = ret && (i.first->second == c.second.value()); + } + } + + return trys > 0 && ret; + } + +bool GeneralName::matches_ip(const std::string& nam) const + { + uint32_t ip = string_to_ipv4(nam); + std::vector p = split_on(name(), '/'); + + if(p.size() != 2) + throw Decoding_Error("failed to parse IPv4 address"); + + uint32_t net = string_to_ipv4(p.at(0)); + uint32_t mask = string_to_ipv4(p.at(1)); + + return (ip & mask) == net; + } + +std::ostream& operator<<(std::ostream& os, const GeneralName& gn) + { + os << gn.type() << ":" << gn.name(); + return os; + } + +GeneralSubtree::GeneralSubtree(const std::string& str) : GeneralSubtree() + { + size_t p0, p1; + size_t min = std::stoull(str, &p0, 10); + size_t max = std::stoull(str.substr(p0 + 1), &p1, 10); + GeneralName gn(str.substr(p0 + p1 + 2)); + + if(p0 > 0 && p1 > 0) + { + m_minimum = min; + m_maximum = max; + m_base = gn; + } + else + { + throw Invalid_Argument("Failed to decode Name Constraint"); + } + } + +void GeneralSubtree::encode_into(DER_Encoder&) const + { + throw Not_Implemented("General Subtree encoding"); + } + +void GeneralSubtree::decode_from(class BER_Decoder& ber) + { + ber.start_cons(SEQUENCE) + .decode(m_base) + .decode_optional(m_minimum,ASN1_Tag(0), CONTEXT_SPECIFIC,size_t(0)) + .end_cons(); + + if(m_minimum != 0) + throw Decoding_Error("GeneralSubtree minimum must be 0"); + + m_maximum = std::numeric_limits::max(); + } + +std::ostream& operator<<(std::ostream& os, const GeneralSubtree& gs) + { + os << gs.minimum() << "," << gs.maximum() << "," << gs.base(); + return os; + } +} diff --git a/src/libs/3rdparty/botan/src/lib/x509/name_constraint.h b/src/libs/3rdparty/botan/src/lib/x509/name_constraint.h new file mode 100644 index 0000000000..34ee5dc324 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/x509/name_constraint.h @@ -0,0 +1,182 @@ +/* +* X.509 Name Constraint +* (C) 2015 Kai Michaelis +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_NAME_CONSTRAINT_H_ +#define BOTAN_NAME_CONSTRAINT_H_ + +#include +#include +#include + +namespace Botan { + +class BER_Encoder; +class DER_Encoder; +class X509_Certificate; + +/** +* @brief X.509 GeneralName Type +* +* Handles parsing GeneralName types in their BER and canonical string +* encoding. Allows matching GeneralNames against each other using +* the rules laid out in the RFC 5280, sec. 4.2.1.10 (Name Contraints). +*/ +class BOTAN_PUBLIC_API(2,0) GeneralName final : public ASN1_Object + { + public: + enum MatchResult : int + { + All, + Some, + None, + NotFound, + UnknownType, + }; + + /** + * Creates an empty GeneralName. + */ + GeneralName() = default; + + /** + * Creates a new GeneralName for its string format. + * @param str type and name, colon-separated, e.g., "DNS:google.com" + */ + GeneralName(const std::string& str); + + void encode_into(DER_Encoder&) const override; + + void decode_from(BER_Decoder&) override; + + /** + * @return Type of the name. Can be DN, DNS, IP, RFC822 or URI. + */ + const std::string& type() const { return m_type; } + + /** + * @return The name as string. Format depends on type. + */ + const std::string& name() const { return m_name; } + + /** + * Checks whether a given certificate (partially) matches this name. + * @param cert certificate to be matched + * @return the match result + */ + MatchResult matches(const X509_Certificate& cert) const; + + private: + std::string m_type; + std::string m_name; + + bool matches_dns(const std::string&) const; + bool matches_dn(const std::string&) const; + bool matches_ip(const std::string&) const; + }; + +std::ostream& operator<<(std::ostream& os, const GeneralName& gn); + +/** +* @brief A single Name Constraint +* +* The Name Constraint extension adds a minimum and maximum path +* length to a GeneralName to form a constraint. The length limits +* are currently unused. +*/ +class BOTAN_PUBLIC_API(2,0) GeneralSubtree final : public ASN1_Object + { + public: + /** + * Creates an empty name constraint. + */ + GeneralSubtree() : m_base(), m_minimum(0), m_maximum(std::numeric_limits::max()) + {} + + /*** + * Creates a new name constraint. + * @param base name + * @param min minimum path length + * @param max maximum path length + */ + GeneralSubtree(GeneralName base, size_t min, size_t max) + : m_base(base), m_minimum(min), m_maximum(max) + {} + + /** + * Creates a new name constraint for its string format. + * @param str name constraint + */ + GeneralSubtree(const std::string& str); + + void encode_into(DER_Encoder&) const override; + + void decode_from(BER_Decoder&) override; + + /** + * @return name + */ + GeneralName base() const { return m_base; } + + /** + * @return minimum path length + */ + size_t minimum() const { return m_minimum; } + + /** + * @return maximum path length + */ + size_t maximum() const { return m_maximum; } + + private: + GeneralName m_base; + size_t m_minimum; + size_t m_maximum; + }; + +std::ostream& operator<<(std::ostream& os, const GeneralSubtree& gs); + +/** +* @brief Name Constraints +* +* Wraps the Name Constraints associated with a certificate. +*/ +class BOTAN_PUBLIC_API(2,0) NameConstraints final + { + public: + /** + * Creates an empty name NameConstraints. + */ + NameConstraints() : m_permitted_subtrees(), m_excluded_subtrees() {} + + /** + * Creates NameConstraints from a list of permitted and excluded subtrees. + * @param permitted_subtrees names for which the certificate is permitted + * @param excluded_subtrees names for which the certificate is not permitted + */ + NameConstraints(std::vector&& permitted_subtrees, + std::vector&& excluded_subtrees) + : m_permitted_subtrees(permitted_subtrees), m_excluded_subtrees(excluded_subtrees) + {} + + /** + * @return permitted names + */ + const std::vector& permitted() const { return m_permitted_subtrees; } + + /** + * @return excluded names + */ + const std::vector& excluded() const { return m_excluded_subtrees; } + + private: + std::vector m_permitted_subtrees; + std::vector m_excluded_subtrees; +}; + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/x509/ocsp.cpp b/src/libs/3rdparty/botan/src/lib/x509/ocsp.cpp new file mode 100644 index 0000000000..115c4117ac --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/x509/ocsp.cpp @@ -0,0 +1,354 @@ +/* +* OCSP +* (C) 2012,2013 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(BOTAN_HAS_HTTP_UTIL) + #include +#endif + +namespace Botan { + +namespace OCSP { + +namespace { + +// TODO: should this be in a header somewhere? +void decode_optional_list(BER_Decoder& ber, + ASN1_Tag tag, + std::vector& output) + { + BER_Object obj = ber.get_next_object(); + + if(obj.is_a(tag, ASN1_Tag(CONTEXT_SPECIFIC | CONSTRUCTED)) == false) + { + ber.push_back(obj); + return; + } + + BER_Decoder list(obj); + + while(list.more_items()) + { + BER_Object certbits = list.get_next_object(); + X509_Certificate cert(certbits.bits(), certbits.length()); + output.push_back(std::move(cert)); + } + } + +} + +Request::Request(const X509_Certificate& issuer_cert, + const X509_Certificate& subject_cert) : + m_issuer(issuer_cert), + m_certid(m_issuer, BigInt::decode(subject_cert.serial_number())) + { + if(subject_cert.issuer_dn() != issuer_cert.subject_dn()) + throw Invalid_Argument("Invalid cert pair to OCSP::Request (mismatched issuer,subject args?)"); + } + +Request::Request(const X509_Certificate& issuer_cert, + const BigInt& subject_serial) : + m_issuer(issuer_cert), + m_certid(m_issuer, subject_serial) + { + } + +std::vector Request::BER_encode() const + { + std::vector output; + DER_Encoder(output).start_cons(SEQUENCE) + .start_cons(SEQUENCE) + .start_explicit(0) + .encode(static_cast(0)) // version # + .end_explicit() + .start_cons(SEQUENCE) + .start_cons(SEQUENCE) + .encode(m_certid) + .end_cons() + .end_cons() + .end_cons() + .end_cons(); + + return output; + } + +std::string Request::base64_encode() const + { + return Botan::base64_encode(BER_encode()); + } + +Response::Response(Certificate_Status_Code status) + { + m_dummy_response_status = status; + } + +Response::Response(const uint8_t response_bits[], size_t response_bits_len) : + m_response_bits(response_bits, response_bits + response_bits_len) + { + m_dummy_response_status = Certificate_Status_Code::OCSP_RESPONSE_INVALID; + + BER_Decoder response_outer = BER_Decoder(m_response_bits).start_cons(SEQUENCE); + + size_t resp_status = 0; + + response_outer.decode(resp_status, ENUMERATED, UNIVERSAL); + + if(resp_status != 0) + throw Exception("OCSP response status " + std::to_string(resp_status)); + + if(response_outer.more_items()) + { + BER_Decoder response_bytes = + response_outer.start_cons(ASN1_Tag(0), CONTEXT_SPECIFIC).start_cons(SEQUENCE); + + response_bytes.decode_and_check(OID("1.3.6.1.5.5.7.48.1.1"), + "Unknown response type in OCSP response"); + + BER_Decoder basicresponse = + BER_Decoder(response_bytes.get_next_octet_string()).start_cons(SEQUENCE); + + basicresponse.start_cons(SEQUENCE) + .raw_bytes(m_tbs_bits) + .end_cons() + .decode(m_sig_algo) + .decode(m_signature, BIT_STRING); + decode_optional_list(basicresponse, ASN1_Tag(0), m_certs); + + size_t responsedata_version = 0; + Extensions extensions; + + BER_Decoder(m_tbs_bits) + .decode_optional(responsedata_version, ASN1_Tag(0), + ASN1_Tag(CONSTRUCTED | CONTEXT_SPECIFIC)) + + .decode_optional(m_signer_name, ASN1_Tag(1), + ASN1_Tag(CONSTRUCTED | CONTEXT_SPECIFIC)) + + .decode_optional_string(m_key_hash, OCTET_STRING, 2, + ASN1_Tag(CONSTRUCTED | CONTEXT_SPECIFIC)) + + .decode(m_produced_at) + + .decode_list(m_responses) + + .decode_optional(extensions, ASN1_Tag(1), + ASN1_Tag(CONSTRUCTED | CONTEXT_SPECIFIC)); + } + + response_outer.end_cons(); + } + +Certificate_Status_Code Response::verify_signature(const X509_Certificate& issuer) const + { + if (m_responses.empty()) + return m_dummy_response_status; + + try + { + std::unique_ptr pub_key(issuer.subject_public_key()); + + const std::vector sig_info = + split_on(OIDS::lookup(m_sig_algo.get_oid()), '/'); + + if(sig_info.size() != 2 || sig_info[0] != pub_key->algo_name()) + return Certificate_Status_Code::OCSP_RESPONSE_INVALID; + + std::string padding = sig_info[1]; + Signature_Format format = (pub_key->message_parts() >= 2) ? DER_SEQUENCE : IEEE_1363; + + PK_Verifier verifier(*pub_key, padding, format); + + if(verifier.verify_message(ASN1::put_in_sequence(m_tbs_bits), m_signature)) + return Certificate_Status_Code::OCSP_SIGNATURE_OK; + else + return Certificate_Status_Code::OCSP_SIGNATURE_ERROR; + } + catch(Exception&) + { + return Certificate_Status_Code::OCSP_SIGNATURE_ERROR; + } + } + +Certificate_Status_Code Response::check_signature(const std::vector& trusted_roots, + const std::vector>& ee_cert_path) const + { + if (m_responses.empty()) + return m_dummy_response_status; + + std::shared_ptr signing_cert; + + for(size_t i = 0; i != trusted_roots.size(); ++i) + { + if(m_signer_name.empty() && m_key_hash.empty()) + return Certificate_Status_Code::OCSP_RESPONSE_INVALID; + + if(!m_signer_name.empty()) + { + signing_cert = trusted_roots[i]->find_cert(m_signer_name, std::vector()); + if(signing_cert) + { + break; + } + } + + if(m_key_hash.size() > 0) + { + signing_cert = trusted_roots[i]->find_cert_by_pubkey_sha1(m_key_hash); + if(signing_cert) + { + break; + } + } + } + + if(!signing_cert && ee_cert_path.size() > 1) + { + // End entity cert is not allowed to sign their own OCSP request :) + for(size_t i = 1; i < ee_cert_path.size(); ++i) + { + // Check all CA certificates in the (assumed validated) EE cert path + if(!m_signer_name.empty() && ee_cert_path[i]->subject_dn() == m_signer_name) + { + signing_cert = ee_cert_path[i]; + break; + } + + if(m_key_hash.size() > 0 && ee_cert_path[i]->subject_public_key_bitstring_sha1() == m_key_hash) + { + signing_cert = ee_cert_path[i]; + break; + } + } + } + + if(!signing_cert && m_certs.size() > 0) + { + for(size_t i = 0; i < m_certs.size(); ++i) + { + // Check all CA certificates in the (assumed validated) EE cert path + if(!m_signer_name.empty() && m_certs[i].subject_dn() == m_signer_name) + { + signing_cert = std::make_shared(m_certs[i]); + break; + } + + if(m_key_hash.size() > 0 && m_certs[i].subject_public_key_bitstring_sha1() == m_key_hash) + { + signing_cert = std::make_shared(m_certs[i]); + break; + } + } + } + + if(!signing_cert) + return Certificate_Status_Code::OCSP_ISSUER_NOT_FOUND; + + if(!signing_cert->allowed_usage(CRL_SIGN) && + !signing_cert->allowed_extended_usage("PKIX.OCSPSigning")) + { + return Certificate_Status_Code::OCSP_RESPONSE_MISSING_KEYUSAGE; + } + + return this->verify_signature(*signing_cert); + } + +Certificate_Status_Code Response::status_for(const X509_Certificate& issuer, + const X509_Certificate& subject, + std::chrono::system_clock::time_point ref_time) const + { + if (m_responses.empty()) + return m_dummy_response_status; + + for(const auto& response : m_responses) + { + if(response.certid().is_id_for(issuer, subject)) + { + X509_Time x509_ref_time(ref_time); + + if(response.cert_status() == 1) + return Certificate_Status_Code::CERT_IS_REVOKED; + + if(response.this_update() > x509_ref_time) + return Certificate_Status_Code::OCSP_NOT_YET_VALID; + + if(response.next_update().time_is_set() && x509_ref_time > response.next_update()) + return Certificate_Status_Code::OCSP_HAS_EXPIRED; + + if(response.cert_status() == 0) + return Certificate_Status_Code::OCSP_RESPONSE_GOOD; + else + return Certificate_Status_Code::OCSP_BAD_STATUS; + } + } + + return Certificate_Status_Code::OCSP_CERT_NOT_LISTED; + } + +#if defined(BOTAN_HAS_HTTP_UTIL) + +Response online_check(const X509_Certificate& issuer, + const BigInt& subject_serial, + const std::string& ocsp_responder, + Certificate_Store* trusted_roots, + std::chrono::milliseconds timeout) + { + if(ocsp_responder.empty()) + throw Invalid_Argument("No OCSP responder specified"); + + OCSP::Request req(issuer, subject_serial); + + auto http = HTTP::POST_sync(ocsp_responder, + "application/ocsp-request", + req.BER_encode(), + 1, + timeout); + + http.throw_unless_ok(); + + // Check the MIME type? + + OCSP::Response response(http.body()); + + std::vector trusted_roots_vec; + trusted_roots_vec.push_back(trusted_roots); + + if(trusted_roots) + response.check_signature(trusted_roots_vec); + + return response; + } + + +Response online_check(const X509_Certificate& issuer, + const X509_Certificate& subject, + Certificate_Store* trusted_roots, + std::chrono::milliseconds timeout) + { + if(subject.issuer_dn() != issuer.subject_dn()) + throw Invalid_Argument("Invalid cert pair to OCSP::online_check (mismatched issuer,subject args?)"); + + return online_check(issuer, + BigInt::decode(subject.serial_number()), + subject.ocsp_responder(), + trusted_roots, + timeout); + } + +#endif + +} + +} diff --git a/src/libs/3rdparty/botan/src/lib/x509/ocsp.h b/src/libs/3rdparty/botan/src/lib/x509/ocsp.h new file mode 100644 index 0000000000..884b1c5b33 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/x509/ocsp.h @@ -0,0 +1,212 @@ +/* +* OCSP +* (C) 2012 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_OCSP_H_ +#define BOTAN_OCSP_H_ + +#include +#include +#include +#include + +namespace Botan { + +class Certificate_Store; + +namespace OCSP { + +/** +* An OCSP request. +*/ +class BOTAN_PUBLIC_API(2,0) Request final + { + public: + /** + * Create an OCSP request. + * @param issuer_cert issuer certificate + * @param subject_cert subject certificate + */ + Request(const X509_Certificate& issuer_cert, + const X509_Certificate& subject_cert); + + Request(const X509_Certificate& issuer_cert, + const BigInt& subject_serial); + + /** + * @return BER-encoded OCSP request + */ + std::vector BER_encode() const; + + /** + * @return Base64-encoded OCSP request + */ + std::string base64_encode() const; + + /** + * @return issuer certificate + */ + const X509_Certificate& issuer() const { return m_issuer; } + + /** + * @return subject certificate + */ + const X509_Certificate& subject() const { throw Not_Implemented("Method have been deprecated"); } + + const std::vector& issuer_key_hash() const + { return m_certid.issuer_key_hash(); } + private: + X509_Certificate m_issuer; + CertID m_certid; + }; + +/** +* OCSP response. +* +* Note this class is only usable as an OCSP client +*/ +class BOTAN_PUBLIC_API(2,0) Response final + { + public: + /** + * Creates an empty OCSP response. + */ + Response() = default; + + /** + * Create a fake OCSP response from a given status code. + * @param status the status code the check functions will return + */ + Response(Certificate_Status_Code status); + + /** + * Parses an OCSP response. + * @param response_bits response bits received + */ + Response(const std::vector& response_bits) : + Response(response_bits.data(), response_bits.size()) + {} + + /** + * Parses an OCSP response. + * @param response_bits response bits received + * @param response_bits_len length of response in bytes + */ + Response(const uint8_t response_bits[], + size_t response_bits_len); + + /** + * Check signature and return status + * The optional cert_path is the (already validated!) certificate path of + * the end entity which is being inquired about + * @param trust_roots list of certstores containing trusted roots + * @param cert_path optionally, the (already verified!) certificate path for the certificate + * this is an OCSP response for. This is necessary to find the correct intermediate CA in + * some cases. + */ + Certificate_Status_Code check_signature(const std::vector& trust_roots, + const std::vector>& cert_path = {}) const; + + /** + * Verify that issuer's key signed this response + * @param issuer certificate of issuer + * @return if signature valid OCSP_SIGNATURE_OK else an error code + */ + Certificate_Status_Code verify_signature(const X509_Certificate& issuer) const; + + /** + * @return the time this OCSP response was supposedly produced at + */ + const X509_Time& produced_at() const { return m_produced_at; } + + /** + * @return DN of signer, if provided in response (may be empty) + */ + const X509_DN& signer_name() const { return m_signer_name; } + + /** + * @return key hash, if provided in response (may be empty) + */ + const std::vector& signer_key_hash() const { return m_key_hash; } + + const std::vector& raw_bits() const { return m_response_bits; } + + /** + * Searches the OCSP response for issuer and subject certificate. + * @param issuer issuer certificate + * @param subject subject certificate + * @param ref_time the reference time + * @return OCSP status code, possible values: + * CERT_IS_REVOKED, + * OCSP_NOT_YET_VALID, + * OCSP_HAS_EXPIRED, + * OCSP_RESPONSE_GOOD, + * OCSP_BAD_STATUS, + * OCSP_CERT_NOT_LISTED + */ + Certificate_Status_Code status_for(const X509_Certificate& issuer, + const X509_Certificate& subject, + std::chrono::system_clock::time_point ref_time = std::chrono::system_clock::now()) const; + + /** + * @return the certificate chain, if provided in response + */ + const std::vector &certificates() const { return m_certs; } + + private: + std::vector m_response_bits; + X509_Time m_produced_at; + X509_DN m_signer_name; + std::vector m_key_hash; + std::vector m_tbs_bits; + AlgorithmIdentifier m_sig_algo; + std::vector m_signature; + std::vector m_certs; + + std::vector m_responses; + + Certificate_Status_Code m_dummy_response_status; + }; + +#if defined(BOTAN_HAS_HTTP_UTIL) + +/** +* Makes an online OCSP request via HTTP and returns the OCSP response. +* @param issuer issuer certificate +* @param subject_serial the subject's serial number +* @param ocsp_responder the OCSP responder to query +* @param trusted_roots trusted roots for the OCSP response +* @param timeout a timeout on the HTTP request +* @return OCSP response +*/ +BOTAN_PUBLIC_API(2,1) +Response online_check(const X509_Certificate& issuer, + const BigInt& subject_serial, + const std::string& ocsp_responder, + Certificate_Store* trusted_roots, + std::chrono::milliseconds timeout = std::chrono::milliseconds(3000)); + +/** +* Makes an online OCSP request via HTTP and returns the OCSP response. +* @param issuer issuer certificate +* @param subject subject certificate +* @param trusted_roots trusted roots for the OCSP response +* @param timeout a timeout on the HTTP request +* @return OCSP response +*/ +BOTAN_PUBLIC_API(2,0) +Response online_check(const X509_Certificate& issuer, + const X509_Certificate& subject, + Certificate_Store* trusted_roots, + std::chrono::milliseconds timeout = std::chrono::milliseconds(3000)); + +#endif + +} + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/x509/ocsp_types.cpp b/src/libs/3rdparty/botan/src/lib/x509/ocsp_types.cpp new file mode 100644 index 0000000000..3eda5c05bb --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/x509/ocsp_types.cpp @@ -0,0 +1,105 @@ +/* +* OCSP subtypes +* (C) 2012 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include +#include +#include + +namespace Botan { + +namespace OCSP { + +CertID::CertID(const X509_Certificate& issuer, + const BigInt& subject_serial) + { + /* + In practice it seems some responders, including, notably, + ocsp.verisign.com, will reject anything but SHA-1 here + */ + std::unique_ptr hash(HashFunction::create_or_throw("SHA-160")); + + m_hash_id = AlgorithmIdentifier(hash->name(), AlgorithmIdentifier::USE_NULL_PARAM); + m_issuer_key_hash = unlock(hash->process(issuer.subject_public_key_bitstring())); + m_issuer_dn_hash = unlock(hash->process(issuer.raw_subject_dn())); + m_subject_serial = subject_serial; + } + +bool CertID::is_id_for(const X509_Certificate& issuer, + const X509_Certificate& subject) const + { + try + { + if(BigInt::decode(subject.serial_number()) != m_subject_serial) + return false; + + std::unique_ptr hash(HashFunction::create(OIDS::lookup(m_hash_id.get_oid()))); + + if(m_issuer_dn_hash != unlock(hash->process(subject.raw_issuer_dn()))) + return false; + + if(m_issuer_key_hash != unlock(hash->process(issuer.subject_public_key_bitstring()))) + return false; + } + catch(...) + { + return false; + } + + return true; + } + +void CertID::encode_into(class DER_Encoder& to) const + { + to.start_cons(SEQUENCE) + .encode(m_hash_id) + .encode(m_issuer_dn_hash, OCTET_STRING) + .encode(m_issuer_key_hash, OCTET_STRING) + .encode(m_subject_serial) + .end_cons(); + } + +void CertID::decode_from(class BER_Decoder& from) + { + from.start_cons(SEQUENCE) + .decode(m_hash_id) + .decode(m_issuer_dn_hash, OCTET_STRING) + .decode(m_issuer_key_hash, OCTET_STRING) + .decode(m_subject_serial) + .end_cons(); + + } + +void SingleResponse::encode_into(class DER_Encoder&) const + { + throw Not_Implemented("SingleResponse::encode_into"); + } + +void SingleResponse::decode_from(class BER_Decoder& from) + { + BER_Object cert_status; + Extensions extensions; + + from.start_cons(SEQUENCE) + .decode(m_certid) + .get_next(cert_status) + .decode(m_thisupdate) + .decode_optional(m_nextupdate, ASN1_Tag(0), + ASN1_Tag(CONTEXT_SPECIFIC | CONSTRUCTED)) + .decode_optional(extensions, + ASN1_Tag(1), + ASN1_Tag(CONTEXT_SPECIFIC | CONSTRUCTED)) + .end_cons(); + + m_cert_status = cert_status.type(); + } + +} + +} diff --git a/src/libs/3rdparty/botan/src/lib/x509/ocsp_types.h b/src/libs/3rdparty/botan/src/lib/x509/ocsp_types.h new file mode 100644 index 0000000000..8131addb16 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/x509/ocsp_types.h @@ -0,0 +1,68 @@ +/* +* OCSP subtypes +* (C) 2012 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_OCSP_TYPES_H_ +#define BOTAN_OCSP_TYPES_H_ + +#include +#include +#include + +namespace Botan { + +namespace OCSP { + +class BOTAN_PUBLIC_API(2,0) CertID final : public ASN1_Object + { + public: + CertID() = default; + + CertID(const X509_Certificate& issuer, + const BigInt& subject_serial); + + bool is_id_for(const X509_Certificate& issuer, + const X509_Certificate& subject) const; + + void encode_into(class DER_Encoder& to) const override; + + void decode_from(class BER_Decoder& from) override; + + const std::vector& issuer_key_hash() const { return m_issuer_key_hash; } + + private: + AlgorithmIdentifier m_hash_id; + std::vector m_issuer_dn_hash; + std::vector m_issuer_key_hash; + BigInt m_subject_serial; + }; + +class BOTAN_PUBLIC_API(2,0) SingleResponse final : public ASN1_Object + { + public: + const CertID& certid() const { return m_certid; } + + size_t cert_status() const { return m_cert_status; } + + X509_Time this_update() const { return m_thisupdate; } + + X509_Time next_update() const { return m_nextupdate; } + + void encode_into(class DER_Encoder& to) const override; + + void decode_from(class BER_Decoder& from) override; + private: + CertID m_certid; + size_t m_cert_status = 2; // unknown + X509_Time m_thisupdate; + X509_Time m_nextupdate; + }; + +} + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/x509/pkcs10.cpp b/src/libs/3rdparty/botan/src/lib/x509/pkcs10.cpp new file mode 100644 index 0000000000..2da002cd16 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/x509/pkcs10.cpp @@ -0,0 +1,314 @@ +/* +* PKCS #10 +* (C) 1999-2007,2017 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Botan { + +struct PKCS10_Data + { + X509_DN m_subject_dn; + std::vector m_public_key_bits; + AlternativeName m_alt_name; + std::string m_challenge; + Extensions m_extensions; + }; + +std::string PKCS10_Request::PEM_label() const + { + return "CERTIFICATE REQUEST"; + } + +std::vector PKCS10_Request::alternate_PEM_labels() const + { + return { "NEW CERTIFICATE REQUEST" }; + } + +PKCS10_Request::PKCS10_Request(DataSource& src) + { + load_data(src); + } + +PKCS10_Request::PKCS10_Request(const std::vector& vec) + { + DataSource_Memory src(vec.data(), vec.size()); + load_data(src); + } + +#if defined(BOTAN_TARGET_OS_HAS_FILESYSTEM) +PKCS10_Request::PKCS10_Request(const std::string& fsname) + { + DataSource_Stream src(fsname, true); + load_data(src); + } +#endif + +//static +PKCS10_Request PKCS10_Request::create(const Private_Key& key, + const X509_DN& subject_dn, + const Extensions& extensions, + const std::string& hash_fn, + RandomNumberGenerator& rng, + const std::string& padding_scheme, + const std::string& challenge) + { + const std::map sig_opts = { {"padding", padding_scheme} }; + + AlgorithmIdentifier sig_algo; + std::unique_ptr signer = choose_sig_format(sig_algo, key, rng, hash_fn, padding_scheme); + + const size_t PKCS10_VERSION = 0; + + DER_Encoder tbs_req; + + tbs_req.start_cons(SEQUENCE) + .encode(PKCS10_VERSION) + .encode(subject_dn) + .raw_bytes(key.subject_public_key()) + .start_explicit(0); + + if(challenge.empty() == false) + { + ASN1_String challenge_str(challenge, DIRECTORY_STRING); + + tbs_req.encode( + Attribute("PKCS9.ChallengePassword", + DER_Encoder().encode(challenge_str).get_contents_unlocked() + ) + ); + } + + tbs_req.encode( + Attribute("PKCS9.ExtensionRequest", + DER_Encoder() + .start_cons(SEQUENCE) + .encode(extensions) + .end_cons() + .get_contents_unlocked() + ) + ) + .end_explicit() + .end_cons(); + + const std::vector req = + X509_Object::make_signed(signer.get(), rng, sig_algo, + tbs_req.get_contents()); + + return PKCS10_Request(req); + } + +/* +* Decode the CertificateRequestInfo +*/ +namespace { + +std::unique_ptr decode_pkcs10(const std::vector& body) + { + std::unique_ptr data(new PKCS10_Data); + + BER_Decoder cert_req_info(body); + + size_t version; + cert_req_info.decode(version); + if(version != 0) + throw Decoding_Error("Unknown version code in PKCS #10 request: " + + std::to_string(version)); + + cert_req_info.decode(data->m_subject_dn); + + BER_Object public_key = cert_req_info.get_next_object(); + if(public_key.is_a(SEQUENCE, CONSTRUCTED) == false) + throw BER_Bad_Tag("PKCS10_Request: Unexpected tag for public key", public_key.tagging()); + + data->m_public_key_bits = ASN1::put_in_sequence(public_key.bits(), public_key.length()); + + BER_Object attr_bits = cert_req_info.get_next_object(); + + std::set pkcs9_email; + + if(attr_bits.is_a(0, ASN1_Tag(CONSTRUCTED | CONTEXT_SPECIFIC))) + { + BER_Decoder attributes(attr_bits); + while(attributes.more_items()) + { + Attribute attr; + attributes.decode(attr); + + const OID& oid = attr.get_oid(); + BER_Decoder value(attr.get_parameters()); + + if(oid == OIDS::lookup("PKCS9.EmailAddress")) + { + ASN1_String email; + value.decode(email); + pkcs9_email.insert(email.value()); + } + else if(oid == OIDS::lookup("PKCS9.ChallengePassword")) + { + ASN1_String challenge_password; + value.decode(challenge_password); + data->m_challenge = challenge_password.value(); + } + else if(oid == OIDS::lookup("PKCS9.ExtensionRequest")) + { + value.decode(data->m_extensions).verify_end(); + } + } + attributes.verify_end(); + } + else if(attr_bits.is_set()) + throw BER_Bad_Tag("PKCS10_Request: Unexpected tag for attributes", attr_bits.tagging()); + + cert_req_info.verify_end(); + + if(auto ext = data->m_extensions.get_extension_object_as()) + { + data->m_alt_name = ext->get_alt_name(); + } + + for(std::string email : pkcs9_email) + { + data->m_alt_name.add_attribute("RFC882", email); + } + + return data; + } + +} + +void PKCS10_Request::force_decode() + { + m_data.reset(); + + std::unique_ptr data = decode_pkcs10(signed_body()); + + m_data.reset(data.release()); + + if(!this->check_signature(subject_public_key())) + throw Decoding_Error("PKCS #10 request: Bad signature detected"); + } + +const PKCS10_Data& PKCS10_Request::data() const + { + if(m_data == nullptr) + throw Decoding_Error("PKCS10_Request decoding failed"); + return *m_data.get(); + } + +/* +* Return the challenge password (if any) +*/ +std::string PKCS10_Request::challenge_password() const + { + return data().m_challenge; + } + +/* +* Return the name of the requestor +*/ +const X509_DN& PKCS10_Request::subject_dn() const + { + return data().m_subject_dn; + } + +/* +* Return the public key of the requestor +*/ +const std::vector& PKCS10_Request::raw_public_key() const + { + return data().m_public_key_bits; + } + +/* +* Return the public key of the requestor +*/ +Public_Key* PKCS10_Request::subject_public_key() const + { + DataSource_Memory source(raw_public_key()); + return X509::load_key(source); + } + +/* +* Return the alternative names of the requestor +*/ +const AlternativeName& PKCS10_Request::subject_alt_name() const + { + return data().m_alt_name; + } + +/* +* Return the X509v3 extensions +*/ +const Extensions& PKCS10_Request::extensions() const + { + return data().m_extensions; + } + +/* +* Return the key constraints (if any) +*/ +Key_Constraints PKCS10_Request::constraints() const + { + if(auto ext = extensions().get(OIDS::lookup("X509v3.KeyUsage"))) + { + return dynamic_cast(*ext).get_constraints(); + } + + return NO_CONSTRAINTS; + } + +/* +* Return the extendend key constraints (if any) +*/ +std::vector PKCS10_Request::ex_constraints() const + { + if(auto ext = extensions().get(OIDS::lookup("X509v3.ExtendedKeyUsage"))) + { + return dynamic_cast(*ext).get_oids(); + } + + return {}; + } + +/* +* Return is a CA certificate is requested +*/ +bool PKCS10_Request::is_CA() const + { + if(auto ext = extensions().get(OIDS::lookup("X509v3.BasicConstraints"))) + { + return dynamic_cast(*ext).get_is_ca(); + } + + return false; + } + +/* +* Return the desired path limit (if any) +*/ +size_t PKCS10_Request::path_limit() const + { + if(auto ext = extensions().get(OIDS::lookup("X509v3.BasicConstraints"))) + { + Cert_Extension::Basic_Constraints& basic_constraints = dynamic_cast(*ext); + if(basic_constraints.get_is_ca()) + { + return basic_constraints.get_path_limit(); + } + } + + return 0; + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/x509/pkcs10.h b/src/libs/3rdparty/botan/src/lib/x509/pkcs10.h new file mode 100644 index 0000000000..bd8cdb2e14 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/x509/pkcs10.h @@ -0,0 +1,148 @@ +/* +* PKCS #10 +* (C) 1999-2007 Jack Lloyd +* (C) 2016 René Korthaus, Rohde & Schwarz Cybersecurity +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_PKCS10_H_ +#define BOTAN_PKCS10_H_ + +#include +#include +#include +#include +#include +#include + +namespace Botan { + +class Private_Key; +class Extensions; +struct PKCS10_Data; + +/** +* PKCS #10 Certificate Request. +*/ +class BOTAN_PUBLIC_API(2,0) PKCS10_Request final : public X509_Object + { + public: + /** + * Get the subject public key. + * @return subject public key + */ + Public_Key* subject_public_key() const; + + /** + * Get the raw DER encoded public key. + * @return raw DER encoded public key + */ + const std::vector& raw_public_key() const; + + /** + * Get the subject DN. + * @return subject DN + */ + const X509_DN& subject_dn() const; + + /** + * Get the subject alternative name. + * @return subject alternative name. + */ + const AlternativeName& subject_alt_name() const; + + /** + * Get the key constraints for the key associated with this + * PKCS#10 object. + * @return key constraints + */ + Key_Constraints constraints() const; + + /** + * Get the extendend key constraints (if any). + * @return extended key constraints + */ + std::vector ex_constraints() const; + + /** + * Find out whether this is a CA request. + * @result true if it is a CA request, false otherwise. + */ + bool is_CA() const; + + /** + * Return the constraint on the path length defined + * in the BasicConstraints extension. + * @return path limit + */ + size_t path_limit() const; + + /** + * Get the challenge password for this request + * @return challenge password for this request + */ + std::string challenge_password() const; + + /** + * Get the X509v3 extensions. + * @return X509v3 extensions + */ + const Extensions& extensions() const; + + /** + * Create a PKCS#10 Request from a data source. + * @param source the data source providing the DER encoded request + */ + explicit PKCS10_Request(DataSource& source); + +#if defined(BOTAN_TARGET_OS_HAS_FILESYSTEM) + /** + * Create a PKCS#10 Request from a file. + * @param filename the name of the file containing the DER or PEM + * encoded request file + */ + explicit PKCS10_Request(const std::string& filename); +#endif + + /** + * Create a PKCS#10 Request from binary data. + * @param vec a std::vector containing the DER value + */ + explicit PKCS10_Request(const std::vector& vec); + + /** + * Create a new PKCS10 certificate request + * @param key the key that will be included in the certificate request + * @param subject_dn the DN to be placed in the request + * @param extensions extensions to include in the request + * @param hash_fn the hash function to use to create the signature + * @param rng a random number generator + * @param padding_scheme if set specifies the padding scheme, otherwise an + * algorithm-specific default is used. + * @param challenge a challenge string to be included in the PKCS10 request, + * sometimes used for revocation purposes. + */ + static PKCS10_Request create(const Private_Key& key, + const X509_DN& subject_dn, + const Extensions& extensions, + const std::string& hash_fn, + RandomNumberGenerator& rng, + const std::string& padding_scheme = "", + const std::string& challenge = ""); + + private: + std::string PEM_label() const override; + + std::vector alternate_PEM_labels() const override; + + void force_decode() override; + + const PKCS10_Data& data() const; + + std::shared_ptr m_data; + }; + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/x509/x509_ca.cpp b/src/libs/3rdparty/botan/src/lib/x509/x509_ca.cpp new file mode 100644 index 0000000000..73eea4a95b --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/x509/x509_ca.cpp @@ -0,0 +1,338 @@ +/* +* X.509 Certificate Authority +* (C) 1999-2010 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Botan { + +/* +* Load the certificate and private key +*/ +X509_CA::X509_CA(const X509_Certificate& c, + const Private_Key& key, + const std::string& hash_fn, + RandomNumberGenerator& rng) : + m_ca_cert(c), + m_hash_fn(hash_fn) + { + if(!m_ca_cert.is_CA_cert()) + throw Invalid_Argument("X509_CA: This certificate is not for a CA"); + + std::map opts; + // constructor without additional options: use the padding used in the CA certificate + // sig_oid_str = /, so padding with all its options will look + // like a cipher mode to the scanner + std::string sig_oid_str = OIDS::lookup(c.signature_algorithm().oid); + SCAN_Name scanner(sig_oid_str); + std::string pad = scanner.cipher_mode(); + if(!pad.empty()) + opts.insert({"padding",pad}); + + m_signer.reset(choose_sig_format(key, opts, rng, hash_fn, m_ca_sig_algo)); + } + +/* +* Load the certificate and private key, and additional options +*/ +X509_CA::X509_CA(const X509_Certificate& ca_certificate, + const Private_Key& key, + const std::map& opts, + const std::string& hash_fn, + RandomNumberGenerator& rng) : m_ca_cert(ca_certificate), m_hash_fn(hash_fn) + { + if(!m_ca_cert.is_CA_cert()) + throw Invalid_Argument("X509_CA: This certificate is not for a CA"); + + m_signer.reset(choose_sig_format(key, opts, rng, hash_fn, m_ca_sig_algo)); + } + +/* +* X509_CA Destructor +*/ +X509_CA::~X509_CA() + { + /* for unique_ptr */ + } + +namespace { + +Extensions choose_extensions(const PKCS10_Request& req, + const X509_Certificate& ca_cert, + const std::string& hash_fn) + { + Key_Constraints constraints; + if(req.is_CA()) + { + constraints = Key_Constraints(KEY_CERT_SIGN | CRL_SIGN); + } + else + { + std::unique_ptr key(req.subject_public_key()); + verify_cert_constraints_valid_for_key_type(*key, req.constraints()); + constraints = req.constraints(); + } + + Extensions extensions = req.extensions(); + + extensions.replace( + new Cert_Extension::Basic_Constraints(req.is_CA(), req.path_limit()), + true); + + if(constraints != NO_CONSTRAINTS) + { + extensions.replace(new Cert_Extension::Key_Usage(constraints), true); + } + + extensions.replace(new Cert_Extension::Authority_Key_ID(ca_cert.subject_key_id())); + extensions.replace(new Cert_Extension::Subject_Key_ID(req.raw_public_key(), hash_fn)); + + extensions.replace( + new Cert_Extension::Subject_Alternative_Name(req.subject_alt_name())); + + extensions.replace( + new Cert_Extension::Extended_Key_Usage(req.ex_constraints())); + + return extensions; + } + +} + +X509_Certificate X509_CA::sign_request(const PKCS10_Request& req, + RandomNumberGenerator& rng, + const BigInt& serial_number, + const X509_Time& not_before, + const X509_Time& not_after) const + { + auto extensions = choose_extensions(req, m_ca_cert, m_hash_fn); + + return make_cert(m_signer.get(), rng, serial_number, + m_ca_sig_algo, req.raw_public_key(), + not_before, not_after, + m_ca_cert.subject_dn(), req.subject_dn(), + extensions); + } + +/* +* Sign a PKCS #10 certificate request +*/ +X509_Certificate X509_CA::sign_request(const PKCS10_Request& req, + RandomNumberGenerator& rng, + const X509_Time& not_before, + const X509_Time& not_after) const + { + auto extensions = choose_extensions(req, m_ca_cert, m_hash_fn); + + return make_cert(m_signer.get(), rng, m_ca_sig_algo, + req.raw_public_key(), + not_before, not_after, + m_ca_cert.subject_dn(), req.subject_dn(), + extensions); + } + +X509_Certificate X509_CA::make_cert(PK_Signer* signer, + RandomNumberGenerator& rng, + const AlgorithmIdentifier& sig_algo, + const std::vector& pub_key, + const X509_Time& not_before, + const X509_Time& not_after, + const X509_DN& issuer_dn, + const X509_DN& subject_dn, + const Extensions& extensions) + { + const size_t SERIAL_BITS = 128; + BigInt serial_no(rng, SERIAL_BITS); + + return make_cert(signer, rng, serial_no, sig_algo, pub_key, + not_before, not_after, issuer_dn, subject_dn, extensions); + } + +/* +* Create a new certificate +*/ +X509_Certificate X509_CA::make_cert(PK_Signer* signer, + RandomNumberGenerator& rng, + const BigInt& serial_no, + const AlgorithmIdentifier& sig_algo, + const std::vector& pub_key, + const X509_Time& not_before, + const X509_Time& not_after, + const X509_DN& issuer_dn, + const X509_DN& subject_dn, + const Extensions& extensions) + { + const size_t X509_CERT_VERSION = 3; + + // clang-format off + return X509_Certificate(X509_Object::make_signed( + signer, rng, sig_algo, + DER_Encoder().start_cons(SEQUENCE) + .start_explicit(0) + .encode(X509_CERT_VERSION-1) + .end_explicit() + + .encode(serial_no) + + .encode(sig_algo) + .encode(issuer_dn) + + .start_cons(SEQUENCE) + .encode(not_before) + .encode(not_after) + .end_cons() + + .encode(subject_dn) + .raw_bytes(pub_key) + + .start_explicit(3) + .start_cons(SEQUENCE) + .encode(extensions) + .end_cons() + .end_explicit() + .end_cons() + .get_contents() + )); + // clang-format on + } + +/* +* Create a new, empty CRL +*/ +X509_CRL X509_CA::new_crl(RandomNumberGenerator& rng, + uint32_t next_update) const + { + return new_crl(rng, + std::chrono::system_clock::now(), + std::chrono::seconds(next_update)); + } + +/* +* Update a CRL with new entries +*/ +X509_CRL X509_CA::update_crl(const X509_CRL& crl, + const std::vector& new_revoked, + RandomNumberGenerator& rng, + uint32_t next_update) const + { + return update_crl(crl, new_revoked, rng, + std::chrono::system_clock::now(), + std::chrono::seconds(next_update)); + } + + +X509_CRL X509_CA::new_crl(RandomNumberGenerator& rng, + std::chrono::system_clock::time_point issue_time, + std::chrono::seconds next_update) const + { + std::vector empty; + return make_crl(empty, 1, rng, issue_time, next_update); + } + +X509_CRL X509_CA::update_crl(const X509_CRL& last_crl, + const std::vector& new_revoked, + RandomNumberGenerator& rng, + std::chrono::system_clock::time_point issue_time, + std::chrono::seconds next_update) const + { + std::vector revoked = last_crl.get_revoked(); + + std::copy(new_revoked.begin(), new_revoked.end(), + std::back_inserter(revoked)); + + return make_crl(revoked, last_crl.crl_number() + 1, rng, issue_time, next_update); + } + +/* +* Create a CRL +*/ +X509_CRL X509_CA::make_crl(const std::vector& revoked, + uint32_t crl_number, + RandomNumberGenerator& rng, + std::chrono::system_clock::time_point issue_time, + std::chrono::seconds next_update) const + { + const size_t X509_CRL_VERSION = 2; + + auto expire_time = issue_time + next_update; + + Extensions extensions; + extensions.add(new Cert_Extension::Authority_Key_ID(m_ca_cert.subject_key_id())); + extensions.add(new Cert_Extension::CRL_Number(crl_number)); + + // clang-format off + const std::vector crl = X509_Object::make_signed( + m_signer.get(), rng, m_ca_sig_algo, + DER_Encoder().start_cons(SEQUENCE) + .encode(X509_CRL_VERSION-1) + .encode(m_ca_sig_algo) + .encode(m_ca_cert.subject_dn()) + .encode(X509_Time(issue_time)) + .encode(X509_Time(expire_time)) + .encode_if(revoked.size() > 0, + DER_Encoder() + .start_cons(SEQUENCE) + .encode_list(revoked) + .end_cons() + ) + .start_explicit(0) + .start_cons(SEQUENCE) + .encode(extensions) + .end_cons() + .end_explicit() + .end_cons() + .get_contents()); + // clang-format on + + return X509_CRL(crl); + } + +/* +* Return the CA's certificate +*/ +X509_Certificate X509_CA::ca_certificate() const + { + return m_ca_cert; + } + +/* +* Choose a signing format for the key +*/ + +PK_Signer* choose_sig_format(const Private_Key& key, + RandomNumberGenerator& rng, + const std::string& hash_fn, + AlgorithmIdentifier& sig_algo) + { + return X509_Object::choose_sig_format(sig_algo, key, rng, hash_fn, "").release(); + } + +PK_Signer* choose_sig_format(const Private_Key& key, + const std::map& opts, + RandomNumberGenerator& rng, + const std::string& hash_fn, + AlgorithmIdentifier& sig_algo) + { + std::string padding; + if(opts.count("padding")) + padding = opts.at("padding"); + return X509_Object::choose_sig_format(sig_algo, key, rng, hash_fn, padding).release(); + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/x509/x509_ca.h b/src/libs/3rdparty/botan/src/lib/x509/x509_ca.h new file mode 100644 index 0000000000..c8ffab69d5 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/x509/x509_ca.h @@ -0,0 +1,262 @@ +/* +* X.509 Certificate Authority +* (C) 1999-2008 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_X509_CA_H_ +#define BOTAN_X509_CA_H_ + +#include +#include +#include + +#if defined(BOTAN_HAS_SYSTEM_RNG) + #include +#endif + +namespace Botan { + +class BigInt; +class Private_Key; +class PKCS10_Request; +class PK_Signer; + +/** +* This class represents X.509 Certificate Authorities (CAs). +*/ +class BOTAN_PUBLIC_API(2,0) X509_CA final + { + public: + /** + * Sign a PKCS#10 Request. + * @param req the request to sign + * @param rng the rng to use + * @param not_before the starting time for the certificate + * @param not_after the expiration time for the certificate + * @return resulting certificate + */ + X509_Certificate sign_request(const PKCS10_Request& req, + RandomNumberGenerator& rng, + const X509_Time& not_before, + const X509_Time& not_after) const; + + /** + * Sign a PKCS#10 Request. + * @param req the request to sign + * @param rng the rng to use + * @param serial_number the serial number the cert will be assigned. + * @param not_before the starting time for the certificate + * @param not_after the expiration time for the certificate + * @return resulting certificate + */ + X509_Certificate sign_request(const PKCS10_Request& req, + RandomNumberGenerator& rng, + const BigInt& serial_number, + const X509_Time& not_before, + const X509_Time& not_after) const; + + /** + * Get the certificate of this CA. + * @return CA certificate + */ + X509_Certificate ca_certificate() const; + + /** + * Create a new and empty CRL for this CA. + * @param rng the random number generator to use + * @param issue_time the issue time (typically system_clock::now) + * @param next_update the time interval after issue_data within which + * a new CRL will be produced. + * @return new CRL + */ + X509_CRL new_crl(RandomNumberGenerator& rng, + std::chrono::system_clock::time_point issue_time, + std::chrono::seconds next_update) const; + + /** + * Create a new CRL by with additional entries. + * @param last_crl the last CRL of this CA to add the new entries to + * @param new_entries contains the new CRL entries to be added to the CRL + * @param rng the random number generator to use + * @param issue_time the issue time (typically system_clock::now) + * @param next_update the time interval after issue_data within which + * a new CRL will be produced. + */ + X509_CRL update_crl(const X509_CRL& last_crl, + const std::vector& new_entries, + RandomNumberGenerator& rng, + std::chrono::system_clock::time_point issue_time, + std::chrono::seconds next_update) const; + + /** + * Create a new and empty CRL for this CA. + * @param rng the random number generator to use + * @param next_update the time to set in next update in seconds + * as the offset from the current time + * @return new CRL + */ + X509_CRL new_crl(RandomNumberGenerator& rng, + uint32_t next_update = 604800) const; + + /** + * Create a new CRL by with additional entries. + * @param last_crl the last CRL of this CA to add the new entries to + * @param new_entries contains the new CRL entries to be added to the CRL + * @param rng the random number generator to use + * @param next_update the time to set in next update in seconds + * as the offset from the current time + */ + X509_CRL update_crl(const X509_CRL& last_crl, + const std::vector& new_entries, + RandomNumberGenerator& rng, + uint32_t next_update = 604800) const; + + /** + * Interface for creating new certificates + * @param signer a signing object + * @param rng a random number generator + * @param sig_algo the signature algorithm identifier + * @param pub_key the serialized public key + * @param not_before the start time of the certificate + * @param not_after the end time of the certificate + * @param issuer_dn the DN of the issuer + * @param subject_dn the DN of the subject + * @param extensions an optional list of certificate extensions + * @returns newly minted certificate + */ + static X509_Certificate make_cert(PK_Signer* signer, + RandomNumberGenerator& rng, + const AlgorithmIdentifier& sig_algo, + const std::vector& pub_key, + const X509_Time& not_before, + const X509_Time& not_after, + const X509_DN& issuer_dn, + const X509_DN& subject_dn, + const Extensions& extensions); + + /** + * Interface for creating new certificates + * @param signer a signing object + * @param rng a random number generator + * @param serial_number the serial number the cert will be assigned + * @param sig_algo the signature algorithm identifier + * @param pub_key the serialized public key + * @param not_before the start time of the certificate + * @param not_after the end time of the certificate + * @param issuer_dn the DN of the issuer + * @param subject_dn the DN of the subject + * @param extensions an optional list of certificate extensions + * @returns newly minted certificate + */ + static X509_Certificate make_cert(PK_Signer* signer, + RandomNumberGenerator& rng, + const BigInt& serial_number, + const AlgorithmIdentifier& sig_algo, + const std::vector& pub_key, + const X509_Time& not_before, + const X509_Time& not_after, + const X509_DN& issuer_dn, + const X509_DN& subject_dn, + const Extensions& extensions); + + /** + * Create a new CA object. + * @param ca_certificate the certificate of the CA + * @param key the private key of the CA + * @param hash_fn name of a hash function to use for signing + * @param rng the random generator to use + */ + X509_CA(const X509_Certificate& ca_certificate, + const Private_Key& key, + const std::string& hash_fn, + RandomNumberGenerator& rng); + + /** + * Create a new CA object. + * @param ca_certificate the certificate of the CA + * @param key the private key of the CA + * @param opts additional options, e.g. padding, as key value pairs + * @param hash_fn name of a hash function to use for signing + * @param rng the random generator to use + */ + X509_CA(const X509_Certificate& ca_certificate, + const Private_Key& key, + const std::map& opts, + const std::string& hash_fn, + RandomNumberGenerator& rng); + +#if defined(BOTAN_HAS_SYSTEM_RNG) + BOTAN_DEPRECATED("Use version taking RNG object") + X509_CA(const X509_Certificate& ca_certificate, + const Private_Key& key, + const std::string& hash_fn) : + X509_CA(ca_certificate, key, hash_fn, system_rng()) + {} +#endif + + X509_CA(const X509_CA&) = delete; + X509_CA& operator=(const X509_CA&) = delete; + +#if !defined(BOTAN_BUILD_COMPILER_IS_MSVC_2013) + X509_CA(X509_CA&&) = default; + X509_CA& operator=(X509_CA&&) = default; +#endif + + ~X509_CA(); + + private: + X509_CRL make_crl(const std::vector& entries, + uint32_t crl_number, + RandomNumberGenerator& rng, + std::chrono::system_clock::time_point issue_time, + std::chrono::seconds next_update) const; + + AlgorithmIdentifier m_ca_sig_algo; + X509_Certificate m_ca_cert; + std::string m_hash_fn; + std::unique_ptr m_signer; + }; + +/** +* Choose the default signature format for a certain public key signature +* scheme. +* @param key will be the key to choose a padding scheme for +* @param rng the random generator to use +* @param hash_fn is the desired hash function +* @param alg_id will be set to the chosen scheme +* @return A PK_Signer object for generating signatures +*/ +BOTAN_PUBLIC_API(2,0) PK_Signer* choose_sig_format(const Private_Key& key, + RandomNumberGenerator& rng, + const std::string& hash_fn, + AlgorithmIdentifier& alg_id); + +/** +* @verbatim +* Choose the default signature format for a certain public key signature +* scheme. +* +* The only option recognized by opts at this moment is "padding" +* Find an entry from src/build-data/oids.txt under [signature] of the form +* /[()] and add {"padding",} +* to opts. +* @endverbatim +* +* @param key will be the key to choose a padding scheme for +* @param opts contains additional options for building the certificate +* @param rng the random generator to use +* @param hash_fn is the desired hash function +* @param alg_id will be set to the chosen scheme +* @return A PK_Signer object for generating signatures +*/ +PK_Signer* choose_sig_format(const Private_Key& key, + const std::map& opts, + RandomNumberGenerator& rng, + const std::string& hash_fn, + AlgorithmIdentifier& alg_id); + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/x509/x509_crl.cpp b/src/libs/3rdparty/botan/src/lib/x509/x509_crl.cpp new file mode 100644 index 0000000000..47742c1dad --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/x509/x509_crl.cpp @@ -0,0 +1,268 @@ +/* +* X.509 CRL +* (C) 1999-2007 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include + +#include + +namespace Botan { + +struct CRL_Data + { + X509_DN m_issuer; + X509_Time m_this_update; + X509_Time m_next_update; + std::vector m_entries; + Extensions m_extensions; + + // cached values from extensions + size_t m_crl_number = 0; + std::vector m_auth_key_id; + std::string m_issuing_distribution_point; + }; + +std::string X509_CRL::PEM_label() const + { + return "X509 CRL"; + } + +std::vector X509_CRL::alternate_PEM_labels() const + { + return { "CRL" }; + } + +X509_CRL::X509_CRL(DataSource& src) + { + load_data(src); + } + +X509_CRL::X509_CRL(const std::vector& vec) + { + DataSource_Memory src(vec.data(), vec.size()); + load_data(src); + } + +#if defined(BOTAN_TARGET_OS_HAS_FILESYSTEM) +X509_CRL::X509_CRL(const std::string& fsname) + { + DataSource_Stream src(fsname, true); + load_data(src); + } +#endif + +X509_CRL::X509_CRL(const X509_DN& issuer, + const X509_Time& this_update, + const X509_Time& next_update, + const std::vector& revoked) : + X509_Object() + { + m_data.reset(new CRL_Data); + m_data->m_issuer = issuer; + m_data->m_this_update = this_update; + m_data->m_next_update = next_update; + m_data->m_entries = revoked; + } + +/** +* Check if this particular certificate is listed in the CRL +*/ +bool X509_CRL::is_revoked(const X509_Certificate& cert) const + { + /* + If the cert wasn't issued by the CRL issuer, it's possible the cert + is revoked, but not by this CRL. Maybe throw an exception instead? + */ + if(cert.issuer_dn() != issuer_dn()) + return false; + + std::vector crl_akid = authority_key_id(); + std::vector cert_akid = cert.authority_key_id(); + + if(!crl_akid.empty() && !cert_akid.empty()) + { + if(crl_akid != cert_akid) + return false; + } + + std::vector cert_serial = cert.serial_number(); + + bool is_revoked = false; + + // FIXME would be nice to avoid a linear scan here - maybe sort the entries? + for(const CRL_Entry& entry : get_revoked()) + { + if(cert_serial == entry.serial_number()) + { + if(entry.reason_code() == REMOVE_FROM_CRL) + is_revoked = false; + else + is_revoked = true; + } + } + + return is_revoked; + } + +/* +* Decode the TBSCertList data +*/ +namespace { + +std::unique_ptr decode_crl_body(const std::vector& body, + const AlgorithmIdentifier& sig_algo) + { + std::unique_ptr data(new CRL_Data); + + BER_Decoder tbs_crl(body); + + size_t version; + tbs_crl.decode_optional(version, INTEGER, UNIVERSAL); + + if(version != 0 && version != 1) + throw X509_CRL::X509_CRL_Error("Unknown X.509 CRL version " + + std::to_string(version+1)); + + AlgorithmIdentifier sig_algo_inner; + tbs_crl.decode(sig_algo_inner); + + if(sig_algo != sig_algo_inner) + throw X509_CRL::X509_CRL_Error("Algorithm identifier mismatch"); + + tbs_crl.decode(data->m_issuer) + .decode(data->m_this_update) + .decode(data->m_next_update); + + BER_Object next = tbs_crl.get_next_object(); + + if(next.is_a(SEQUENCE, CONSTRUCTED)) + { + BER_Decoder cert_list(std::move(next)); + + while(cert_list.more_items()) + { + CRL_Entry entry; + cert_list.decode(entry); + data->m_entries.push_back(entry); + } + next = tbs_crl.get_next_object(); + } + + if(next.is_a(0, ASN1_Tag(CONSTRUCTED | CONTEXT_SPECIFIC))) + { + BER_Decoder crl_options(std::move(next)); + crl_options.decode(data->m_extensions).verify_end(); + next = tbs_crl.get_next_object(); + } + + if(next.is_set()) + throw X509_CRL::X509_CRL_Error("Unknown tag in CRL"); + + tbs_crl.verify_end(); + + // Now cache some fields from the extensions + if(auto ext = data->m_extensions.get_extension_object_as()) + { + data->m_crl_number = ext->get_crl_number(); + } + if(auto ext = data->m_extensions.get_extension_object_as()) + { + data->m_auth_key_id = ext->get_key_id(); + } + if(auto ext = data->m_extensions.get_extension_object_as()) + { + std::stringstream ss; + + for(const auto& pair : ext->get_point().contents()) + { + ss << pair.first << ": " << pair.second << " "; + } + data->m_issuing_distribution_point = ss.str(); + } + + return data; + } + +} + +void X509_CRL::force_decode() + { + m_data.reset(decode_crl_body(signed_body(), signature_algorithm()).release()); + } + +const CRL_Data& X509_CRL::data() const + { + if(!m_data) + { + throw Invalid_State("X509_CRL uninitialized"); + } + return *m_data.get(); + } + +const Extensions& X509_CRL::extensions() const + { + return data().m_extensions; + } + +/* +* Return the list of revoked certificates +*/ +const std::vector& X509_CRL::get_revoked() const + { + return data().m_entries; + } + +/* +* Return the distinguished name of the issuer +*/ +const X509_DN& X509_CRL::issuer_dn() const + { + return data().m_issuer; + } + +/* +* Return the key identifier of the issuer +*/ +const std::vector& X509_CRL::authority_key_id() const + { + return data().m_auth_key_id; + } + +/* +* Return the CRL number of this CRL +*/ +uint32_t X509_CRL::crl_number() const + { + return data().m_crl_number; + } + +/* +* Return the issue data of the CRL +*/ +const X509_Time& X509_CRL::this_update() const + { + return data().m_this_update; + } + +/* +* Return the date when a new CRL will be issued +*/ +const X509_Time& X509_CRL::next_update() const + { + return data().m_next_update; + } + +/* +* Return the CRL's distribution point +*/ +std::string X509_CRL::crl_issuing_distribution_point() const + { + return data().m_issuing_distribution_point; + } +} diff --git a/src/libs/3rdparty/botan/src/lib/x509/x509_crl.h b/src/libs/3rdparty/botan/src/lib/x509/x509_crl.h new file mode 100644 index 0000000000..89925aa043 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/x509/x509_crl.h @@ -0,0 +1,141 @@ +/* +* X.509 CRL +* (C) 1999-2007 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_X509_CRL_H_ +#define BOTAN_X509_CRL_H_ + +#include +#include +#include +#include + +namespace Botan { + +class Extensions; +class X509_Certificate; + +struct CRL_Data; + +/** +* This class represents X.509 Certificate Revocation Lists (CRLs). +*/ +class BOTAN_PUBLIC_API(2,0) X509_CRL final : public X509_Object + { + public: + /** + * This class represents CRL related errors. + */ + class BOTAN_PUBLIC_API(2,0) X509_CRL_Error final : public Exception + { + public: + explicit X509_CRL_Error(const std::string& error) : + Exception("X509_CRL: " + error) {} + }; + + /** + * Check if this particular certificate is listed in the CRL + */ + bool is_revoked(const X509_Certificate& cert) const; + + /** + * Get the entries of this CRL in the form of a vector. + * @return vector containing the entries of this CRL. + */ + const std::vector& get_revoked() const; + + /** + * Get the issuer DN of this CRL. + * @return CRLs issuer DN + */ + const X509_DN& issuer_dn() const; + + /** + * @return extension data for this CRL + */ + const Extensions& extensions() const; + + /** + * Get the AuthorityKeyIdentifier of this CRL. + * @return this CRLs AuthorityKeyIdentifier + */ + const std::vector& authority_key_id() const; + + /** + * Get the serial number of this CRL. + * @return CRLs serial number + */ + uint32_t crl_number() const; + + /** + * Get the CRL's thisUpdate value. + * @return CRLs thisUpdate + */ + const X509_Time& this_update() const; + + /** + * Get the CRL's nextUpdate value. + * @return CRLs nextdUpdate + */ + const X509_Time& next_update() const; + + /** + * Get the CRL's distribution point + * @return CRL.IssuingDistributionPoint from the CRL's Data_Store + */ + std::string crl_issuing_distribution_point() const; + + /** + * Create an uninitialized CRL object. Any attempts to access + * this object will throw an exception. + */ + X509_CRL() = default; + + /** + * Construct a CRL from a data source. + * @param source the data source providing the DER or PEM encoded CRL. + */ + X509_CRL(DataSource& source); + +#if defined(BOTAN_TARGET_OS_HAS_FILESYSTEM) + /** + * Construct a CRL from a file containing the DER or PEM encoded CRL. + * @param filename the name of the CRL file + */ + X509_CRL(const std::string& filename); +#endif + + /** + * Construct a CRL from a binary vector + * @param vec the binary (DER) representation of the CRL + */ + X509_CRL(const std::vector& vec); + + /** + * Construct a CRL + * @param issuer issuer of this CRL + * @param thisUpdate valid from + * @param nextUpdate valid until + * @param revoked entries to be included in the CRL + */ + X509_CRL(const X509_DN& issuer, const X509_Time& thisUpdate, + const X509_Time& nextUpdate, const std::vector& revoked); + + private: + std::string PEM_label() const override; + + std::vector alternate_PEM_labels() const override; + + void force_decode() override; + + const CRL_Data& data() const; + + std::shared_ptr m_data; + }; + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/x509/x509_dn.cpp b/src/libs/3rdparty/botan/src/lib/x509/x509_dn.cpp new file mode 100644 index 0000000000..9eb509daba --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/x509/x509_dn.cpp @@ -0,0 +1,382 @@ +/* +* X509_DN +* (C) 1999-2007,2018 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Botan { + +/* +* Add an attribute to a X509_DN +*/ +void X509_DN::add_attribute(const std::string& type, + const std::string& str) + { + add_attribute(OIDS::lookup(type), str); + } + +/* +* Add an attribute to a X509_DN +*/ +void X509_DN::add_attribute(const OID& oid, const ASN1_String& str) + { + if(str.empty()) + return; + + m_rdn.push_back(std::make_pair(oid, str)); + m_dn_bits.clear(); + } + +/* +* Get the attributes of this X509_DN +*/ +std::multimap X509_DN::get_attributes() const + { + std::multimap retval; + + for(auto& i : m_rdn) + multimap_insert(retval, i.first, i.second.value()); + return retval; + } + +/* +* Get the contents of this X.500 Name +*/ +std::multimap X509_DN::contents() const + { + std::multimap retval; + + for(auto& i : m_rdn) + { + std::string str_value = OIDS::oid2str(i.first); + + if(str_value.empty()) + str_value = i.first.as_string(); + multimap_insert(retval, str_value, i.second.value()); + } + return retval; + } + +bool X509_DN::has_field(const std::string& attr) const + { + return has_field(OIDS::lookup(deref_info_field(attr))); + } + +bool X509_DN::has_field(const OID& oid) const + { + for(auto& i : m_rdn) + { + if(i.first == oid) + return true; + } + + return false; + } + +std::string X509_DN::get_first_attribute(const std::string& attr) const + { + const OID oid = OIDS::lookup(deref_info_field(attr)); + return get_first_attribute(oid).value(); + } + +ASN1_String X509_DN::get_first_attribute(const OID& oid) const + { + for(auto& i : m_rdn) + { + if(i.first == oid) + { + return i.second; + } + } + + return ASN1_String(); + } + +/* +* Get a single attribute type +*/ +std::vector X509_DN::get_attribute(const std::string& attr) const + { + const OID oid = OIDS::lookup(deref_info_field(attr)); + + std::vector values; + + for(auto& i : m_rdn) + { + if(i.first == oid) + { + values.push_back(i.second.value()); + } + } + + return values; + } + +/* +* Deref aliases in a subject/issuer info request +*/ +std::string X509_DN::deref_info_field(const std::string& info) + { + if(info == "Name" || info == "CommonName" || info == "CN") return "X520.CommonName"; + if(info == "SerialNumber" || info == "SN") return "X520.SerialNumber"; + if(info == "Country" || info == "C") return "X520.Country"; + if(info == "Organization" || info == "O") return "X520.Organization"; + if(info == "Organizational Unit" || info == "OrgUnit" || info == "OU") + return "X520.OrganizationalUnit"; + if(info == "Locality" || info == "L") return "X520.Locality"; + if(info == "State" || info == "Province" || info == "ST") return "X520.State"; + if(info == "Email") return "RFC822"; + return info; + } + +/* +* Compare two X509_DNs for equality +*/ +bool operator==(const X509_DN& dn1, const X509_DN& dn2) + { + auto attr1 = dn1.get_attributes(); + auto attr2 = dn2.get_attributes(); + + if(attr1.size() != attr2.size()) return false; + + auto p1 = attr1.begin(); + auto p2 = attr2.begin(); + + while(true) + { + if(p1 == attr1.end() && p2 == attr2.end()) + break; + if(p1 == attr1.end()) return false; + if(p2 == attr2.end()) return false; + if(p1->first != p2->first) return false; + if(!x500_name_cmp(p1->second, p2->second)) + return false; + ++p1; + ++p2; + } + return true; + } + +/* +* Compare two X509_DNs for inequality +*/ +bool operator!=(const X509_DN& dn1, const X509_DN& dn2) + { + return !(dn1 == dn2); + } + +/* +* Induce an arbitrary ordering on DNs +*/ +bool operator<(const X509_DN& dn1, const X509_DN& dn2) + { + auto attr1 = dn1.get_attributes(); + auto attr2 = dn2.get_attributes(); + + if(attr1.size() < attr2.size()) return true; + if(attr1.size() > attr2.size()) return false; + + for(auto p1 = attr1.begin(); p1 != attr1.end(); ++p1) + { + auto p2 = attr2.find(p1->first); + if(p2 == attr2.end()) return false; + if(p1->second > p2->second) return false; + if(p1->second < p2->second) return true; + } + return false; + } + +/* +* DER encode a DistinguishedName +*/ +void X509_DN::encode_into(DER_Encoder& der) const + { + der.start_cons(SEQUENCE); + + if(!m_dn_bits.empty()) + { + /* + If we decoded this from somewhere, encode it back exactly as + we received it + */ + der.raw_bytes(m_dn_bits); + } + else + { + for(const auto& dn : m_rdn) + { + der.start_cons(SET) + .start_cons(SEQUENCE) + .encode(dn.first) + .encode(dn.second) + .end_cons() + .end_cons(); + } + } + + der.end_cons(); + } + +/* +* Decode a BER encoded DistinguishedName +*/ +void X509_DN::decode_from(BER_Decoder& source) + { + std::vector bits; + + source.start_cons(SEQUENCE) + .raw_bytes(bits) + .end_cons(); + + BER_Decoder sequence(bits); + + while(sequence.more_items()) + { + BER_Decoder rdn = sequence.start_cons(SET); + + while(rdn.more_items()) + { + OID oid; + ASN1_String str; + + rdn.start_cons(SEQUENCE).decode(oid).decode(str).end_cons(); + + add_attribute(oid, str); + } + } + + m_dn_bits = bits; + } + +namespace { + +std::string to_short_form(const OID& oid) + { + const std::string long_id = OIDS::oid2str(oid); + + if(long_id.empty()) + return oid.to_string(); + + if(long_id == "X520.CommonName") + return "CN"; + + if(long_id == "X520.Country") + return "C"; + + if(long_id == "X520.Organization") + return "O"; + + if(long_id == "X520.OrganizationalUnit") + return "OU"; + + return long_id; + } + +} + +std::ostream& operator<<(std::ostream& out, const X509_DN& dn) + { + auto info = dn.dn_info(); + + for(size_t i = 0; i != info.size(); ++i) + { + out << to_short_form(info[i].first) << "=\""; + for(char c : info[i].second.value()) + { + if(c == '\\' || c == '\"') + { + out << "\\"; + } + out << c; + } + out << "\""; + + if(i + 1 < info.size()) + { + out << ","; + } + } + return out; + } + +std::istream& operator>>(std::istream& in, X509_DN& dn) + { + in >> std::noskipws; + do + { + std::string key; + std::string val; + char c; + + while(in.good()) + { + in >> c; + + if(std::isspace(c) && key.empty()) + continue; + else if(!std::isspace(c)) + { + key.push_back(c); + break; + } + else + break; + } + + while(in.good()) + { + in >> c; + + if(!std::isspace(c) && c != '=') + key.push_back(c); + else if(c == '=') + break; + else + throw Invalid_Argument("Ill-formed X.509 DN"); + } + + bool in_quotes = false; + while(in.good()) + { + in >> c; + + if(std::isspace(c)) + { + if(!in_quotes && !val.empty()) + break; + else if(in_quotes) + val.push_back(' '); + } + else if(c == '"') + in_quotes = !in_quotes; + else if(c == '\\') + { + if(in.good()) + in >> c; + val.push_back(c); + } + else if(c == ',' && !in_quotes) + break; + else + val.push_back(c); + } + + if(!key.empty() && !val.empty()) + dn.add_attribute(X509_DN::deref_info_field(key),val); + else + break; + } + while(in.good()); + return in; + } +} diff --git a/src/libs/3rdparty/botan/src/lib/x509/x509_dn.h b/src/libs/3rdparty/botan/src/lib/x509/x509_dn.h new file mode 100644 index 0000000000..9d8beb0bf1 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/x509/x509_dn.h @@ -0,0 +1,97 @@ +/* +* X.509 Distinguished Name +* (C) 1999-2010,2018 Jack Lloyd +* (C) 2017 Fabian Weissberg, Rohde & Schwarz Cybersecurity +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_X509_DN_H_ +#define BOTAN_X509_DN_H_ + +#include +#include +#include +#include +#include +#include + +namespace Botan { + +/** +* Distinguished Name +*/ +class BOTAN_PUBLIC_API(2,0) X509_DN final : public ASN1_Object + { + public: + X509_DN() = default; + + explicit X509_DN(const std::multimap& args) + { + for(auto i : args) + add_attribute(i.first, i.second); + } + + explicit X509_DN(const std::multimap& args) + { + for(auto i : args) + add_attribute(i.first, i.second); + } + + void encode_into(class DER_Encoder&) const override; + void decode_from(class BER_Decoder&) override; + + bool has_field(const OID& oid) const; + ASN1_String get_first_attribute(const OID& oid) const; + + /* + * Return the BER encoded data, if any + */ + const std::vector& get_bits() const { return m_dn_bits; } + + bool empty() const { return m_rdn.empty(); } + + const std::vector>& dn_info() const { return m_rdn; } + + std::multimap get_attributes() const; + std::multimap contents() const; + + bool has_field(const std::string& attr) const; + std::vector get_attribute(const std::string& attr) const; + std::string get_first_attribute(const std::string& attr) const; + + void add_attribute(const std::string& key, const std::string& val); + + void add_attribute(const OID& oid, const std::string& val) + { + add_attribute(oid, ASN1_String(val)); + } + + void add_attribute(const OID& oid, const ASN1_String& val); + + static std::string deref_info_field(const std::string& key); + + /** + * Lookup upper bounds in characters for the length of distinguished name fields + * as given in RFC 5280, Appendix A. + * + * @param oid the oid of the DN to lookup + * @return the upper bound, or zero if no ub is known to Botan + */ + static size_t lookup_ub(const OID& oid); + + private: + std::vector> m_rdn; + std::vector m_dn_bits; + }; + +bool BOTAN_PUBLIC_API(2,0) operator==(const X509_DN&, const X509_DN&); +bool BOTAN_PUBLIC_API(2,0) operator!=(const X509_DN&, const X509_DN&); +bool BOTAN_PUBLIC_API(2,0) operator<(const X509_DN&, const X509_DN&); + +BOTAN_PUBLIC_API(2,0) std::ostream& operator<<(std::ostream& out, const X509_DN& dn); +BOTAN_PUBLIC_API(2,0) std::istream& operator>>(std::istream& in, X509_DN& dn); + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/x509/x509_dn_ub.cpp b/src/libs/3rdparty/botan/src/lib/x509/x509_dn_ub.cpp new file mode 100644 index 0000000000..cf8714320e --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/x509/x509_dn_ub.cpp @@ -0,0 +1,58 @@ +/* +* DN_UB maps: Upper bounds on the length of DN strings +* +* This file was automatically generated by ./src/scripts/oids.py on 2017-12-23 +* +* All manual edits to this file will be lost. Edit the script +* then regenerate this source file. +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include + +namespace { +/** + * Upper bounds for the length of distinguished name fields as given in RFC 5280, Appendix A. + * Only OIDS recognized by botan are considered, so far. + * Maps OID string representations instead of human readable strings in order + * to avoid an additional lookup. + */ +static const std::map DN_UB = + { + { Botan::OID("2.5.4.10"), 64 }, // X520.Organization + { Botan::OID("2.5.4.11"), 64 }, // X520.OrganizationalUnit + { Botan::OID("2.5.4.12"), 64 }, // X520.Title + { Botan::OID("2.5.4.3"), 64 }, // X520.CommonName + { Botan::OID("2.5.4.4"), 40 }, // X520.Surname + { Botan::OID("2.5.4.42"), 32768 }, // X520.GivenName + { Botan::OID("2.5.4.43"), 32768 }, // X520.Initials + { Botan::OID("2.5.4.44"), 32768 }, // X520.GenerationalQualifier + { Botan::OID("2.5.4.46"), 64 }, // X520.DNQualifier + { Botan::OID("2.5.4.5"), 64 }, // X520.SerialNumber + { Botan::OID("2.5.4.6"), 3 }, // X520.Country + { Botan::OID("2.5.4.65"), 128 }, // X520.Pseudonym + { Botan::OID("2.5.4.7"), 128 }, // X520.Locality + { Botan::OID("2.5.4.8"), 128 } // X520.State + }; +} + +namespace Botan { + +//static +size_t X509_DN::lookup_ub(const OID& oid) + { + auto ub_entry = DN_UB.find(oid); + if(ub_entry != DN_UB.end()) + { + return ub_entry->second; + } + else + { + return 0; + } + } +} + diff --git a/src/libs/3rdparty/botan/src/lib/x509/x509_ext.cpp b/src/libs/3rdparty/botan/src/lib/x509/x509_ext.cpp new file mode 100644 index 0000000000..122be2885d --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/x509/x509_ext.cpp @@ -0,0 +1,1000 @@ +/* +* X.509 Certificate Extensions +* (C) 1999-2010,2012 Jack Lloyd +* (C) 2016 René Korthaus, Rohde & Schwarz Cybersecurity +* (C) 2017 Fabian Weissberg, Rohde & Schwarz Cybersecurity +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Botan { + +/* +* Create a Certificate_Extension object of some kind to handle +*/ +std::unique_ptr +Extensions::create_extn_obj(const OID& oid, + bool critical, + const std::vector& body) + { + const std::string oid_str = oid.as_string(); + + std::unique_ptr extn; + + if(oid == Cert_Extension::Subject_Key_ID::static_oid()) + { + extn.reset(new Cert_Extension::Subject_Key_ID); + } + else if(oid == Cert_Extension::Key_Usage::static_oid()) + { + extn.reset(new Cert_Extension::Key_Usage); + } + else if(oid == Cert_Extension::Subject_Alternative_Name::static_oid()) + { + extn.reset(new Cert_Extension::Subject_Alternative_Name); + } + else if(oid == Cert_Extension::Issuer_Alternative_Name::static_oid()) + { + extn.reset(new Cert_Extension::Issuer_Alternative_Name); + } + else if(oid == Cert_Extension::Basic_Constraints::static_oid()) + { + extn.reset(new Cert_Extension::Basic_Constraints); + } + else if(oid == Cert_Extension::CRL_Number::static_oid()) + { + extn.reset(new Cert_Extension::CRL_Number); + } + else if(oid == Cert_Extension::CRL_ReasonCode::static_oid()) + { + extn.reset(new Cert_Extension::CRL_ReasonCode); + } + else if(oid == Cert_Extension::Authority_Key_ID::static_oid()) + { + extn.reset(new Cert_Extension::Authority_Key_ID); + } + else if(oid == Cert_Extension::Name_Constraints::static_oid()) + { + extn.reset(new Cert_Extension::Name_Constraints); + } + else if(oid == Cert_Extension::CRL_Distribution_Points::static_oid()) + { + extn.reset(new Cert_Extension::CRL_Distribution_Points); + } + else if(oid == Cert_Extension::CRL_Issuing_Distribution_Point::static_oid()) + { + extn.reset(new Cert_Extension::CRL_Issuing_Distribution_Point); + } + else if(oid == Cert_Extension::Certificate_Policies::static_oid()) + { + extn.reset(new Cert_Extension::Certificate_Policies); + } + else if(oid == Cert_Extension::Extended_Key_Usage::static_oid()) + { + extn.reset(new Cert_Extension::Extended_Key_Usage); + } + else if(oid == Cert_Extension::Authority_Information_Access::static_oid()) + { + extn.reset(new Cert_Extension::Authority_Information_Access); + } + else + { + // some other unknown extension type + extn.reset(new Cert_Extension::Unknown_Extension(oid, critical)); + } + + try + { + extn->decode_inner(body); + } + catch(Decoding_Error& e) + { + throw Decoding_Error("Decoding X.509 extension " + oid.as_string() + " failed", e.what()); + } + return extn; + } + +/* +* Validate the extension (the default implementation is a NOP) +*/ +void Certificate_Extension::validate(const X509_Certificate&, const X509_Certificate&, + const std::vector>&, + std::vector>&, + size_t) + { + } + +/* +* Add a new cert +*/ +void Extensions::add(Certificate_Extension* extn, bool critical) + { + // sanity check: we don't want to have the same extension more than once + if(m_extension_info.count(extn->oid_of()) > 0) + throw Invalid_Argument(extn->oid_name() + " extension already present in Extensions::add"); + + const OID oid = extn->oid_of(); + Extensions_Info info(critical, extn); + m_extension_oids.push_back(oid); + m_extension_info.emplace(oid, info); + } + +bool Extensions::add_new(Certificate_Extension* extn, bool critical) + { + if(m_extension_info.count(extn->oid_of()) > 0) + { + delete extn; + return false; // already exists + } + + const OID oid = extn->oid_of(); + Extensions_Info info(critical, extn); + m_extension_oids.push_back(oid); + m_extension_info.emplace(oid, info); + return true; + } + +void Extensions::replace(Certificate_Extension* extn, bool critical) + { + // Remove it if it existed + m_extension_info.erase(extn->oid_of()); + + const OID oid = extn->oid_of(); + Extensions_Info info(critical, extn); + m_extension_oids.push_back(oid); + m_extension_info.emplace(oid, info); + } + +bool Extensions::extension_set(const OID& oid) const + { + return (m_extension_info.find(oid) != m_extension_info.end()); + } + +bool Extensions::critical_extension_set(const OID& oid) const + { + auto i = m_extension_info.find(oid); + if(i != m_extension_info.end()) + return i->second.is_critical(); + return false; + } + +const Certificate_Extension* Extensions::get_extension_object(const OID& oid) const + { + auto extn = m_extension_info.find(oid); + if(extn == m_extension_info.end()) + return nullptr; + + return &extn->second.obj(); + } + +std::unique_ptr Extensions::get(const OID& oid) const + { + if(const Certificate_Extension* ext = this->get_extension_object(oid)) + { + return std::unique_ptr(ext->copy()); + } + return nullptr; + } + +std::vector, bool>> Extensions::extensions() const + { + std::vector, bool>> exts; + for(auto&& ext : m_extension_info) + { + exts.push_back( + std::make_pair( + std::unique_ptr(ext.second.obj().copy()), + ext.second.is_critical()) + ); + } + return exts; + } + +std::map, bool>> Extensions::extensions_raw() const + { + std::map, bool>> out; + for(auto&& ext : m_extension_info) + { + out.emplace(ext.first, + std::make_pair(ext.second.bits(), + ext.second.is_critical())); + } + return out; + } + +/* +* Encode an Extensions list +*/ +void Extensions::encode_into(DER_Encoder& to_object) const + { + for(auto ext_info : m_extension_info) + { + const OID& oid = ext_info.first; + const bool should_encode = ext_info.second.obj().should_encode(); + + if(should_encode) + { + const bool is_critical = ext_info.second.is_critical(); + const std::vector& ext_value = ext_info.second.bits(); + + to_object.start_cons(SEQUENCE) + .encode(oid) + .encode_optional(is_critical, false) + .encode(ext_value, OCTET_STRING) + .end_cons(); + } + } + } + +/* +* Decode a list of Extensions +*/ +void Extensions::decode_from(BER_Decoder& from_source) + { + m_extension_oids.clear(); + m_extension_info.clear(); + + BER_Decoder sequence = from_source.start_cons(SEQUENCE); + + while(sequence.more_items()) + { + OID oid; + bool critical; + std::vector bits; + + sequence.start_cons(SEQUENCE) + .decode(oid) + .decode_optional(critical, BOOLEAN, UNIVERSAL, false) + .decode(bits, OCTET_STRING) + .end_cons(); + + std::unique_ptr obj = create_extn_obj(oid, critical, bits); + Extensions_Info info(critical, bits, obj.release()); + + m_extension_oids.push_back(oid); + m_extension_info.emplace(oid, info); + } + sequence.verify_end(); + } + +/* +* Write the extensions to an info store +*/ +void Extensions::contents_to(Data_Store& subject_info, + Data_Store& issuer_info) const + { + for(auto&& m_extn_info : m_extension_info) + { + m_extn_info.second.obj().contents_to(subject_info, issuer_info); + subject_info.add(m_extn_info.second.obj().oid_name() + ".is_critical", + m_extn_info.second.is_critical()); + } + } + +namespace Cert_Extension { + +/* +* Checked accessor for the path_limit member +*/ +size_t Basic_Constraints::get_path_limit() const + { + if(!m_is_ca) + throw Invalid_State("Basic_Constraints::get_path_limit: Not a CA"); + return m_path_limit; + } + +/* +* Encode the extension +*/ +std::vector Basic_Constraints::encode_inner() const + { + std::vector output; + DER_Encoder(output) + .start_cons(SEQUENCE) + .encode_if(m_is_ca, + DER_Encoder() + .encode(m_is_ca) + .encode_optional(m_path_limit, NO_CERT_PATH_LIMIT) + ) + .end_cons(); + return output; + } + +/* +* Decode the extension +*/ +void Basic_Constraints::decode_inner(const std::vector& in) + { + BER_Decoder(in) + .start_cons(SEQUENCE) + .decode_optional(m_is_ca, BOOLEAN, UNIVERSAL, false) + .decode_optional(m_path_limit, INTEGER, UNIVERSAL, NO_CERT_PATH_LIMIT) + .end_cons(); + + if(m_is_ca == false) + m_path_limit = 0; + } + +/* +* Return a textual representation +*/ +void Basic_Constraints::contents_to(Data_Store& subject, Data_Store&) const + { + subject.add("X509v3.BasicConstraints.is_ca", (m_is_ca ? 1 : 0)); + subject.add("X509v3.BasicConstraints.path_constraint", static_cast(m_path_limit)); + } + +/* +* Encode the extension +*/ +std::vector Key_Usage::encode_inner() const + { + if(m_constraints == NO_CONSTRAINTS) + throw Encoding_Error("Cannot encode zero usage constraints"); + + const size_t unused_bits = low_bit(m_constraints) - 1; + + std::vector der; + der.push_back(BIT_STRING); + der.push_back(2 + ((unused_bits < 8) ? 1 : 0)); + der.push_back(unused_bits % 8); + der.push_back((m_constraints >> 8) & 0xFF); + if(m_constraints & 0xFF) + der.push_back(m_constraints & 0xFF); + + return der; + } + +/* +* Decode the extension +*/ +void Key_Usage::decode_inner(const std::vector& in) + { + BER_Decoder ber(in); + + BER_Object obj = ber.get_next_object(); + + obj.assert_is_a(BIT_STRING, UNIVERSAL, "usage constraint"); + + if(obj.length() != 2 && obj.length() != 3) + throw BER_Decoding_Error("Bad size for BITSTRING in usage constraint"); + + uint16_t usage = 0; + + const uint8_t* bits = obj.bits(); + + if(bits[0] >= 8) + throw BER_Decoding_Error("Invalid unused bits in usage constraint"); + + const uint8_t mask = static_cast(0xFF << bits[0]); + + if(obj.length() == 2) + { + usage = make_uint16(bits[1] & mask, 0); + } + else if(obj.length() == 3) + { + usage = make_uint16(bits[1], bits[2] & mask); + } + + m_constraints = Key_Constraints(usage); + } + +/* +* Return a textual representation +*/ +void Key_Usage::contents_to(Data_Store& subject, Data_Store&) const + { + subject.add("X509v3.KeyUsage", m_constraints); + } + +/* +* Encode the extension +*/ +std::vector Subject_Key_ID::encode_inner() const + { + std::vector output; + DER_Encoder(output).encode(m_key_id, OCTET_STRING); + return output; + } + +/* +* Decode the extension +*/ +void Subject_Key_ID::decode_inner(const std::vector& in) + { + BER_Decoder(in).decode(m_key_id, OCTET_STRING).verify_end(); + } + +/* +* Return a textual representation +*/ +void Subject_Key_ID::contents_to(Data_Store& subject, Data_Store&) const + { + subject.add("X509v3.SubjectKeyIdentifier", m_key_id); + } + +/* +* Subject_Key_ID Constructor +*/ +Subject_Key_ID::Subject_Key_ID(const std::vector& pub_key, const std::string& hash_name) + { + std::unique_ptr hash(HashFunction::create_or_throw(hash_name)); + + m_key_id.resize(hash->output_length()); + + hash->update(pub_key); + hash->final(m_key_id.data()); + + // Truncate longer hashes, 192 bits here seems plenty + const size_t max_skid_len = (192 / 8); + if(m_key_id.size() > max_skid_len) + m_key_id.resize(max_skid_len); + } + +/* +* Encode the extension +*/ +std::vector Authority_Key_ID::encode_inner() const + { + std::vector output; + DER_Encoder(output) + .start_cons(SEQUENCE) + .encode(m_key_id, OCTET_STRING, ASN1_Tag(0), CONTEXT_SPECIFIC) + .end_cons(); + return output; + } + +/* +* Decode the extension +*/ +void Authority_Key_ID::decode_inner(const std::vector& in) + { + BER_Decoder(in) + .start_cons(SEQUENCE) + .decode_optional_string(m_key_id, OCTET_STRING, 0); + } + +/* +* Return a textual representation +*/ +void Authority_Key_ID::contents_to(Data_Store&, Data_Store& issuer) const + { + if(m_key_id.size()) + issuer.add("X509v3.AuthorityKeyIdentifier", m_key_id); + } + +/* +* Encode the extension +*/ +std::vector Subject_Alternative_Name::encode_inner() const + { + std::vector output; + DER_Encoder(output).encode(m_alt_name); + return output; + } + +/* +* Encode the extension +*/ +std::vector Issuer_Alternative_Name::encode_inner() const + { + std::vector output; + DER_Encoder(output).encode(m_alt_name); + return output; + } + +/* +* Decode the extension +*/ +void Subject_Alternative_Name::decode_inner(const std::vector& in) + { + BER_Decoder(in).decode(m_alt_name); + } + +/* +* Decode the extension +*/ +void Issuer_Alternative_Name::decode_inner(const std::vector& in) + { + BER_Decoder(in).decode(m_alt_name); + } + +/* +* Return a textual representation +*/ +void Subject_Alternative_Name::contents_to(Data_Store& subject_info, + Data_Store&) const + { + subject_info.add(get_alt_name().contents()); + } + +/* +* Return a textual representation +*/ +void Issuer_Alternative_Name::contents_to(Data_Store&, Data_Store& issuer_info) const + { + issuer_info.add(get_alt_name().contents()); + } + +/* +* Encode the extension +*/ +std::vector Extended_Key_Usage::encode_inner() const + { + std::vector output; + DER_Encoder(output) + .start_cons(SEQUENCE) + .encode_list(m_oids) + .end_cons(); + return output; + } + +/* +* Decode the extension +*/ +void Extended_Key_Usage::decode_inner(const std::vector& in) + { + BER_Decoder(in).decode_list(m_oids); + } + +/* +* Return a textual representation +*/ +void Extended_Key_Usage::contents_to(Data_Store& subject, Data_Store&) const + { + for(size_t i = 0; i != m_oids.size(); ++i) + subject.add("X509v3.ExtendedKeyUsage", m_oids[i].as_string()); + } + +/* +* Encode the extension +*/ +std::vector Name_Constraints::encode_inner() const + { + throw Not_Implemented("Name_Constraints encoding"); + } + + +/* +* Decode the extension +*/ +void Name_Constraints::decode_inner(const std::vector& in) + { + std::vector permit, exclude; + BER_Decoder ber(in); + BER_Decoder ext = ber.start_cons(SEQUENCE); + BER_Object per = ext.get_next_object(); + + ext.push_back(per); + if(per.is_a(0, ASN1_Tag(CONSTRUCTED | CONTEXT_SPECIFIC))) + { + ext.decode_list(permit,ASN1_Tag(0),ASN1_Tag(CONSTRUCTED | CONTEXT_SPECIFIC)); + if(permit.empty()) + throw Encoding_Error("Empty Name Contraint list"); + } + + BER_Object exc = ext.get_next_object(); + ext.push_back(exc); + if(per.is_a(1, ASN1_Tag(CONSTRUCTED | CONTEXT_SPECIFIC))) + { + ext.decode_list(exclude,ASN1_Tag(1),ASN1_Tag(CONSTRUCTED | CONTEXT_SPECIFIC)); + if(exclude.empty()) + throw Encoding_Error("Empty Name Contraint list"); + } + + ext.end_cons(); + + if(permit.empty() && exclude.empty()) + throw Encoding_Error("Empty Name Contraint extension"); + + m_name_constraints = NameConstraints(std::move(permit),std::move(exclude)); + } + +/* +* Return a textual representation +*/ +void Name_Constraints::contents_to(Data_Store& subject, Data_Store&) const + { + std::stringstream ss; + + for(const GeneralSubtree& gs: m_name_constraints.permitted()) + { + ss << gs; + subject.add("X509v3.NameConstraints.permitted", ss.str()); + ss.str(std::string()); + } + for(const GeneralSubtree& gs: m_name_constraints.excluded()) + { + ss << gs; + subject.add("X509v3.NameConstraints.excluded", ss.str()); + ss.str(std::string()); + } + } + +void Name_Constraints::validate(const X509_Certificate& subject, const X509_Certificate& issuer, + const std::vector>& cert_path, + std::vector>& cert_status, + size_t pos) + { + if(!m_name_constraints.permitted().empty() || !m_name_constraints.excluded().empty()) + { + if(!subject.is_CA_cert() || !subject.is_critical("X509v3.NameConstraints")) + cert_status.at(pos).insert(Certificate_Status_Code::NAME_CONSTRAINT_ERROR); + + const bool issuer_name_constraint_critical = + issuer.is_critical("X509v3.NameConstraints"); + + const bool at_self_signed_root = (pos == cert_path.size() - 1); + + // Check that all subordinate certs pass the name constraint + for(size_t j = 0; j <= pos; ++j) + { + if(pos == j && at_self_signed_root) + continue; + + bool permitted = m_name_constraints.permitted().empty(); + bool failed = false; + + for(auto c: m_name_constraints.permitted()) + { + switch(c.base().matches(*cert_path.at(j))) + { + case GeneralName::MatchResult::NotFound: + case GeneralName::MatchResult::All: + permitted = true; + break; + case GeneralName::MatchResult::UnknownType: + failed = issuer_name_constraint_critical; + permitted = true; + break; + default: + break; + } + } + + for(auto c: m_name_constraints.excluded()) + { + switch(c.base().matches(*cert_path.at(j))) + { + case GeneralName::MatchResult::All: + case GeneralName::MatchResult::Some: + failed = true; + break; + case GeneralName::MatchResult::UnknownType: + failed = issuer_name_constraint_critical; + break; + default: + break; + } + } + + if(failed || !permitted) + { + cert_status.at(j).insert(Certificate_Status_Code::NAME_CONSTRAINT_ERROR); + } + } + } + } + +namespace { + +/* +* A policy specifier +*/ +class Policy_Information final : public ASN1_Object + { + public: + Policy_Information() = default; + explicit Policy_Information(const OID& oid) : m_oid(oid) {} + + const OID& oid() const { return m_oid; } + + void encode_into(DER_Encoder& codec) const override + { + codec.start_cons(SEQUENCE) + .encode(m_oid) + .end_cons(); + } + + void decode_from(BER_Decoder& codec) override + { + codec.start_cons(SEQUENCE) + .decode(m_oid) + .discard_remaining() + .end_cons(); + } + + private: + OID m_oid; + }; + +} + +/* +* Encode the extension +*/ +std::vector Certificate_Policies::encode_inner() const + { + std::vector policies; + + for(size_t i = 0; i != m_oids.size(); ++i) + policies.push_back(Policy_Information(m_oids[i])); + + std::vector output; + DER_Encoder(output) + .start_cons(SEQUENCE) + .encode_list(policies) + .end_cons(); + return output; + } + +/* +* Decode the extension +*/ +void Certificate_Policies::decode_inner(const std::vector& in) + { + std::vector policies; + + BER_Decoder(in).decode_list(policies); + m_oids.clear(); + for(size_t i = 0; i != policies.size(); ++i) + m_oids.push_back(policies[i].oid()); + } + +/* +* Return a textual representation +*/ +void Certificate_Policies::contents_to(Data_Store& info, Data_Store&) const + { + for(size_t i = 0; i != m_oids.size(); ++i) + info.add("X509v3.CertificatePolicies", m_oids[i].as_string()); + } + +void Certificate_Policies::validate( + const X509_Certificate& /*subject*/, + const X509_Certificate& /*issuer*/, + const std::vector>& /*cert_path*/, + std::vector>& cert_status, + size_t pos) + { + std::set oid_set(m_oids.begin(), m_oids.end()); + if(oid_set.size() != m_oids.size()) + { + cert_status.at(pos).insert(Certificate_Status_Code::DUPLICATE_CERT_POLICY); + } + } + +std::vector Authority_Information_Access::encode_inner() const + { + ASN1_String url(m_ocsp_responder, IA5_STRING); + + std::vector output; + DER_Encoder(output) + .start_cons(SEQUENCE) + .start_cons(SEQUENCE) + .encode(OIDS::lookup("PKIX.OCSP")) + .add_object(ASN1_Tag(6), CONTEXT_SPECIFIC, url.value()) + .end_cons() + .end_cons(); + return output; + } + +void Authority_Information_Access::decode_inner(const std::vector& in) + { + BER_Decoder ber = BER_Decoder(in).start_cons(SEQUENCE); + + while(ber.more_items()) + { + OID oid; + + BER_Decoder info = ber.start_cons(SEQUENCE); + + info.decode(oid); + + if(oid == OIDS::lookup("PKIX.OCSP")) + { + BER_Object name = info.get_next_object(); + + if(name.is_a(6, CONTEXT_SPECIFIC)) + { + m_ocsp_responder = ASN1::to_string(name); + } + + } + if(oid == OIDS::lookup("PKIX.CertificateAuthorityIssuers")) + { + BER_Object name = info.get_next_object(); + + if(name.is_a(6, CONTEXT_SPECIFIC)) + { + m_ca_issuers.push_back(ASN1::to_string(name)); + } + } + } + } + +void Authority_Information_Access::contents_to(Data_Store& subject, Data_Store&) const + { + if(!m_ocsp_responder.empty()) + subject.add("OCSP.responder", m_ocsp_responder); + for(const std::string& ca_issuer : m_ca_issuers) + subject.add("PKIX.CertificateAuthorityIssuers", ca_issuer); + } + +/* +* Checked accessor for the crl_number member +*/ +size_t CRL_Number::get_crl_number() const + { + if(!m_has_value) + throw Invalid_State("CRL_Number::get_crl_number: Not set"); + return m_crl_number; + } + +/* +* Copy a CRL_Number extension +*/ +CRL_Number* CRL_Number::copy() const + { + if(!m_has_value) + throw Invalid_State("CRL_Number::copy: Not set"); + return new CRL_Number(m_crl_number); + } + +/* +* Encode the extension +*/ +std::vector CRL_Number::encode_inner() const + { + std::vector output; + DER_Encoder(output).encode(m_crl_number); + return output; + } + +/* +* Decode the extension +*/ +void CRL_Number::decode_inner(const std::vector& in) + { + BER_Decoder(in).decode(m_crl_number); + m_has_value = true; + } + +/* +* Return a textual representation +*/ +void CRL_Number::contents_to(Data_Store& info, Data_Store&) const + { + info.add("X509v3.CRLNumber", static_cast(m_crl_number)); + } + +/* +* Encode the extension +*/ +std::vector CRL_ReasonCode::encode_inner() const + { + std::vector output; + DER_Encoder(output).encode(static_cast(m_reason), ENUMERATED, UNIVERSAL); + return output; + } + +/* +* Decode the extension +*/ +void CRL_ReasonCode::decode_inner(const std::vector& in) + { + size_t reason_code = 0; + BER_Decoder(in).decode(reason_code, ENUMERATED, UNIVERSAL); + m_reason = static_cast(reason_code); + } + +/* +* Return a textual representation +*/ +void CRL_ReasonCode::contents_to(Data_Store& info, Data_Store&) const + { + info.add("X509v3.CRLReasonCode", m_reason); + } + +std::vector CRL_Distribution_Points::encode_inner() const + { + throw Not_Implemented("CRL_Distribution_Points encoding"); + } + +void CRL_Distribution_Points::decode_inner(const std::vector& buf) + { + BER_Decoder(buf) + .decode_list(m_distribution_points) + .verify_end(); + + std::stringstream ss; + + for(size_t i = 0; i != m_distribution_points.size(); ++i) + { + auto contents = m_distribution_points[i].point().contents(); + + for(const auto& pair : contents) + { + ss << pair.first << ": " << pair.second << " "; + } + } + + m_crl_distribution_urls.push_back(ss.str()); + } + +void CRL_Distribution_Points::contents_to(Data_Store& subject, Data_Store&) const + { + for(const std::string& crl_url : m_crl_distribution_urls) + subject.add("CRL.DistributionPoint", crl_url); + } + +void CRL_Distribution_Points::Distribution_Point::encode_into(class DER_Encoder&) const + { + throw Not_Implemented("CRL_Distribution_Points encoding"); + } + +void CRL_Distribution_Points::Distribution_Point::decode_from(class BER_Decoder& ber) + { + ber.start_cons(SEQUENCE) + .start_cons(ASN1_Tag(0), CONTEXT_SPECIFIC) + .decode_optional_implicit(m_point, ASN1_Tag(0), + ASN1_Tag(CONTEXT_SPECIFIC | CONSTRUCTED), + SEQUENCE, CONSTRUCTED) + .end_cons().end_cons(); + } + +std::vector CRL_Issuing_Distribution_Point::encode_inner() const + { + throw Not_Implemented("CRL_Issuing_Distribution_Point encoding"); + } + +void CRL_Issuing_Distribution_Point::decode_inner(const std::vector& buf) + { + BER_Decoder(buf).decode(m_distribution_point).verify_end(); + } + +void CRL_Issuing_Distribution_Point::contents_to(Data_Store& info, Data_Store&) const + { + auto contents = m_distribution_point.point().contents(); + std::stringstream ss; + + for(const auto& pair : contents) + { + ss << pair.first << ": " << pair.second << " "; + } + + info.add("X509v3.CRLIssuingDistributionPoint", ss.str()); + } + +std::vector Unknown_Extension::encode_inner() const + { + return m_bytes; + } + +void Unknown_Extension::decode_inner(const std::vector& bytes) + { + // Just treat as an opaque blob at this level + m_bytes = bytes; + } + +void Unknown_Extension::contents_to(Data_Store&, Data_Store&) const + { + // No information store + } + +} + +} diff --git a/src/libs/3rdparty/botan/src/lib/x509/x509_ext.h b/src/libs/3rdparty/botan/src/lib/x509/x509_ext.h new file mode 100644 index 0000000000..6e71fb8797 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/x509/x509_ext.h @@ -0,0 +1,790 @@ +/* +* X.509 Certificate Extensions +* (C) 1999-2007,2012 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_X509_EXTENSIONS_H_ +#define BOTAN_X509_EXTENSIONS_H_ + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Botan { + +class Data_Store; +class X509_Certificate; + +/** +* X.509 Certificate Extension +*/ +class BOTAN_PUBLIC_API(2,0) Certificate_Extension + { + public: + /** + * @return OID representing this extension + */ + virtual OID oid_of() const = 0; + + /* + * @return specific OID name + * If possible OIDS table should match oid_name to OIDS, ie + * OIDS::lookup(ext->oid_name()) == ext->oid_of() + * Should return empty string if OID is not known + */ + virtual std::string oid_name() const = 0; + + /** + * Make a copy of this extension + * @return copy of this + */ + virtual Certificate_Extension* copy() const = 0; + + /* + * Add the contents of this extension into the information + * for the subject and/or issuer, as necessary. + * @param subject the subject info + * @param issuer the issuer info + */ + virtual void contents_to(Data_Store& subject, + Data_Store& issuer) const = 0; + + /* + * Callback visited during path validation. + * + * An extension can implement this callback to inspect + * the path during path validation. + * + * If an error occurs during validation of this extension, + * an appropriate status code shall be added to cert_status. + * + * @param subject Subject certificate that contains this extension + * @param issuer Issuer certificate + * @param status Certificate validation status codes for subject certificate + * @param cert_path Certificate path which is currently validated + * @param pos Position of subject certificate in cert_path + */ + virtual void validate(const X509_Certificate& subject, const X509_Certificate& issuer, + const std::vector>& cert_path, + std::vector>& cert_status, + size_t pos); + + virtual ~Certificate_Extension() = default; + protected: + friend class Extensions; + virtual bool should_encode() const { return true; } + virtual std::vector encode_inner() const = 0; + virtual void decode_inner(const std::vector&) = 0; + }; + +/** +* X.509 Certificate Extension List +*/ +class BOTAN_PUBLIC_API(2,0) Extensions final : public ASN1_Object + { + public: + /** + * Look up an object in the extensions, based on OID Returns + * nullptr if not set, if the extension was either absent or not + * handled. The pointer returned is owned by the Extensions + * object. + * This would be better with an optional return value + */ + const Certificate_Extension* get_extension_object(const OID& oid) const; + + template + const T* get_extension_object_as(const OID& oid = T::static_oid()) const + { + if(const Certificate_Extension* extn = get_extension_object(oid)) + { + if(const T* extn_as_T = dynamic_cast(extn)) + { + return extn_as_T; + } + else + { + throw Exception("Exception::get_extension_object_as dynamic_cast failed"); + } + } + + return nullptr; + } + + /** + * Return the set of extensions in the order they appeared in the certificate + * (or as they were added, if constructed) + */ + const std::vector& get_extension_oids() const + { + return m_extension_oids; + } + + /** + * Return true if an extension was set + */ + bool extension_set(const OID& oid) const; + + /** + * Return true if an extesion was set and marked critical + */ + bool critical_extension_set(const OID& oid) const; + + /** + * Return the raw bytes of the extension + * Will throw if OID was not set as an extension. + */ + std::vector get_extension_bits(const OID& oid) const; + + void encode_into(class DER_Encoder&) const override; + void decode_from(class BER_Decoder&) override; + void contents_to(Data_Store&, Data_Store&) const; + + /** + * Adds a new extension to the list. + * @param extn pointer to the certificate extension (Extensions takes ownership) + * @param critical whether this extension should be marked as critical + * @throw Invalid_Argument if the extension is already present in the list + */ + void add(Certificate_Extension* extn, bool critical = false); + + /** + * Adds a new extension to the list unless it already exists. If the extension + * already exists within the Extensions object, the extn pointer will be deleted. + * + * @param extn pointer to the certificate extension (Extensions takes ownership) + * @param critical whether this extension should be marked as critical + * @return true if the object was added false if the extension was already used + */ + bool add_new(Certificate_Extension* extn, bool critical = false); + + /** + * Adds an extension to the list or replaces it. + * @param extn the certificate extension + * @param critical whether this extension should be marked as critical + */ + void replace(Certificate_Extension* extn, bool critical = false); + + /** + * Searches for an extension by OID and returns the result. + * Only the known extensions types declared in this header + * are searched for by this function. + * @return Copy of extension with oid, nullptr if not found. + * Can avoid creating a copy by using get_extension_object function + */ + std::unique_ptr get(const OID& oid) const; + + /** + * Searches for an extension by OID and returns the result decoding + * it to some arbitrary extension type chosen by the application. + * + * Only the unknown extensions, that is, extensions types that + * are not declared in this header, are searched for by this + * function. + * + * @return Pointer to new extension with oid, nullptr if not found. + */ + template + std::unique_ptr get_raw(const OID& oid) const + { + auto extn_info = m_extension_info.find(oid); + + if(extn_info != m_extension_info.end()) + { + // Unknown_Extension oid_name is empty + if(extn_info->second.obj().oid_name() == "") + { + std::unique_ptr ext(new T); + ext->decode_inner(extn_info->second.bits()); + return std::move(ext); + } + } + return nullptr; + } + + /** + * Returns a copy of the list of extensions together with the corresponding + * criticality flag. All extensions are encoded as some object, falling back + * to Unknown_Extension class which simply allows reading the bytes as well + * as the criticality flag. + */ + std::vector, bool>> extensions() const; + + /** + * Returns the list of extensions as raw, encoded bytes + * together with the corresponding criticality flag. + * Contains all extensions, including any extensions encoded as Unknown_Extension + */ + std::map, bool>> extensions_raw() const; + + Extensions() {} + + Extensions(const Extensions&) = default; + Extensions& operator=(const Extensions&) = default; + +#if !defined(BOTAN_BUILD_COMPILER_IS_MSVC_2013) + Extensions(Extensions&&) = default; + Extensions& operator=(Extensions&&) = default; +#endif + + private: + static std::unique_ptr + create_extn_obj(const OID& oid, + bool critical, + const std::vector& body); + + class Extensions_Info + { + public: + Extensions_Info(bool critical, + Certificate_Extension* ext) : + m_obj(ext), + m_bits(m_obj->encode_inner()), + m_critical(critical) + { + } + + Extensions_Info(bool critical, + const std::vector& encoding, + Certificate_Extension* ext) : + m_obj(ext), + m_bits(encoding), + m_critical(critical) + { + } + + bool is_critical() const { return m_critical; } + const std::vector& bits() const { return m_bits; } + const Certificate_Extension& obj() const + { + BOTAN_ASSERT_NONNULL(m_obj.get()); + return *m_obj.get(); + } + + private: + std::shared_ptr m_obj; + std::vector m_bits; + bool m_critical = false; + }; + + std::vector m_extension_oids; + std::map m_extension_info; + }; + +namespace Cert_Extension { + +static const size_t NO_CERT_PATH_LIMIT = 0xFFFFFFF0; + +/** +* Basic Constraints Extension +*/ +class BOTAN_PUBLIC_API(2,0) Basic_Constraints final : public Certificate_Extension + { + public: + Basic_Constraints* copy() const override + { return new Basic_Constraints(m_is_ca, m_path_limit); } + + Basic_Constraints(bool ca = false, size_t limit = 0) : + m_is_ca(ca), m_path_limit(limit) {} + + bool get_is_ca() const { return m_is_ca; } + size_t get_path_limit() const; + + static OID static_oid() { return OID("2.5.29.19"); } + OID oid_of() const override { return static_oid(); } + + private: + std::string oid_name() const override + { return "X509v3.BasicConstraints"; } + + std::vector encode_inner() const override; + void decode_inner(const std::vector&) override; + void contents_to(Data_Store&, Data_Store&) const override; + + bool m_is_ca; + size_t m_path_limit; + }; + +/** +* Key Usage Constraints Extension +*/ +class BOTAN_PUBLIC_API(2,0) Key_Usage final : public Certificate_Extension + { + public: + Key_Usage* copy() const override { return new Key_Usage(m_constraints); } + + explicit Key_Usage(Key_Constraints c = NO_CONSTRAINTS) : m_constraints(c) {} + + Key_Constraints get_constraints() const { return m_constraints; } + + static OID static_oid() { return OID("2.5.29.15"); } + OID oid_of() const override { return static_oid(); } + + private: + std::string oid_name() const override { return "X509v3.KeyUsage"; } + + bool should_encode() const override + { return (m_constraints != NO_CONSTRAINTS); } + std::vector encode_inner() const override; + void decode_inner(const std::vector&) override; + void contents_to(Data_Store&, Data_Store&) const override; + + Key_Constraints m_constraints; + }; + +/** +* Subject Key Identifier Extension +*/ +class BOTAN_PUBLIC_API(2,0) Subject_Key_ID final : public Certificate_Extension + { + public: + Subject_Key_ID() = default; + + explicit Subject_Key_ID(const std::vector& k) : m_key_id(k) {} + + Subject_Key_ID(const std::vector& public_key, + const std::string& hash_fn); + + Subject_Key_ID* copy() const override + { return new Subject_Key_ID(m_key_id); } + + const std::vector& get_key_id() const { return m_key_id; } + + static OID static_oid() { return OID("2.5.29.14"); } + OID oid_of() const override { return static_oid(); } + + private: + + std::string oid_name() const override + { return "X509v3.SubjectKeyIdentifier"; } + + bool should_encode() const override { return (m_key_id.size() > 0); } + std::vector encode_inner() const override; + void decode_inner(const std::vector&) override; + void contents_to(Data_Store&, Data_Store&) const override; + + std::vector m_key_id; + }; + +/** +* Authority Key Identifier Extension +*/ +class BOTAN_PUBLIC_API(2,0) Authority_Key_ID final : public Certificate_Extension + { + public: + Authority_Key_ID* copy() const override + { return new Authority_Key_ID(m_key_id); } + + Authority_Key_ID() = default; + explicit Authority_Key_ID(const std::vector& k) : m_key_id(k) {} + + const std::vector& get_key_id() const { return m_key_id; } + + static OID static_oid() { return OID("2.5.29.35"); } + OID oid_of() const override { return static_oid(); } + + private: + std::string oid_name() const override + { return "X509v3.AuthorityKeyIdentifier"; } + + bool should_encode() const override { return (m_key_id.size() > 0); } + std::vector encode_inner() const override; + void decode_inner(const std::vector&) override; + void contents_to(Data_Store&, Data_Store&) const override; + + std::vector m_key_id; + }; + +/** +* Subject Alternative Name Extension +*/ +class BOTAN_PUBLIC_API(2,4) Subject_Alternative_Name final : public Certificate_Extension + { + public: + const AlternativeName& get_alt_name() const { return m_alt_name; } + + static OID static_oid() { return OID("2.5.29.17"); } + OID oid_of() const override { return static_oid(); } + + Subject_Alternative_Name* copy() const override + { return new Subject_Alternative_Name(get_alt_name()); } + + explicit Subject_Alternative_Name(const AlternativeName& name = AlternativeName()) : + m_alt_name(name) {} + + private: + std::string oid_name() const override { return "X509v3.SubjectAlternativeName"; } + + bool should_encode() const override { return m_alt_name.has_items(); } + std::vector encode_inner() const override; + void decode_inner(const std::vector&) override; + void contents_to(Data_Store&, Data_Store&) const override; + + AlternativeName m_alt_name; + }; + +/** +* Issuer Alternative Name Extension +*/ +class BOTAN_PUBLIC_API(2,0) Issuer_Alternative_Name final : public Certificate_Extension + { + public: + const AlternativeName& get_alt_name() const { return m_alt_name; } + + static OID static_oid() { return OID("2.5.29.18"); } + OID oid_of() const override { return static_oid(); } + + Issuer_Alternative_Name* copy() const override + { return new Issuer_Alternative_Name(get_alt_name()); } + + explicit Issuer_Alternative_Name(const AlternativeName& name = AlternativeName()) : + m_alt_name(name) {} + + private: + std::string oid_name() const override { return "X509v3.IssuerAlternativeName"; } + + bool should_encode() const override { return m_alt_name.has_items(); } + std::vector encode_inner() const override; + void decode_inner(const std::vector&) override; + void contents_to(Data_Store&, Data_Store&) const override; + + AlternativeName m_alt_name; + }; + +/** +* Extended Key Usage Extension +*/ +class BOTAN_PUBLIC_API(2,0) Extended_Key_Usage final : public Certificate_Extension + { + public: + Extended_Key_Usage* copy() const override + { return new Extended_Key_Usage(m_oids); } + + Extended_Key_Usage() = default; + explicit Extended_Key_Usage(const std::vector& o) : m_oids(o) {} + + const std::vector& get_oids() const { return m_oids; } + + static OID static_oid() { return OID("2.5.29.37"); } + OID oid_of() const override { return static_oid(); } + + private: + std::string oid_name() const override { return "X509v3.ExtendedKeyUsage"; } + + bool should_encode() const override { return (m_oids.size() > 0); } + std::vector encode_inner() const override; + void decode_inner(const std::vector&) override; + void contents_to(Data_Store&, Data_Store&) const override; + + std::vector m_oids; + }; + +/** +* Name Constraints +*/ +class BOTAN_PUBLIC_API(2,0) Name_Constraints final : public Certificate_Extension + { + public: + Name_Constraints* copy() const override + { return new Name_Constraints(m_name_constraints); } + + Name_Constraints() = default; + Name_Constraints(const NameConstraints &nc) : m_name_constraints(nc) {} + + void validate(const X509_Certificate& subject, const X509_Certificate& issuer, + const std::vector>& cert_path, + std::vector>& cert_status, + size_t pos) override; + + const NameConstraints& get_name_constraints() const { return m_name_constraints; } + + static OID static_oid() { return OID("2.5.29.30"); } + OID oid_of() const override { return static_oid(); } + + private: + std::string oid_name() const override + { return "X509v3.NameConstraints"; } + + bool should_encode() const override { return true; } + std::vector encode_inner() const override; + void decode_inner(const std::vector&) override; + void contents_to(Data_Store&, Data_Store&) const override; + + NameConstraints m_name_constraints; + }; + +/** +* Certificate Policies Extension +*/ +class BOTAN_PUBLIC_API(2,0) Certificate_Policies final : public Certificate_Extension + { + public: + Certificate_Policies* copy() const override + { return new Certificate_Policies(m_oids); } + + Certificate_Policies() = default; + explicit Certificate_Policies(const std::vector& o) : m_oids(o) {} + + BOTAN_DEPRECATED("Use get_policy_oids") + std::vector get_oids() const { return m_oids; } + + const std::vector& get_policy_oids() const { return m_oids; } + + static OID static_oid() { return OID("2.5.29.32"); } + OID oid_of() const override { return static_oid(); } + + void validate(const X509_Certificate& subject, const X509_Certificate& issuer, + const std::vector>& cert_path, + std::vector>& cert_status, + size_t pos) override; + private: + std::string oid_name() const override + { return "X509v3.CertificatePolicies"; } + + bool should_encode() const override { return (m_oids.size() > 0); } + std::vector encode_inner() const override; + void decode_inner(const std::vector&) override; + void contents_to(Data_Store&, Data_Store&) const override; + + std::vector m_oids; + }; + +/** +* Authority Information Access Extension +*/ +class BOTAN_PUBLIC_API(2,0) Authority_Information_Access final : public Certificate_Extension + { + public: + Authority_Information_Access* copy() const override + { return new Authority_Information_Access(m_ocsp_responder, m_ca_issuers); } + + Authority_Information_Access() = default; + + explicit Authority_Information_Access(const std::string& ocsp, const std::vector& ca_issuers = std::vector()) : + m_ocsp_responder(ocsp), m_ca_issuers(ca_issuers) {} + + std::string ocsp_responder() const { return m_ocsp_responder; } + + static OID static_oid() { return OID("1.3.6.1.5.5.7.1.1"); } + OID oid_of() const override { return static_oid(); } + const std::vector ca_issuers() const { return m_ca_issuers; } + + private: + std::string oid_name() const override + { return "PKIX.AuthorityInformationAccess"; } + + bool should_encode() const override { return (!m_ocsp_responder.empty()); } + + std::vector encode_inner() const override; + void decode_inner(const std::vector&) override; + + void contents_to(Data_Store&, Data_Store&) const override; + + std::string m_ocsp_responder; + std::vector m_ca_issuers; + }; + +/** +* CRL Number Extension +*/ +class BOTAN_PUBLIC_API(2,0) CRL_Number final : public Certificate_Extension + { + public: + CRL_Number* copy() const override; + + CRL_Number() : m_has_value(false), m_crl_number(0) {} + CRL_Number(size_t n) : m_has_value(true), m_crl_number(n) {} + + size_t get_crl_number() const; + + static OID static_oid() { return OID("2.5.29.20"); } + OID oid_of() const override { return static_oid(); } + + private: + std::string oid_name() const override { return "X509v3.CRLNumber"; } + + bool should_encode() const override { return m_has_value; } + std::vector encode_inner() const override; + void decode_inner(const std::vector&) override; + void contents_to(Data_Store&, Data_Store&) const override; + + bool m_has_value; + size_t m_crl_number; + }; + +/** +* CRL Entry Reason Code Extension +*/ +class BOTAN_PUBLIC_API(2,0) CRL_ReasonCode final : public Certificate_Extension + { + public: + CRL_ReasonCode* copy() const override + { return new CRL_ReasonCode(m_reason); } + + explicit CRL_ReasonCode(CRL_Code r = UNSPECIFIED) : m_reason(r) {} + + CRL_Code get_reason() const { return m_reason; } + + static OID static_oid() { return OID("2.5.29.21"); } + OID oid_of() const override { return static_oid(); } + + private: + std::string oid_name() const override { return "X509v3.ReasonCode"; } + + bool should_encode() const override { return (m_reason != UNSPECIFIED); } + std::vector encode_inner() const override; + void decode_inner(const std::vector&) override; + void contents_to(Data_Store&, Data_Store&) const override; + + CRL_Code m_reason; + }; + +/** +* CRL Distribution Points Extension +* todo enforce restrictions from RFC 5280 4.2.1.13 +*/ +class BOTAN_PUBLIC_API(2,0) CRL_Distribution_Points final : public Certificate_Extension + { + public: + class BOTAN_PUBLIC_API(2,0) Distribution_Point final : public ASN1_Object + { + public: + void encode_into(class DER_Encoder&) const override; + void decode_from(class BER_Decoder&) override; + + const AlternativeName& point() const { return m_point; } + private: + AlternativeName m_point; + }; + + CRL_Distribution_Points* copy() const override + { return new CRL_Distribution_Points(m_distribution_points); } + + CRL_Distribution_Points() = default; + + explicit CRL_Distribution_Points(const std::vector& points) : + m_distribution_points(points) {} + + const std::vector& distribution_points() const + { return m_distribution_points; } + + const std::vector& crl_distribution_urls() const + { return m_crl_distribution_urls; } + + static OID static_oid() { return OID("2.5.29.31"); } + OID oid_of() const override { return static_oid(); } + + private: + std::string oid_name() const override + { return "X509v3.CRLDistributionPoints"; } + + bool should_encode() const override + { return !m_distribution_points.empty(); } + + std::vector encode_inner() const override; + void decode_inner(const std::vector&) override; + void contents_to(Data_Store&, Data_Store&) const override; + + std::vector m_distribution_points; + std::vector m_crl_distribution_urls; + }; + +/** +* CRL Issuing Distribution Point Extension +* todo enforce restrictions from RFC 5280 5.2.5 +*/ +class CRL_Issuing_Distribution_Point final : public Certificate_Extension + { + public: + CRL_Issuing_Distribution_Point() = default; + + explicit CRL_Issuing_Distribution_Point(const CRL_Distribution_Points::Distribution_Point& distribution_point) : + m_distribution_point(distribution_point) {} + + CRL_Issuing_Distribution_Point* copy() const override + { return new CRL_Issuing_Distribution_Point(m_distribution_point); } + + const AlternativeName& get_point() const + { return m_distribution_point.point(); } + + static OID static_oid() { return OID("2.5.29.28"); } + OID oid_of() const override { return static_oid(); } + + private: + std::string oid_name() const override + { return "X509v3.CRLIssuingDistributionPoint"; } + + bool should_encode() const override { return true; } + std::vector encode_inner() const override; + void decode_inner(const std::vector&) override; + void contents_to(Data_Store&, Data_Store&) const override; + + CRL_Distribution_Points::Distribution_Point m_distribution_point; + }; + +/** +* An unknown X.509 extension +* Will add a failure to the path validation result, if critical +*/ +class BOTAN_PUBLIC_API(2,4) Unknown_Extension final : public Certificate_Extension + { + public: + Unknown_Extension(const OID& oid, bool critical) : + m_oid(oid), m_critical(critical) {} + + Unknown_Extension* copy() const override + { return new Unknown_Extension(m_oid, m_critical); } + + /** + * Return the OID of this unknown extension + */ + OID oid_of() const override + { return m_oid; } + + //static_oid not defined for Unknown_Extension + + /** + * Return the extension contents + */ + const std::vector& extension_contents() const { return m_bytes; } + + /** + * Return if this extension was marked critical + */ + bool is_critical_extension() const { return m_critical; } + + void validate(const X509_Certificate&, const X509_Certificate&, + const std::vector>&, + std::vector>& cert_status, + size_t pos) override + { + if(m_critical) + { + cert_status.at(pos).insert(Certificate_Status_Code::UNKNOWN_CRITICAL_EXTENSION); + } + } + + private: + std::string oid_name() const override { return ""; } + + bool should_encode() const override { return true; } + std::vector encode_inner() const override; + void decode_inner(const std::vector&) override; + void contents_to(Data_Store&, Data_Store&) const override; + + OID m_oid; + bool m_critical; + std::vector m_bytes; + }; + + } + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/x509/x509_obj.cpp b/src/libs/3rdparty/botan/src/lib/x509/x509_obj.cpp new file mode 100644 index 0000000000..0604530729 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/x509/x509_obj.cpp @@ -0,0 +1,379 @@ +/* +* X.509 SIGNED Object +* (C) 1999-2007 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Botan { + +namespace { +struct Pss_params + { + AlgorithmIdentifier hash_algo; + AlgorithmIdentifier mask_gen_algo; + AlgorithmIdentifier mask_gen_hash; // redundant: decoded mask_gen_algo.parameters + size_t salt_len; + size_t trailer_field; + }; + +Pss_params decode_pss_params(const std::vector& encoded_pss_params) + { + const AlgorithmIdentifier default_hash("SHA-160", AlgorithmIdentifier::USE_NULL_PARAM); + const AlgorithmIdentifier default_mgf("MGF1", default_hash.BER_encode()); + + Pss_params pss_parameter; + BER_Decoder(encoded_pss_params) + .start_cons(SEQUENCE) + .decode_optional(pss_parameter.hash_algo, ASN1_Tag(0), PRIVATE, default_hash) + .decode_optional(pss_parameter.mask_gen_algo, ASN1_Tag(1), PRIVATE, default_mgf) + .decode_optional(pss_parameter.salt_len, ASN1_Tag(2), PRIVATE, size_t(20)) + .decode_optional(pss_parameter.trailer_field, ASN1_Tag(3), PRIVATE, size_t(1)) + .end_cons(); + + BER_Decoder(pss_parameter.mask_gen_algo.get_parameters()).decode(pss_parameter.mask_gen_hash); + + return pss_parameter; + } +} + +/* +* Read a PEM or BER X.509 object +*/ +void X509_Object::load_data(DataSource& in) + { + try { + if(ASN1::maybe_BER(in) && !PEM_Code::matches(in)) + { + BER_Decoder dec(in); + decode_from(dec); + } + else + { + std::string got_label; + DataSource_Memory ber(PEM_Code::decode(in, got_label)); + + if(got_label != PEM_label()) + { + bool is_alternate = false; + for(std::string alt_label : alternate_PEM_labels()) + { + if(got_label == alt_label) + { + is_alternate = true; + break; + } + } + + if(!is_alternate) + throw Decoding_Error("Unexpected PEM label for " + PEM_label() + " of " + got_label); + } + + BER_Decoder dec(ber); + decode_from(dec); + } + } + catch(Decoding_Error& e) + { + throw Decoding_Error(PEM_label() + " decoding failed: " + e.what()); + } + } + + +void X509_Object::encode_into(DER_Encoder& to) const + { + to.start_cons(SEQUENCE) + .start_cons(SEQUENCE) + .raw_bytes(signed_body()) + .end_cons() + .encode(signature_algorithm()) + .encode(signature(), BIT_STRING) + .end_cons(); + } + +/* +* Read a BER encoded X.509 object +*/ +void X509_Object::decode_from(BER_Decoder& from) + { + from.start_cons(SEQUENCE) + .start_cons(SEQUENCE) + .raw_bytes(m_tbs_bits) + .end_cons() + .decode(m_sig_algo) + .decode(m_sig, BIT_STRING) + .end_cons(); + + force_decode(); + } + +/* +* Return a PEM encoded X.509 object +*/ +std::string X509_Object::PEM_encode() const + { + return PEM_Code::encode(BER_encode(), PEM_label()); + } + +/* +* Return the TBS data +*/ +std::vector X509_Object::tbs_data() const + { + return ASN1::put_in_sequence(m_tbs_bits); + } + +/* +* Return the hash used in generating the signature +*/ +std::string X509_Object::hash_used_for_signature() const + { + const OID& oid = m_sig_algo.get_oid(); + const std::vector sig_info = split_on(OIDS::lookup(oid), '/'); + + if(sig_info.size() == 1 && sig_info[0] == "Ed25519") + return "SHA-512"; + else if(sig_info.size() != 2) + throw Internal_Error("Invalid name format found for " + oid.as_string()); + + if(sig_info[1] == "EMSA4") + { + return OIDS::lookup(decode_pss_params(signature_algorithm().get_parameters()).hash_algo.get_oid()); + } + else + { + const std::vector pad_and_hash = + parse_algorithm_name(sig_info[1]); + + if(pad_and_hash.size() != 2) + { + throw Internal_Error("Invalid name format " + sig_info[1]); + } + + return pad_and_hash[1]; + } + } + +/* +* Check the signature on an object +*/ +bool X509_Object::check_signature(const Public_Key* pub_key) const + { + if(!pub_key) + throw Exception("No key provided for " + PEM_label() + " signature check"); + std::unique_ptr key(pub_key); + return check_signature(*key); + } + +bool X509_Object::check_signature(const Public_Key& pub_key) const + { + const Certificate_Status_Code code = verify_signature(pub_key); + return (code == Certificate_Status_Code::VERIFIED); + } + +Certificate_Status_Code X509_Object::verify_signature(const Public_Key& pub_key) const + { + const std::vector sig_info = + split_on(OIDS::lookup(m_sig_algo.get_oid()), '/'); + + if(sig_info.size() < 1 || sig_info.size() > 2 || sig_info[0] != pub_key.algo_name()) + return Certificate_Status_Code::SIGNATURE_ALGO_BAD_PARAMS; + + std::string padding; + if(sig_info.size() == 2) + padding = sig_info[1]; + else if(sig_info[0] == "Ed25519") + padding = "Pure"; + else + return Certificate_Status_Code::SIGNATURE_ALGO_BAD_PARAMS; + + const Signature_Format format = + (pub_key.message_parts() >= 2) ? DER_SEQUENCE : IEEE_1363; + + if(padding == "EMSA4") + { + // "MUST contain RSASSA-PSS-params" + if(signature_algorithm().parameters.empty()) + { + return Certificate_Status_Code::SIGNATURE_ALGO_BAD_PARAMS; + } + + Pss_params pss_parameter = decode_pss_params(signature_algorithm().parameters); + + // hash_algo must be SHA1, SHA2-224, SHA2-256, SHA2-384 or SHA2-512 + const std::string hash_algo = OIDS::lookup(pss_parameter.hash_algo.oid); + if(hash_algo != "SHA-160" && + hash_algo != "SHA-224" && + hash_algo != "SHA-256" && + hash_algo != "SHA-384" && + hash_algo != "SHA-512") + { + return Certificate_Status_Code::UNTRUSTED_HASH; + } + + const std::string mgf_algo = OIDS::lookup(pss_parameter.mask_gen_algo.oid); + if(mgf_algo != "MGF1") + { + return Certificate_Status_Code::SIGNATURE_ALGO_BAD_PARAMS; + } + + // For MGF1, it is strongly RECOMMENDED that the underlying hash function be the same as the one identified by hashAlgorithm + // Must be SHA1, SHA2-224, SHA2-256, SHA2-384 or SHA2-512 + if(pss_parameter.mask_gen_hash.oid != pss_parameter.hash_algo.oid) + { + return Certificate_Status_Code::SIGNATURE_ALGO_BAD_PARAMS; + } + + if(pss_parameter.trailer_field != 1) + { + return Certificate_Status_Code::SIGNATURE_ALGO_BAD_PARAMS; + } + + // salt_len is actually not used for verification. Length is inferred from the signature + padding += "(" + hash_algo + "," + mgf_algo + "," + std::to_string(pss_parameter.salt_len) + ")"; + } + + try + { + PK_Verifier verifier(pub_key, padding, format); + const bool valid = verifier.verify_message(tbs_data(), signature()); + + if(valid) + return Certificate_Status_Code::VERIFIED; + else + return Certificate_Status_Code::SIGNATURE_ERROR; + } + catch(Algorithm_Not_Found&) + { + return Certificate_Status_Code::SIGNATURE_ALGO_UNKNOWN; + } + catch(...) + { + // This shouldn't happen, fallback to generic signature error + return Certificate_Status_Code::SIGNATURE_ERROR; + } + } + +/* +* Apply the X.509 SIGNED macro +*/ +std::vector X509_Object::make_signed(PK_Signer* signer, + RandomNumberGenerator& rng, + const AlgorithmIdentifier& algo, + const secure_vector& tbs_bits) + { + const std::vector signature = signer->sign_message(tbs_bits, rng); + + std::vector output; + DER_Encoder(output) + .start_cons(SEQUENCE) + .raw_bytes(tbs_bits) + .encode(algo) + .encode(signature, BIT_STRING) + .end_cons(); + + return output; + } + +namespace { + +std::string choose_sig_algo(AlgorithmIdentifier& sig_algo, + const Private_Key& key, + const std::string& hash_fn, + const std::string& user_specified) + { + const std::string algo_name = key.algo_name(); + std::string padding; + + // check algo_name and set default + if(algo_name == "RSA") + { + // set to EMSA3 for compatibility reasons, originally it was the only option + padding = "EMSA3(" + hash_fn + ")"; + } + else if(algo_name == "DSA" || + algo_name == "ECDSA" || + algo_name == "ECGDSA" || + algo_name == "ECKCDSA" || + algo_name == "GOST-34.10") + { + padding = "EMSA1(" + hash_fn + ")"; + } + else if(algo_name == "Ed25519") + { + padding = "Pure"; + } + else + { + throw Invalid_Argument("Unknown X.509 signing key type: " + algo_name); + } + + if(user_specified.empty() == false) + { + padding = user_specified; + } + + if(padding != "Pure") + { + // try to construct an EMSA object from the padding options or default + std::unique_ptr emsa; + try + { + emsa.reset(get_emsa(padding)); + } + /* + * get_emsa will throw if opts contains {"padding",} but + * does not specify a hash function. + * Omitting it is valid since it needs to be identical to hash_fn. + * If it still throws, something happened that we cannot repair here, + * e.g. the algorithm/padding combination is not supported. + */ + catch(...) + { + emsa.reset(get_emsa(padding + "(" + hash_fn + ")")); + } + + if(!emsa) + { + throw Invalid_Argument("Could not parse padding scheme " + padding); + } + + sig_algo = emsa->config_for_x509(key, hash_fn); + return emsa->name(); + } + else + { + sig_algo = AlgorithmIdentifier(OIDS::lookup("Ed25519"), AlgorithmIdentifier::USE_EMPTY_PARAM); + return "Pure"; + } + } + +} + +/* +* Choose a signing format for the key +*/ +std::unique_ptr X509_Object::choose_sig_format(AlgorithmIdentifier& sig_algo, + const Private_Key& key, + RandomNumberGenerator& rng, + const std::string& hash_fn, + const std::string& padding_algo) + { + const Signature_Format format = (key.message_parts() > 1) ? DER_SEQUENCE : IEEE_1363; + + const std::string emsa = choose_sig_algo(sig_algo, key, hash_fn, padding_algo); + + return std::unique_ptr(new PK_Signer(key, rng, emsa, format)); + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/x509/x509_obj.h b/src/libs/3rdparty/botan/src/lib/x509/x509_obj.h new file mode 100644 index 0000000000..a0c8e5b398 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/x509/x509_obj.h @@ -0,0 +1,145 @@ +/* +* X.509 SIGNED Object +* (C) 1999-2007 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_X509_OBJECT_H_ +#define BOTAN_X509_OBJECT_H_ + +#include +#include +#include +#include + +namespace Botan { + +class Public_Key; +class Private_Key; +class RandomNumberGenerator; + +/** +* This class represents abstract X.509 signed objects as in the X.500 +* SIGNED macro +*/ +class BOTAN_PUBLIC_API(2,0) X509_Object : public ASN1_Object + { + public: + /** + * The underlying data that is to be or was signed + * @return data that is or was signed + */ + std::vector tbs_data() const; + + /** + * @return signature on tbs_data() + */ + const std::vector& signature() const { return m_sig; } + + /** + * @return signed body + */ + const std::vector& signed_body() const { return m_tbs_bits; } + + /** + * @return signature algorithm that was used to generate signature + */ + const AlgorithmIdentifier& signature_algorithm() const { return m_sig_algo; } + + /** + * @return hash algorithm that was used to generate signature + */ + std::string hash_used_for_signature() const; + + /** + * Create a signed X509 object. + * @param signer the signer used to sign the object + * @param rng the random number generator to use + * @param alg_id the algorithm identifier of the signature scheme + * @param tbs the tbs bits to be signed + * @return signed X509 object + */ + static std::vector make_signed(class PK_Signer* signer, + RandomNumberGenerator& rng, + const AlgorithmIdentifier& alg_id, + const secure_vector& tbs); + + /** + * Check the signature on this data + * @param key the public key purportedly used to sign this data + * @return status of the signature - OK if verified or otherwise an indicator of + * the problem preventing verification. + */ + Certificate_Status_Code verify_signature(const Public_Key& key) const; + + /** + * Check the signature on this data + * @param key the public key purportedly used to sign this data + * @return true if the signature is valid, otherwise false + */ + bool check_signature(const Public_Key& key) const; + + /** + * Check the signature on this data + * @param key the public key purportedly used to sign this data + * the object will be deleted after use (this should have + * been a std::unique_ptr) + * @return true if the signature is valid, otherwise false + */ + bool check_signature(const Public_Key* key) const; + + /** + * DER encode an X509_Object + * See @ref ASN1_Object::encode_into() + */ + void encode_into(class DER_Encoder& to) const override; + + /** + * Decode a BER encoded X509_Object + * See @ref ASN1_Object::decode_from() + */ + void decode_from(class BER_Decoder& from) override; + + /** + * @return PEM encoding of this + */ + std::string PEM_encode() const; + + X509_Object(const X509_Object&) = default; + X509_Object& operator=(const X509_Object&) = default; + + virtual std::string PEM_label() const = 0; + + virtual std::vector alternate_PEM_labels() const + { return std::vector(); } + + virtual ~X509_Object() = default; + + static std::unique_ptr + choose_sig_format(AlgorithmIdentifier& sig_algo, + const Private_Key& key, + RandomNumberGenerator& rng, + const std::string& hash_fn, + const std::string& padding_algo); + + protected: + + X509_Object() = default; + + /** + * Decodes from src as either DER or PEM data, then calls force_decode() + */ + void load_data(DataSource& src); + + private: + virtual void force_decode() = 0; + + AlgorithmIdentifier m_sig_algo; + std::vector m_tbs_bits; + std::vector m_sig; + }; + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/x509/x509cert.cpp b/src/libs/3rdparty/botan/src/lib/x509/x509cert.cpp new file mode 100644 index 0000000000..ddfe5d5b2b --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/x509/x509cert.cpp @@ -0,0 +1,879 @@ +/* +* X.509 Certificates +* (C) 1999-2010,2015,2017 Jack Lloyd +* (C) 2016 René Korthaus, Rohde & Schwarz Cybersecurity +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Botan { + +struct X509_Certificate_Data + { + std::vector m_serial; + AlgorithmIdentifier m_sig_algo_inner; + X509_DN m_issuer_dn; + X509_DN m_subject_dn; + std::vector m_issuer_dn_bits; + std::vector m_subject_dn_bits; + X509_Time m_not_before; + X509_Time m_not_after; + std::vector m_subject_public_key_bits; + std::vector m_subject_public_key_bits_seq; + std::vector m_subject_public_key_bitstring; + std::vector m_subject_public_key_bitstring_sha1; + AlgorithmIdentifier m_subject_public_key_algid; + + std::vector m_v2_issuer_key_id; + std::vector m_v2_subject_key_id; + Extensions m_v3_extensions; + + std::vector m_extended_key_usage; + std::vector m_authority_key_id; + std::vector m_subject_key_id; + std::vector m_cert_policies; + + std::vector m_crl_distribution_points; + std::string m_ocsp_responder; + std::vector m_ca_issuers; + + AlternativeName m_subject_alt_name; + AlternativeName m_issuer_alt_name; + NameConstraints m_name_constraints; + + Data_Store m_subject_ds; + Data_Store m_issuer_ds; + + size_t m_version = 0; + size_t m_path_len_constraint = 0; + Key_Constraints m_key_constraints = NO_CONSTRAINTS; + bool m_self_signed = false; + bool m_is_ca_certificate = false; + bool m_serial_negative = false; + }; + +std::string X509_Certificate::PEM_label() const + { + return "CERTIFICATE"; + } + +std::vector X509_Certificate::alternate_PEM_labels() const + { + return { "X509 CERTIFICATE" }; + } + +X509_Certificate::X509_Certificate(DataSource& src) + { + load_data(src); + } + +X509_Certificate::X509_Certificate(const std::vector& vec) + { + DataSource_Memory src(vec.data(), vec.size()); + load_data(src); + } + +X509_Certificate::X509_Certificate(const uint8_t data[], size_t len) + { + DataSource_Memory src(data, len); + load_data(src); + } + +#if defined(BOTAN_TARGET_OS_HAS_FILESYSTEM) +X509_Certificate::X509_Certificate(const std::string& fsname) + { + DataSource_Stream src(fsname, true); + load_data(src); + } +#endif + +namespace { + +std::unique_ptr parse_x509_cert_body(const X509_Object& obj) + { + std::unique_ptr data(new X509_Certificate_Data); + + BigInt serial_bn; + BER_Object public_key; + BER_Object v3_exts_data; + + BER_Decoder(obj.signed_body()) + .decode_optional(data->m_version, ASN1_Tag(0), ASN1_Tag(CONSTRUCTED | CONTEXT_SPECIFIC)) + .decode(serial_bn) + .decode(data->m_sig_algo_inner) + .decode(data->m_issuer_dn) + .start_cons(SEQUENCE) + .decode(data->m_not_before) + .decode(data->m_not_after) + .end_cons() + .decode(data->m_subject_dn) + .get_next(public_key) + .decode_optional_string(data->m_v2_issuer_key_id, BIT_STRING, 1) + .decode_optional_string(data->m_v2_subject_key_id, BIT_STRING, 2) + .get_next(v3_exts_data) + .verify_end("TBSCertificate has extra data after extensions block"); + + if(data->m_version > 2) + throw Decoding_Error("Unknown X.509 cert version " + std::to_string(data->m_version)); + if(obj.signature_algorithm() != data->m_sig_algo_inner) + throw Decoding_Error("X.509 Certificate had differing algorithm identifers in inner and outer ID fields"); + + public_key.assert_is_a(SEQUENCE, CONSTRUCTED, "X.509 certificate public key"); + + // crude method to save the serial's sign; will get lost during decoding, otherwise + data->m_serial_negative = serial_bn.is_negative(); + + // for general sanity convert wire version (0 based) to standards version (v1 .. v3) + data->m_version += 1; + + data->m_serial = BigInt::encode(serial_bn); + data->m_subject_dn_bits = ASN1::put_in_sequence(data->m_subject_dn.get_bits()); + data->m_issuer_dn_bits = ASN1::put_in_sequence(data->m_issuer_dn.get_bits()); + + // validate_public_key_params(public_key.value); + AlgorithmIdentifier public_key_alg_id; + BER_Decoder(public_key).decode(public_key_alg_id).discard_remaining(); + + std::vector public_key_info = + split_on(OIDS::oid2str(public_key_alg_id.get_oid()), '/'); + + if(!public_key_info.empty() && public_key_info[0] == "RSA") + { + // RFC4055: If PublicKeyAlgo = PSS or OAEP: limit the use of the public key exclusively to either RSASSA - PSS or RSAES - OAEP + if(public_key_info.size() >= 2) + { + if(public_key_info[1] == "EMSA4") + { + /* + When the RSA private key owner wishes to limit the use of the public + key exclusively to RSASSA-PSS, then the id-RSASSA-PSS object + identifier MUST be used in the algorithm field within the subject + public key information, and, if present, the parameters field MUST + contain RSASSA-PSS-params. + + All parameters in the signature structure algorithm identifier MUST + match the parameters in the key structure algorithm identifier + except the saltLength field. The saltLength field in the signature parameters + MUST be greater or equal to that in the key parameters field. + + ToDo: Allow salt length to be greater + */ + if(public_key_alg_id != obj.signature_algorithm()) + { + throw Decoding_Error("Algorithm identifier mismatch"); + } + } + if(public_key_info[1] == "OAEP") + { + throw Decoding_Error("Decoding subject public keys of type RSAES-OAEP is currently not supported"); + } + } + else + { + // oid = rsaEncryption -> parameters field MUST contain NULL + if(public_key_alg_id != AlgorithmIdentifier(public_key_alg_id.get_oid(), AlgorithmIdentifier::USE_NULL_PARAM)) + { + throw Decoding_Error("Parameters field MUST contain NULL"); + } + } + } + + data->m_subject_public_key_bits.assign(public_key.bits(), public_key.bits() + public_key.length()); + + data->m_subject_public_key_bits_seq = ASN1::put_in_sequence(data->m_subject_public_key_bits); + + BER_Decoder(data->m_subject_public_key_bits) + .decode(data->m_subject_public_key_algid) + .decode(data->m_subject_public_key_bitstring, BIT_STRING); + + if(v3_exts_data.is_a(3, ASN1_Tag(CONSTRUCTED | CONTEXT_SPECIFIC))) + { + BER_Decoder(v3_exts_data).decode(data->m_v3_extensions).verify_end(); + } + else if(v3_exts_data.is_set()) + throw BER_Bad_Tag("Unknown tag in X.509 cert", v3_exts_data.tagging()); + + // Now cache some fields from the extensions + if(auto ext = data->m_v3_extensions.get_extension_object_as()) + { + data->m_key_constraints = ext->get_constraints(); + } + else + { + data->m_key_constraints = NO_CONSTRAINTS; + } + + if(auto ext = data->m_v3_extensions.get_extension_object_as()) + { + data->m_subject_key_id = ext->get_key_id(); + } + + if(auto ext = data->m_v3_extensions.get_extension_object_as()) + { + data->m_authority_key_id = ext->get_key_id(); + } + + if(auto ext = data->m_v3_extensions.get_extension_object_as()) + { + data->m_name_constraints = ext->get_name_constraints(); + } + + if(auto ext = data->m_v3_extensions.get_extension_object_as()) + { + if(ext->get_is_ca() == true) + { + if(data->m_key_constraints == NO_CONSTRAINTS || + (data->m_key_constraints & KEY_CERT_SIGN)) + { + data->m_is_ca_certificate = true; + data->m_path_len_constraint = ext->get_path_limit(); + } + } + } + + if(auto ext = data->m_v3_extensions.get_extension_object_as()) + { + data->m_issuer_alt_name = ext->get_alt_name(); + } + + if(auto ext = data->m_v3_extensions.get_extension_object_as()) + { + data->m_subject_alt_name = ext->get_alt_name(); + } + + if(auto ext = data->m_v3_extensions.get_extension_object_as()) + { + data->m_extended_key_usage = ext->get_oids(); + } + + if(auto ext = data->m_v3_extensions.get_extension_object_as()) + { + data->m_cert_policies = ext->get_policy_oids(); + } + + if(auto ext = data->m_v3_extensions.get_extension_object_as()) + { + data->m_ocsp_responder = ext->ocsp_responder(); + data->m_ca_issuers = ext->ca_issuers(); + } + + if(auto ext = data->m_v3_extensions.get_extension_object_as()) + { + data->m_crl_distribution_points = ext->crl_distribution_urls(); + } + + // Check for self-signed vs self-issued certificates + if(data->m_subject_dn == data->m_issuer_dn) + { + if(data->m_subject_key_id.empty() == false && data->m_authority_key_id.empty() == false) + { + data->m_self_signed = (data->m_subject_key_id == data->m_authority_key_id); + } + else + { + try + { + std::unique_ptr pub_key(X509::load_key(data->m_subject_public_key_bits_seq)); + + Certificate_Status_Code sig_status = obj.verify_signature(*pub_key); + + if(sig_status == Certificate_Status_Code::OK || + sig_status == Certificate_Status_Code::SIGNATURE_ALGO_UNKNOWN) + { + data->m_self_signed = true; + } + } + catch(...) + { + // ignore errors here to allow parsing to continue + } + } + } + + std::unique_ptr sha1(HashFunction::create("SHA-1")); + if(sha1) + { + sha1->update(data->m_subject_public_key_bitstring); + data->m_subject_public_key_bitstring_sha1 = sha1->final_stdvec(); + // otherwise left as empty, and we will throw if subject_public_key_bitstring_sha1 is called + } + + data->m_subject_ds.add(data->m_subject_dn.contents()); + data->m_issuer_ds.add(data->m_issuer_dn.contents()); + data->m_v3_extensions.contents_to(data->m_subject_ds, data->m_issuer_ds); + + return data; + } + +} + +/* +* Decode the TBSCertificate data +*/ +void X509_Certificate::force_decode() + { + m_data.reset(); + + std::unique_ptr data = parse_x509_cert_body(*this); + + m_data.reset(data.release()); + } + +const X509_Certificate_Data& X509_Certificate::data() const + { + if(m_data == nullptr) + { + throw Invalid_State("X509_Certificate uninitialized"); + } + return *m_data.get(); + } + +uint32_t X509_Certificate::x509_version() const + { + return data().m_version; + } + +bool X509_Certificate::is_self_signed() const + { + return data().m_self_signed; + } + +const X509_Time& X509_Certificate::not_before() const + { + return data().m_not_before; + } + +const X509_Time& X509_Certificate::not_after() const + { + return data().m_not_after; + } + +const AlgorithmIdentifier& X509_Certificate::subject_public_key_algo() const + { + return data().m_subject_public_key_algid; + } + +const std::vector& X509_Certificate::v2_issuer_key_id() const + { + return data().m_v2_issuer_key_id; + } + +const std::vector& X509_Certificate::v2_subject_key_id() const + { + return data().m_v2_subject_key_id; + } + +const std::vector& X509_Certificate::subject_public_key_bits() const + { + return data().m_subject_public_key_bits; + } + +const std::vector& X509_Certificate::subject_public_key_info() const + { + return data().m_subject_public_key_bits_seq; + } + +const std::vector& X509_Certificate::subject_public_key_bitstring() const + { + return data().m_subject_public_key_bitstring; + } + +const std::vector& X509_Certificate::subject_public_key_bitstring_sha1() const + { + if(data().m_subject_public_key_bitstring_sha1.empty()) + throw Encoding_Error("X509_Certificate::subject_public_key_bitstring_sha1 called but SHA-1 disabled in build"); + + return data().m_subject_public_key_bitstring_sha1; + } + +const std::vector& X509_Certificate::authority_key_id() const + { + return data().m_authority_key_id; + } + +const std::vector& X509_Certificate::subject_key_id() const + { + return data().m_subject_key_id; + } + +const std::vector& X509_Certificate::serial_number() const + { + return data().m_serial; + } + +bool X509_Certificate::is_serial_negative() const + { + return data().m_serial_negative; + } + + +const X509_DN& X509_Certificate::issuer_dn() const + { + return data().m_issuer_dn; + } + +const X509_DN& X509_Certificate::subject_dn() const + { + return data().m_subject_dn; + } + +const std::vector& X509_Certificate::raw_issuer_dn() const + { + return data().m_issuer_dn_bits; + } + +const std::vector& X509_Certificate::raw_subject_dn() const + { + return data().m_subject_dn_bits; + } + +bool X509_Certificate::is_CA_cert() const + { + return data().m_is_ca_certificate; + } + +uint32_t X509_Certificate::path_limit() const + { + return data().m_path_len_constraint; + } + +Key_Constraints X509_Certificate::constraints() const + { + return data().m_key_constraints; + } + +const std::vector& X509_Certificate::extended_key_usage() const + { + return data().m_extended_key_usage; + } + +const std::vector& X509_Certificate::certificate_policy_oids() const + { + return data().m_cert_policies; + } + +const NameConstraints& X509_Certificate::name_constraints() const + { + return data().m_name_constraints; + } + +const Extensions& X509_Certificate::v3_extensions() const + { + return data().m_v3_extensions; + } + +bool X509_Certificate::allowed_usage(Key_Constraints usage) const + { + if(constraints() == NO_CONSTRAINTS) + return true; + return ((constraints() & usage) == usage); + } + +bool X509_Certificate::allowed_extended_usage(const std::string& usage) const + { + return allowed_extended_usage(OIDS::str2oid(usage)); + } + +bool X509_Certificate::allowed_extended_usage(const OID& usage) const + { + const std::vector& ex = extended_key_usage(); + if(ex.empty()) + return true; + + if(std::find(ex.begin(), ex.end(), usage) != ex.end()) + return true; + + return false; + } + +bool X509_Certificate::allowed_usage(Usage_Type usage) const + { + // These follow suggestions in RFC 5280 4.2.1.12 + + switch(usage) + { + case Usage_Type::UNSPECIFIED: + return true; + + case Usage_Type::TLS_SERVER_AUTH: + return (allowed_usage(KEY_AGREEMENT) || allowed_usage(KEY_ENCIPHERMENT) || allowed_usage(DIGITAL_SIGNATURE)) && allowed_extended_usage("PKIX.ServerAuth"); + + case Usage_Type::TLS_CLIENT_AUTH: + return (allowed_usage(DIGITAL_SIGNATURE) || allowed_usage(KEY_AGREEMENT)) && allowed_extended_usage("PKIX.ClientAuth"); + + case Usage_Type::OCSP_RESPONDER: + return (allowed_usage(DIGITAL_SIGNATURE) || allowed_usage(NON_REPUDIATION)) && allowed_extended_usage("PKIX.OCSPSigning"); + + case Usage_Type::CERTIFICATE_AUTHORITY: + return is_CA_cert(); + } + + return false; + } + +bool X509_Certificate::has_constraints(Key_Constraints constraints) const + { + if(this->constraints() == NO_CONSTRAINTS) + { + return false; + } + + return ((this->constraints() & constraints) != 0); + } + +bool X509_Certificate::has_ex_constraint(const std::string& ex_constraint) const + { + return has_ex_constraint(OIDS::str2oid(ex_constraint)); + } + +bool X509_Certificate::has_ex_constraint(const OID& usage) const + { + const std::vector& ex = extended_key_usage(); + return (std::find(ex.begin(), ex.end(), usage) != ex.end()); + } + +/* +* Return if a certificate extension is marked critical +*/ +bool X509_Certificate::is_critical(const std::string& ex_name) const + { + return v3_extensions().critical_extension_set(OIDS::str2oid(ex_name)); + } + +std::string X509_Certificate::ocsp_responder() const + { + return data().m_ocsp_responder; + } + +std::vector X509_Certificate::ca_issuers() const + { + return data().m_ca_issuers; + } + +std::string X509_Certificate::crl_distribution_point() const + { + // just returns the first (arbitrarily) + if(data().m_crl_distribution_points.size() > 0) + return data().m_crl_distribution_points[0]; + return ""; + } + +const AlternativeName& X509_Certificate::subject_alt_name() const + { + return data().m_subject_alt_name; + } + +const AlternativeName& X509_Certificate::issuer_alt_name() const + { + return data().m_issuer_alt_name; + } + +/* +* Return information about the subject +*/ +std::vector +X509_Certificate::subject_info(const std::string& req) const + { + if(req == "Email") + return this->subject_info("RFC822"); + + if(subject_dn().has_field(req)) + return subject_dn().get_attribute(req); + + if(subject_alt_name().has_field(req)) + return subject_alt_name().get_attribute(req); + + // These will be removed later: + if(req == "X509.Certificate.v2.key_id") + return {hex_encode(this->v2_subject_key_id())}; + if(req == "X509v3.SubjectKeyIdentifier") + return {hex_encode(this->subject_key_id())}; + if(req == "X509.Certificate.dn_bits") + return {hex_encode(this->raw_subject_dn())}; + if(req == "X509.Certificate.start") + return {not_before().to_string()}; + if(req == "X509.Certificate.end") + return {not_after().to_string()}; + + if(req == "X509.Certificate.version") + return {std::to_string(x509_version())}; + if(req == "X509.Certificate.serial") + return {hex_encode(serial_number())}; + + return data().m_subject_ds.get(req); + } + +/* +* Return information about the issuer +*/ +std::vector +X509_Certificate::issuer_info(const std::string& req) const + { + if(issuer_dn().has_field(req)) + return issuer_dn().get_attribute(req); + + if(issuer_alt_name().has_field(req)) + return issuer_alt_name().get_attribute(req); + + // These will be removed later: + if(req == "X509.Certificate.v2.key_id") + return {hex_encode(this->v2_issuer_key_id())}; + if(req == "X509v3.AuthorityKeyIdentifier") + return {hex_encode(this->authority_key_id())}; + if(req == "X509.Certificate.dn_bits") + return {hex_encode(this->raw_issuer_dn())}; + + return data().m_issuer_ds.get(req); + } + +/* +* Return the public key in this certificate +*/ +std::unique_ptr X509_Certificate::load_subject_public_key() const + { + try + { + return std::unique_ptr(X509::load_key(subject_public_key_info())); + } + catch(std::exception& e) + { + throw Decoding_Error("X509_Certificate::load_subject_public_key", e.what()); + } + } + +std::vector X509_Certificate::raw_issuer_dn_sha256() const + { + std::unique_ptr hash(HashFunction::create_or_throw("SHA-256")); + hash->update(raw_issuer_dn()); + return hash->final_stdvec(); + } + +std::vector X509_Certificate::raw_subject_dn_sha256() const + { + std::unique_ptr hash(HashFunction::create("SHA-256")); + hash->update(raw_subject_dn()); + return hash->final_stdvec(); + } + +namespace { + +/* +* Lookup each OID in the vector +*/ +std::vector lookup_oids(const std::vector& oids) + { + std::vector out; + + for(const OID& oid : oids) + { + out.push_back(OIDS::oid2str(oid)); + } + return out; + } + +} + +/* +* Return the list of extended key usage OIDs +*/ +std::vector X509_Certificate::ex_constraints() const + { + return lookup_oids(extended_key_usage()); + } + +/* +* Return the list of certificate policies +*/ +std::vector X509_Certificate::policies() const + { + return lookup_oids(certificate_policy_oids()); + } + +std::string X509_Certificate::fingerprint(const std::string& hash_name) const + { + return create_hex_fingerprint(this->BER_encode(), hash_name); + } + +bool X509_Certificate::matches_dns_name(const std::string& name) const + { + if(name.empty()) + return false; + + std::vector issued_names = subject_info("DNS"); + + // Fall back to CN only if no DNS names are set (RFC 6125 sec 6.4.4) + if(issued_names.empty()) + issued_names = subject_info("Name"); + + for(size_t i = 0; i != issued_names.size(); ++i) + { + if(host_wildcard_match(issued_names[i], name)) + return true; + } + + return false; + } + +/* +* Compare two certificates for equality +*/ +bool X509_Certificate::operator==(const X509_Certificate& other) const + { + return (this->signature() == other.signature() && + this->signature_algorithm() == other.signature_algorithm() && + this->signed_body() == other.signed_body()); + } + +bool X509_Certificate::operator<(const X509_Certificate& other) const + { + /* If signature values are not equal, sort by lexicographic ordering of that */ + if(this->signature() != other.signature()) + { + return (this->signature() < other.signature()); + } + + // Then compare the signed contents + return this->signed_body() < other.signed_body(); + } + +/* +* X.509 Certificate Comparison +*/ +bool operator!=(const X509_Certificate& cert1, const X509_Certificate& cert2) + { + return !(cert1 == cert2); + } + +std::string X509_Certificate::to_string() const + { + std::ostringstream out; + + out << "Version: " << this->x509_version() << "\n"; + out << "Subject: " << subject_dn() << "\n"; + out << "Issuer: " << issuer_dn() << "\n"; + out << "Issued: " << this->not_before().readable_string() << "\n"; + out << "Expires: " << this->not_after().readable_string() << "\n"; + + out << "Constraints:\n"; + Key_Constraints constraints = this->constraints(); + if(constraints == NO_CONSTRAINTS) + out << " None\n"; + else + { + if(constraints & DIGITAL_SIGNATURE) + out << " Digital Signature\n"; + if(constraints & NON_REPUDIATION) + out << " Non-Repudiation\n"; + if(constraints & KEY_ENCIPHERMENT) + out << " Key Encipherment\n"; + if(constraints & DATA_ENCIPHERMENT) + out << " Data Encipherment\n"; + if(constraints & KEY_AGREEMENT) + out << " Key Agreement\n"; + if(constraints & KEY_CERT_SIGN) + out << " Cert Sign\n"; + if(constraints & CRL_SIGN) + out << " CRL Sign\n"; + if(constraints & ENCIPHER_ONLY) + out << " Encipher Only\n"; + if(constraints & DECIPHER_ONLY) + out << " Decipher Only\n"; + } + + const std::vector policies = this->certificate_policy_oids(); + if(!policies.empty()) + { + out << "Policies: " << "\n"; + for(auto oid : policies) + out << " " << oid.as_string() << "\n"; + } + + std::vector ex_constraints = this->extended_key_usage(); + if(!ex_constraints.empty()) + { + out << "Extended Constraints:\n"; + for(size_t i = 0; i != ex_constraints.size(); i++) + out << " " << OIDS::oid2str(ex_constraints[i]) << "\n"; + } + + const NameConstraints& name_constraints = this->name_constraints(); + + if(!name_constraints.permitted().empty() || !name_constraints.excluded().empty()) + { + out << "Name Constraints:\n"; + + if(!name_constraints.permitted().empty()) + { + out << " Permit"; + for(auto st: name_constraints.permitted()) + { + out << " " << st.base(); + } + out << "\n"; + } + + if(!name_constraints.excluded().empty()) + { + out << " Exclude"; + for(auto st: name_constraints.excluded()) + { + out << " " << st.base(); + } + out << "\n"; + } + } + + if(!ocsp_responder().empty()) + out << "OCSP responder " << ocsp_responder() << "\n"; + + std::vector ca_issuers = this->ca_issuers(); + if(!ca_issuers.empty()) + { + out << "CA Issuers:\n"; + for(size_t i = 0; i != ca_issuers.size(); i++) + out << " URI: " << ca_issuers[i] << "\n"; + } + + if(!crl_distribution_point().empty()) + out << "CRL " << crl_distribution_point() << "\n"; + + out << "Signature algorithm: " << + OIDS::oid2str(this->signature_algorithm().get_oid()) << "\n"; + + out << "Serial number: " << hex_encode(this->serial_number()) << "\n"; + + if(this->authority_key_id().size()) + out << "Authority keyid: " << hex_encode(this->authority_key_id()) << "\n"; + + if(this->subject_key_id().size()) + out << "Subject keyid: " << hex_encode(this->subject_key_id()) << "\n"; + + try + { + std::unique_ptr pubkey(this->subject_public_key()); + out << "Public Key [" << pubkey->algo_name() << "-" << pubkey->key_length() << "]\n\n"; + out << X509::PEM_encode(*pubkey); + } + catch(Decoding_Error&) + { + const AlgorithmIdentifier& alg_id = this->subject_public_key_algo(); + out << "Failed to decode key with oid " << alg_id.get_oid().as_string() << "\n"; + } + + return out.str(); + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/x509/x509cert.h b/src/libs/3rdparty/botan/src/lib/x509/x509cert.h new file mode 100644 index 0000000000..34be10e680 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/x509/x509cert.h @@ -0,0 +1,464 @@ +/* +* X.509 Certificates +* (C) 1999-2007,2015,2017 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_X509_CERTS_H_ +#define BOTAN_X509_CERTS_H_ + +#include +#include +#include +#include +#include +#include + +namespace Botan { + +class Public_Key; +class X509_DN; +class AlternativeName; +class Extensions; + +enum class Usage_Type + { + UNSPECIFIED, // no restrictions + TLS_SERVER_AUTH, + TLS_CLIENT_AUTH, + CERTIFICATE_AUTHORITY, + OCSP_RESPONDER + }; + +struct X509_Certificate_Data; + +/** +* This class represents an X.509 Certificate +*/ +class BOTAN_PUBLIC_API(2,0) X509_Certificate : public X509_Object + { + public: + /** + * Return a newly allocated copy of the public key associated + * with the subject of this certificate. This object is owned + * by the caller. + * + * @return public key + */ + Public_Key* subject_public_key() const + { + return load_subject_public_key().release(); + } + + /** + * Create a public key object associated with the public key bits in this + * certificate. If the public key bits was valid for X.509 encoding + * purposes but invalid algorithmically (for example, RSA with an even + * modulus) that will be detected at this point, and an exception will be + * thrown. + * + * @return subject public key of this certificate + */ + std::unique_ptr load_subject_public_key() const; + + /** + * Get the public key associated with this certificate. This includes the + * outer AlgorithmIdentifier + * @return subject public key of this certificate + */ + const std::vector& subject_public_key_bits() const; + + /** + * Get the SubjectPublicKeyInfo associated with this certificate. + * @return subject public key info of this certificate + */ + const std::vector& subject_public_key_info() const; + + /** + * Return the algorithm identifier of the public key + */ + const AlgorithmIdentifier& subject_public_key_algo() const; + + /** + * Get the bit string of the public key associated with this certificate + * @return public key bits + */ + const std::vector& subject_public_key_bitstring() const; + + /** + * Get the SHA-1 bit string of the public key associated with this certificate. + * This is used for OCSP among other protocols. + * This function will throw if SHA-1 is not available. + * @return hash of subject public key of this certificate + */ + const std::vector& subject_public_key_bitstring_sha1() const; + + /** + * Get the certificate's issuer distinguished name (DN). + * @return issuer DN of this certificate + */ + const X509_DN& issuer_dn() const; + + /** + * Get the certificate's subject distinguished name (DN). + * @return subject DN of this certificate + */ + const X509_DN& subject_dn() const; + + /** + * Get a value for a specific subject_info parameter name. + * @param name the name of the parameter to look up. Possible names include + * "X509.Certificate.version", "X509.Certificate.serial", + * "X509.Certificate.start", "X509.Certificate.end", + * "X509.Certificate.v2.key_id", "X509.Certificate.public_key", + * "X509v3.BasicConstraints.path_constraint", + * "X509v3.BasicConstraints.is_ca", "X509v3.NameConstraints", + * "X509v3.ExtendedKeyUsage", "X509v3.CertificatePolicies", + * "X509v3.SubjectKeyIdentifier", "X509.Certificate.serial", + * "X520.CommonName", "X520.Organization", "X520.Country", + * "RFC822" (Email in SAN) or "PKCS9.EmailAddress" (Email in DN). + * @return value(s) of the specified parameter + */ + std::vector subject_info(const std::string& name) const; + + /** + * Get a value for a specific subject_info parameter name. + * @param name the name of the parameter to look up. Possible names are + * "X509.Certificate.v2.key_id" or "X509v3.AuthorityKeyIdentifier". + * @return value(s) of the specified parameter + */ + std::vector issuer_info(const std::string& name) const; + + /** + * Raw issuer DN bits + */ + const std::vector& raw_issuer_dn() const; + + /** + * SHA-256 of Raw issuer DN + */ + std::vector raw_issuer_dn_sha256() const; + + /** + * Raw subject DN + */ + const std::vector& raw_subject_dn() const; + + /** + * SHA-256 of Raw subject DN + */ + std::vector raw_subject_dn_sha256() const; + + /** + * Get the notBefore of the certificate as a string + * @return notBefore of the certificate + */ + std::string BOTAN_DEPRECATED("Use not_before().to_string()") start_time() const + { + return not_before().to_string(); + } + + /** + * Get the notAfter of the certificate as a string + * @return notAfter of the certificate + */ + std::string BOTAN_DEPRECATED("Use not_after().to_string()") end_time() const + { + return not_after().to_string(); + } + + /** + * Get the notBefore of the certificate as X509_Time + * @return notBefore of the certificate + */ + const X509_Time& not_before() const; + + /** + * Get the notAfter of the certificate as X509_Time + * @return notAfter of the certificate + */ + const X509_Time& not_after() const; + + /** + * Get the X509 version of this certificate object. + * @return X509 version + */ + uint32_t x509_version() const; + + /** + * Get the serial number of this certificate. + * @return certificates serial number + */ + const std::vector& serial_number() const; + + /** + * Get the serial number's sign + * @return 1 iff the serial is negative. + */ + bool is_serial_negative() const; + + /** + * Get the DER encoded AuthorityKeyIdentifier of this certificate. + * @return DER encoded AuthorityKeyIdentifier + */ + const std::vector& authority_key_id() const; + + /** + * Get the DER encoded SubjectKeyIdentifier of this certificate. + * @return DER encoded SubjectKeyIdentifier + */ + const std::vector& subject_key_id() const; + + /** + * Check whether this certificate is self signed. + * If the DN issuer and subject agree, + * @return true if this certificate is self signed + */ + bool is_self_signed() const; + + /** + * Check whether this certificate is a CA certificate. + * @return true if this certificate is a CA certificate + */ + bool is_CA_cert() const; + + /** + * Returns true if the specified @param usage is set in the key usage extension + * or if no key usage constraints are set at all. + * To check if a certain key constraint is set in the certificate + * use @see X509_Certificate#has_constraints. + */ + bool allowed_usage(Key_Constraints usage) const; + + /** + * Returns true if the specified @param usage is set in the extended key usage extension + * or if no extended key usage constraints are set at all. + * To check if a certain extended key constraint is set in the certificate + * use @see X509_Certificate#has_ex_constraint. + */ + bool allowed_extended_usage(const std::string& usage) const; + + /** + * Returns true if the specified usage is set in the extended key usage extension, + * or if no extended key usage constraints are set at all. + * To check if a certain extended key constraint is set in the certificate + * use @see X509_Certificate#has_ex_constraint. + */ + bool allowed_extended_usage(const OID& usage) const; + + /** + * Returns true if the required key and extended key constraints are set in the certificate + * for the specified @param usage or if no key constraints are set in both the key usage + * and extended key usage extension. + */ + bool allowed_usage(Usage_Type usage) const; + + /** + * Returns true if the specified @param constraints are included in the key + * usage extension. + */ + bool has_constraints(Key_Constraints constraints) const; + + /** + * Returns true if and only if @param ex_constraint (referring to an + * extended key constraint, eg "PKIX.ServerAuth") is included in the + * extended key extension. + */ + bool BOTAN_DEPRECATED("Use version taking an OID") + has_ex_constraint(const std::string& ex_constraint) const; + + /** + * Returns true if and only if OID @param ex_constraint is + * included in the extended key extension. + */ + bool has_ex_constraint(const OID& ex_constraint) const; + + /** + * Get the path limit as defined in the BasicConstraints extension of + * this certificate. + * @return path limit + */ + uint32_t path_limit() const; + + /** + * Check whenever a given X509 Extension is marked critical in this + * certificate. + */ + bool is_critical(const std::string& ex_name) const; + + /** + * Get the key constraints as defined in the KeyUsage extension of this + * certificate. + * @return key constraints + */ + Key_Constraints constraints() const; + + /** + * Get the key constraints as defined in the ExtendedKeyUsage + * extension of this certificate. + * @return key constraints + */ + std::vector + BOTAN_DEPRECATED("Use extended_key_usage") ex_constraints() const; + + /** + * Get the key usage as defined in the ExtendedKeyUsage extension + * of this certificate, or else an empty vector. + * @return key usage + */ + const std::vector& extended_key_usage() const; + + /** + * Get the name constraints as defined in the NameConstraints + * extension of this certificate. + * @return name constraints + */ + const NameConstraints& name_constraints() const; + + /** + * Get the policies as defined in the CertificatePolicies extension + * of this certificate. + * @return certificate policies + */ + std::vector BOTAN_DEPRECATED("Use certificate_policy_oids") policies() const; + + const std::vector& certificate_policy_oids() const; + + /** + * Get all extensions of this certificate. + * @return certificate extensions + */ + const Extensions& v3_extensions() const; + + /** + * Return the v2 issuer key ID. v2 key IDs are almost never used, + * instead see v3_subject_key_id. + */ + const std::vector& v2_issuer_key_id() const; + + /** + * Return the v2 subject key ID. v2 key IDs are almost never used, + * instead see v3_subject_key_id. + */ + const std::vector& v2_subject_key_id() const; + + /** + * Return the subject alternative names (DNS, IP, ...) + */ + const AlternativeName& subject_alt_name() const; + + /** + * Return the issuer alternative names (DNS, IP, ...) + */ + const AlternativeName& issuer_alt_name() const; + + /** + * Return the listed address of an OCSP responder, or empty if not set + */ + std::string ocsp_responder() const; + + /** + * Return the listed addresses of ca issuers, or empty if not set + */ + std::vector ca_issuers() const; + + /** + * Return the CRL distribution point, or empty if not set + */ + std::string crl_distribution_point() const; + + /** + * @return a free-form string describing the certificate + */ + std::string to_string() const; + + /** + * @return a fingerprint of the certificate + * @param hash_name hash function used to calculate the fingerprint + */ + std::string fingerprint(const std::string& hash_name = "SHA-1") const; + + /** + * Check if a certain DNS name matches up with the information in + * the cert + * @param name DNS name to match + */ + bool matches_dns_name(const std::string& name) const; + + /** + * Check to certificates for equality. + * @return true both certificates are (binary) equal + */ + bool operator==(const X509_Certificate& other) const; + + /** + * Impose an arbitrary (but consistent) ordering, eg to allow sorting + * a container of certificate objects. + * @return true if this is less than other by some unspecified criteria + */ + bool operator<(const X509_Certificate& other) const; + + /** + * Create a certificate from a data source providing the DER or + * PEM encoded certificate. + * @param source the data source + */ + explicit X509_Certificate(DataSource& source); + +#if defined(BOTAN_TARGET_OS_HAS_FILESYSTEM) + /** + * Create a certificate from a file containing the DER or PEM + * encoded certificate. + * @param filename the name of the certificate file + */ + explicit X509_Certificate(const std::string& filename); +#endif + + /** + * Create a certificate from a buffer + * @param in the buffer containing the DER-encoded certificate + */ + explicit X509_Certificate(const std::vector& in); + + /** + * Create a certificate from a buffer + * @param data the buffer containing the DER-encoded certificate + * @param length length of data in bytes + */ + X509_Certificate(const uint8_t data[], size_t length); + + /** + * Create an uninitialized certificate object. Any attempts to + * access this object will throw an exception. + */ + X509_Certificate() = default; + + X509_Certificate(const X509_Certificate& other) = default; + + X509_Certificate& operator=(const X509_Certificate& other) = default; + + private: + std::string PEM_label() const override; + + std::vector alternate_PEM_labels() const override; + + void force_decode() override; + + const X509_Certificate_Data& data() const; + + std::shared_ptr m_data; + }; + +/** +* Check two certificates for inequality +* @param cert1 The first certificate +* @param cert2 The second certificate +* @return true if the arguments represent different certificates, +* false if they are binary identical +*/ +BOTAN_PUBLIC_API(2,0) bool operator!=(const X509_Certificate& cert1, const X509_Certificate& cert2); + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/x509/x509opt.cpp b/src/libs/3rdparty/botan/src/lib/x509/x509opt.cpp new file mode 100644 index 0000000000..e31ead91f9 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/x509/x509opt.cpp @@ -0,0 +1,101 @@ +/* +* X.509 Certificate Options +* (C) 1999-2007 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include + +namespace Botan { + +/* +* Set when the certificate should become valid +*/ +void X509_Cert_Options::not_before(const std::string& time_string) + { + start = X509_Time(time_string, ASN1_Tag::UTC_OR_GENERALIZED_TIME); + } + +/* +* Set when the certificate should expire +*/ +void X509_Cert_Options::not_after(const std::string& time_string) + { + end = X509_Time(time_string, ASN1_Tag::UTC_OR_GENERALIZED_TIME); + } + +/* +* Set key constraint information +*/ +void X509_Cert_Options::add_constraints(Key_Constraints usage) + { + constraints = usage; + } + +/* +* Set key constraint information +*/ +void X509_Cert_Options::add_ex_constraint(const OID& oid) + { + ex_constraints.push_back(oid); + } + +/* +* Set key constraint information +*/ +void X509_Cert_Options::add_ex_constraint(const std::string& oid_str) + { + ex_constraints.push_back(OIDS::lookup(oid_str)); + } + +/* +* Mark this certificate for CA usage +*/ +void X509_Cert_Options::CA_key(size_t limit) + { + is_CA = true; + path_limit = limit; + } + +void X509_Cert_Options::set_padding_scheme(const std::string& scheme) + { + padding_scheme = scheme; + } + +/* +* Initialize the certificate options +*/ +X509_Cert_Options::X509_Cert_Options(const std::string& initial_opts, + uint32_t expiration_time) + { + is_CA = false; + path_limit = 0; + constraints = NO_CONSTRAINTS; + // use default for chosen algorithm + padding_scheme = ""; + + auto now = std::chrono::system_clock::now(); + + start = X509_Time(now); + end = X509_Time(now + std::chrono::seconds(expiration_time)); + + if(initial_opts.empty()) + return; + + std::vector parsed = split_on(initial_opts, '/'); + + if(parsed.size() > 4) + throw Invalid_Argument("X.509 cert options: Too many names: " + + initial_opts); + + if(parsed.size() >= 1) common_name = parsed[0]; + if(parsed.size() >= 2) country = parsed[1]; + if(parsed.size() >= 3) organization = parsed[2]; + if(parsed.size() == 4) org_unit = parsed[3]; + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/x509/x509path.cpp b/src/libs/3rdparty/botan/src/lib/x509/x509path.cpp new file mode 100644 index 0000000000..e73fe12b60 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/x509/x509path.cpp @@ -0,0 +1,1070 @@ +/* +* X.509 Certificate Path Validation +* (C) 2010,2011,2012,2014,2016 Jack Lloyd +* (C) 2017 Fabian Weissberg, Rohde & Schwarz Cybersecurity +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(BOTAN_HAS_ONLINE_REVOCATION_CHECKS) + #include + #include +#endif + +namespace Botan { + +/* +* PKIX path validation +*/ +CertificatePathStatusCodes +PKIX::check_chain(const std::vector>& cert_path, + std::chrono::system_clock::time_point ref_time, + const std::string& hostname, + Usage_Type usage, + size_t min_signature_algo_strength, + const std::set& trusted_hashes) + { + if(cert_path.empty()) + throw Invalid_Argument("PKIX::check_chain cert_path empty"); + + const bool self_signed_ee_cert = (cert_path.size() == 1); + + X509_Time validation_time(ref_time); + + CertificatePathStatusCodes cert_status(cert_path.size()); + + if(!hostname.empty() && !cert_path[0]->matches_dns_name(hostname)) + cert_status[0].insert(Certificate_Status_Code::CERT_NAME_NOMATCH); + + if(!cert_path[0]->allowed_usage(usage)) + cert_status[0].insert(Certificate_Status_Code::INVALID_USAGE); + + if(cert_path[0]->is_CA_cert() == false && + cert_path[0]->has_constraints(KEY_CERT_SIGN)) + { + /* + "If the keyCertSign bit is asserted, then the cA bit in the + basic constraints extension (Section 4.2.1.9) MUST also be + asserted." - RFC 5280 + + We don't bother doing this check on the rest of the path since they + must have the cA bit asserted or the validation will fail anyway. + */ + cert_status[0].insert(Certificate_Status_Code::INVALID_USAGE); + } + + for(size_t i = 0; i != cert_path.size(); ++i) + { + std::set& status = cert_status.at(i); + + const bool at_self_signed_root = (i == cert_path.size() - 1); + + const std::shared_ptr& subject = cert_path[i]; + + const std::shared_ptr& issuer = cert_path[at_self_signed_root ? (i) : (i + 1)]; + + if(at_self_signed_root && (issuer->is_self_signed() == false)) + { + status.insert(Certificate_Status_Code::CHAIN_LACKS_TRUST_ROOT); + } + + if(subject->issuer_dn() != issuer->subject_dn()) + { + status.insert(Certificate_Status_Code::CHAIN_NAME_MISMATCH); + } + + // Check the serial number + if(subject->is_serial_negative()) + { + status.insert(Certificate_Status_Code::CERT_SERIAL_NEGATIVE); + } + + // Check the subject's DN components' length + + for(const auto& dn_pair : subject->subject_dn().dn_info()) + { + const size_t dn_ub = X509_DN::lookup_ub(dn_pair.first); + // dn_pair = + if(dn_ub > 0 && dn_pair.second.size() > dn_ub) + { + status.insert(Certificate_Status_Code::DN_TOO_LONG); + } + } + + // Check all certs for valid time range + if(validation_time < subject->not_before()) + status.insert(Certificate_Status_Code::CERT_NOT_YET_VALID); + + if(validation_time > subject->not_after()) + status.insert(Certificate_Status_Code::CERT_HAS_EXPIRED); + + // Check issuer constraints + if(!issuer->is_CA_cert() && !self_signed_ee_cert) + status.insert(Certificate_Status_Code::CA_CERT_NOT_FOR_CERT_ISSUER); + + std::unique_ptr issuer_key(issuer->subject_public_key()); + + // Check the signature algorithm + if(OIDS::lookup(subject->signature_algorithm().oid).empty()) + { + status.insert(Certificate_Status_Code::SIGNATURE_ALGO_UNKNOWN); + } + // only perform the following checks if the signature algorithm is known + else + { + if(!issuer_key) + { + status.insert(Certificate_Status_Code::CERT_PUBKEY_INVALID); + } + else + { + const Certificate_Status_Code sig_status = subject->verify_signature(*issuer_key); + + if(sig_status != Certificate_Status_Code::VERIFIED) + status.insert(sig_status); + + if(issuer_key->estimated_strength() < min_signature_algo_strength) + status.insert(Certificate_Status_Code::SIGNATURE_METHOD_TOO_WEAK); + } + + // Ignore untrusted hashes on self-signed roots + if(trusted_hashes.size() > 0 && !at_self_signed_root) + { + if(trusted_hashes.count(subject->hash_used_for_signature()) == 0) + status.insert(Certificate_Status_Code::UNTRUSTED_HASH); + } + } + + // Check cert extensions + Extensions extensions = subject->v3_extensions(); + const auto& extensions_vec = extensions.extensions(); + if(subject->x509_version() < 3 && !extensions_vec.empty()) + { + status.insert(Certificate_Status_Code::EXT_IN_V1_V2_CERT); + } + for(auto& extension : extensions_vec) + { + extension.first->validate(*subject, *issuer, cert_path, cert_status, i); + } + if(extensions.extensions().size() != extensions.get_extension_oids().size()) + { + status.insert(Certificate_Status_Code::DUPLICATE_CERT_EXTENSION); + } + } + + // path len check + size_t max_path_length = cert_path.size(); + for(size_t i = cert_path.size() - 1; i > 0 ; --i) + { + std::set& status = cert_status.at(i); + const std::shared_ptr& subject = cert_path[i]; + + /* + * If the certificate was not self-issued, verify that max_path_length is + * greater than zero and decrement max_path_length by 1. + */ + if(subject->subject_dn() != subject->issuer_dn()) + { + if(max_path_length > 0) + { + --max_path_length; + } + else + { + status.insert(Certificate_Status_Code::CERT_CHAIN_TOO_LONG); + } + } + + /* + * If pathLenConstraint is present in the certificate and is less than max_path_length, + * set max_path_length to the value of pathLenConstraint. + */ + if(subject->path_limit() != Cert_Extension::NO_CERT_PATH_LIMIT && subject->path_limit() < max_path_length) + { + max_path_length = subject->path_limit(); + } + } + + return cert_status; + } + +CertificatePathStatusCodes +PKIX::check_ocsp(const std::vector>& cert_path, + const std::vector>& ocsp_responses, + const std::vector& trusted_certstores, + std::chrono::system_clock::time_point ref_time) + { + if(cert_path.empty()) + throw Invalid_Argument("PKIX::check_ocsp cert_path empty"); + + CertificatePathStatusCodes cert_status(cert_path.size() - 1); + + for(size_t i = 0; i != cert_path.size() - 1; ++i) + { + std::set& status = cert_status.at(i); + + std::shared_ptr subject = cert_path.at(i); + std::shared_ptr ca = cert_path.at(i+1); + + if(i < ocsp_responses.size() && (ocsp_responses.at(i) != nullptr)) + { + try + { + Certificate_Status_Code ocsp_signature_status = ocsp_responses.at(i)->check_signature(trusted_certstores, cert_path); + + if(ocsp_signature_status == Certificate_Status_Code::OCSP_SIGNATURE_OK) + { + // Signature ok, so check the claimed status + Certificate_Status_Code ocsp_status = ocsp_responses.at(i)->status_for(*ca, *subject, ref_time); + status.insert(ocsp_status); + } + else + { + // Some signature problem + status.insert(ocsp_signature_status); + } + } + catch(Exception&) + { + status.insert(Certificate_Status_Code::OCSP_RESPONSE_INVALID); + } + } + } + + while(cert_status.size() > 0 && cert_status.back().empty()) + cert_status.pop_back(); + + return cert_status; + } + +CertificatePathStatusCodes +PKIX::check_crl(const std::vector>& cert_path, + const std::vector>& crls, + std::chrono::system_clock::time_point ref_time) + { + if(cert_path.empty()) + throw Invalid_Argument("PKIX::check_crl cert_path empty"); + + CertificatePathStatusCodes cert_status(cert_path.size()); + const X509_Time validation_time(ref_time); + + for(size_t i = 0; i != cert_path.size() - 1; ++i) + { + std::set& status = cert_status.at(i); + + if(i < crls.size() && crls.at(i)) + { + std::shared_ptr subject = cert_path.at(i); + std::shared_ptr ca = cert_path.at(i+1); + + if(!ca->allowed_usage(CRL_SIGN)) + status.insert(Certificate_Status_Code::CA_CERT_NOT_FOR_CRL_ISSUER); + + if(validation_time < crls[i]->this_update()) + status.insert(Certificate_Status_Code::CRL_NOT_YET_VALID); + + if(validation_time > crls[i]->next_update()) + status.insert(Certificate_Status_Code::CRL_HAS_EXPIRED); + + if(crls[i]->check_signature(ca->subject_public_key()) == false) + status.insert(Certificate_Status_Code::CRL_BAD_SIGNATURE); + + status.insert(Certificate_Status_Code::VALID_CRL_CHECKED); + + if(crls[i]->is_revoked(*subject)) + status.insert(Certificate_Status_Code::CERT_IS_REVOKED); + + std::string dp = subject->crl_distribution_point(); + if(!dp.empty()) + { + if(dp != crls[i]->crl_issuing_distribution_point()) + { + status.insert(Certificate_Status_Code::NO_MATCHING_CRLDP); + } + } + + for(const auto& extension : crls[i]->extensions().extensions()) + { + // is the extension critical and unknown? + if(extension.second && OIDS::lookup(extension.first->oid_of()) == "") + { + /* NIST Certificate Path Valiadation Testing document: "When an implementation does not recognize a critical extension in the + * crlExtensions field, it shall assume that identified certificates have been revoked and are no longer valid" + */ + status.insert(Certificate_Status_Code::CERT_IS_REVOKED); + } + } + + } + } + + while(cert_status.size() > 0 && cert_status.back().empty()) + cert_status.pop_back(); + + return cert_status; + } + +CertificatePathStatusCodes +PKIX::check_crl(const std::vector>& cert_path, + const std::vector& certstores, + std::chrono::system_clock::time_point ref_time) + { + if(cert_path.empty()) + throw Invalid_Argument("PKIX::check_crl cert_path empty"); + + if(certstores.empty()) + throw Invalid_Argument("PKIX::check_crl certstores empty"); + + std::vector> crls(cert_path.size()); + + for(size_t i = 0; i != cert_path.size(); ++i) + { + BOTAN_ASSERT_NONNULL(cert_path[i]); + for(size_t c = 0; c != certstores.size(); ++c) + { + crls[i] = certstores[c]->find_crl_for(*cert_path[i]); + if(crls[i]) + break; + } + } + + return PKIX::check_crl(cert_path, crls, ref_time); + } + +#if defined(BOTAN_HAS_ONLINE_REVOCATION_CHECKS) + +CertificatePathStatusCodes +PKIX::check_ocsp_online(const std::vector>& cert_path, + const std::vector& trusted_certstores, + std::chrono::system_clock::time_point ref_time, + std::chrono::milliseconds timeout, + bool ocsp_check_intermediate_CAs) + { + if(cert_path.empty()) + throw Invalid_Argument("PKIX::check_ocsp_online cert_path empty"); + + std::vector>> ocsp_response_futures; + + size_t to_ocsp = 1; + + if(ocsp_check_intermediate_CAs) + to_ocsp = cert_path.size() - 1; + if(cert_path.size() == 1) + to_ocsp = 0; + + for(size_t i = 0; i < to_ocsp; ++i) + { + const std::shared_ptr& subject = cert_path.at(i); + const std::shared_ptr& issuer = cert_path.at(i+1); + + if(subject->ocsp_responder() == "") + { + ocsp_response_futures.emplace_back(std::async(std::launch::deferred, [&]() -> std::shared_ptr { + return std::make_shared(Certificate_Status_Code::OSCP_NO_REVOCATION_URL); + })); + } + else + { + ocsp_response_futures.emplace_back(std::async(std::launch::async, [&]() -> std::shared_ptr { + OCSP::Request req(*issuer, BigInt::decode(subject->serial_number())); + + HTTP::Response http; + try + { + http = HTTP::POST_sync(subject->ocsp_responder(), + "application/ocsp-request", + req.BER_encode(), + /*redirects*/1, + timeout); + } + catch(std::exception& e) + { + // log e.what() ? + } + if (http.status_code() != 200) + return std::make_shared(Certificate_Status_Code::OSCP_SERVER_NOT_AVAILABLE); + // Check the MIME type? + + return std::make_shared(http.body()); + })); + } + } + + std::vector> ocsp_responses; + + for(size_t i = 0; i < ocsp_response_futures.size(); ++i) + { + ocsp_responses.push_back(ocsp_response_futures[i].get()); + } + + return PKIX::check_ocsp(cert_path, ocsp_responses, trusted_certstores, ref_time); + } + +CertificatePathStatusCodes +PKIX::check_crl_online(const std::vector>& cert_path, + const std::vector& certstores, + Certificate_Store_In_Memory* crl_store, + std::chrono::system_clock::time_point ref_time, + std::chrono::milliseconds timeout) + { + if(cert_path.empty()) + throw Invalid_Argument("PKIX::check_crl_online cert_path empty"); + if(certstores.empty()) + throw Invalid_Argument("PKIX::check_crl_online certstores empty"); + + std::vector>> future_crls; + std::vector> crls(cert_path.size()); + + for(size_t i = 0; i != cert_path.size(); ++i) + { + const std::shared_ptr& cert = cert_path.at(i); + for(size_t c = 0; c != certstores.size(); ++c) + { + crls[i] = certstores[c]->find_crl_for(*cert); + if(crls[i]) + break; + } + + // TODO: check if CRL is expired and re-request? + + // Only request if we don't already have a CRL + if(crls[i]) + { + /* + We already have a CRL, so just insert this empty one to hold a place in the vector + so that indexes match up + */ + future_crls.emplace_back(std::future>()); + } + else if(cert->crl_distribution_point() == "") + { + // Avoid creating a thread for this case + future_crls.emplace_back(std::async(std::launch::deferred, [&]() -> std::shared_ptr { + throw Exception("No CRL distribution point for this certificate"); + })); + } + else + { + future_crls.emplace_back(std::async(std::launch::async, [&]() -> std::shared_ptr { + auto http = HTTP::GET_sync(cert->crl_distribution_point(), + /*redirects*/ 1, timeout); + + http.throw_unless_ok(); + // check the mime type? + return std::make_shared(http.body()); + })); + } + } + + for(size_t i = 0; i != future_crls.size(); ++i) + { + if(future_crls[i].valid()) + { + try + { + crls[i] = future_crls[i].get(); + } + catch(std::exception& e) + { + // crls[i] left null + // todo: log exception e.what() ? + } + } + } + + const CertificatePathStatusCodes crl_status = PKIX::check_crl(cert_path, crls, ref_time); + + if(crl_store) + { + for(size_t i = 0; i != crl_status.size(); ++i) + { + if(crl_status[i].count(Certificate_Status_Code::VALID_CRL_CHECKED)) + { + // better be non-null, we supposedly validated it + BOTAN_ASSERT_NONNULL(crls[i]); + crl_store->add_crl(crls[i]); + } + } + } + + return crl_status; + } + +#endif + +Certificate_Status_Code +PKIX::build_certificate_path(std::vector>& cert_path, + const std::vector& trusted_certstores, + const std::shared_ptr& end_entity, + const std::vector>& end_entity_extra) + { + if(end_entity->is_self_signed()) + { + return Certificate_Status_Code::CANNOT_ESTABLISH_TRUST; + } + + /* + * This is an inelegant but functional way of preventing path loops + * (where C1 -> C2 -> C3 -> C1). We store a set of all the certificate + * fingerprints in the path. If there is a duplicate, we error out. + * TODO: save fingerprints in result struct? Maybe useful for blacklists, etc. + */ + std::set certs_seen; + + cert_path.push_back(end_entity); + certs_seen.insert(end_entity->fingerprint("SHA-256")); + + Certificate_Store_In_Memory ee_extras; + for(size_t i = 0; i != end_entity_extra.size(); ++i) + ee_extras.add_certificate(end_entity_extra[i]); + + // iterate until we reach a root or cannot find the issuer + for(;;) + { + const X509_Certificate& last = *cert_path.back(); + const X509_DN issuer_dn = last.issuer_dn(); + const std::vector auth_key_id = last.authority_key_id(); + + std::shared_ptr issuer; + bool trusted_issuer = false; + + for(Certificate_Store* store : trusted_certstores) + { + issuer = store->find_cert(issuer_dn, auth_key_id); + if(issuer) + { + trusted_issuer = true; + break; + } + } + + if(!issuer) + { + // fall back to searching supplemental certs + issuer = ee_extras.find_cert(issuer_dn, auth_key_id); + } + + if(!issuer) + return Certificate_Status_Code::CERT_ISSUER_NOT_FOUND; + + const std::string fprint = issuer->fingerprint("SHA-256"); + + if(certs_seen.count(fprint) > 0) // already seen? + { + return Certificate_Status_Code::CERT_CHAIN_LOOP; + } + + certs_seen.insert(fprint); + cert_path.push_back(issuer); + + if(issuer->is_self_signed()) + { + if(trusted_issuer) + { + return Certificate_Status_Code::OK; + } + else + { + return Certificate_Status_Code::CANNOT_ESTABLISH_TRUST; + } + } + } + } + +/** + * utilities for PKIX::build_all_certificate_paths + */ +namespace +{ +// +using cert_maybe_trusted = std::pair,bool>; +} + +/** + * Build all possible certificate paths from the end certificate to self-signed trusted roots. + * + * All potentially valid paths are put into the cert_paths vector. If no potentially valid paths are found, + * one of the encountered errors is returned arbitrarily. + * + * todo add a path building function that returns detailed information on errors encountered while building + * the potentially numerous path candidates. + * + * Basically, a DFS is performed starting from the end certificate. A stack (vector) serves to control the DFS. + * At the beginning of each iteration, a pair is popped from the stack that contains (1) the next certificate + * to add to the path (2) a bool that indicates if the certificate is part of a trusted certstore. Ideally, we + * follow the unique issuer of the current certificate until a trusted root is reached. However, the issuer DN + + * authority key id need not be unique among the certificates used for building the path. In such a case, + * we consider all the matching issuers by pushing on the stack for each of them. + * + */ +Certificate_Status_Code +PKIX::build_all_certificate_paths(std::vector>>& cert_paths_out, + const std::vector& trusted_certstores, + const std::shared_ptr& end_entity, + const std::vector>& end_entity_extra) + { + if(!cert_paths_out.empty()) + { + throw Invalid_Argument("PKIX::build_all_certificate_paths: cert_paths_out must be empty"); + } + + if(end_entity->is_self_signed()) + { + return Certificate_Status_Code::CANNOT_ESTABLISH_TRUST; + } + + /* + * Pile up error messages + */ + std::vector stats; + + Certificate_Store_In_Memory ee_extras; + for(size_t i = 0; i != end_entity_extra.size(); ++i) + { + ee_extras.add_certificate(end_entity_extra[i]); + } + + /* + * This is an inelegant but functional way of preventing path loops + * (where C1 -> C2 -> C3 -> C1). We store a set of all the certificate + * fingerprints in the path. If there is a duplicate, we error out. + * TODO: save fingerprints in result struct? Maybe useful for blacklists, etc. + */ + std::set certs_seen; + + // new certs are added and removed from the path during the DFS + // it is copied into cert_paths_out when we encounter a trusted root + std::vector> path_so_far; + + // todo can we assume that the end certificate is not trusted? + std::vector stack = { {end_entity, false} }; + + while(!stack.empty()) + { + // found a deletion marker that guides the DFS, backtracing + if(stack.back().first == nullptr) + { + stack.pop_back(); + std::string fprint = path_so_far.back()->fingerprint("SHA-256"); + certs_seen.erase(fprint); + path_so_far.pop_back(); + } + // process next cert on the path + else + { + std::shared_ptr last = stack.back().first; + bool trusted = stack.back().second; + stack.pop_back(); + + // certificate already seen? + const std::string fprint = last->fingerprint("SHA-256"); + if(certs_seen.count(fprint) == 1) + { + stats.push_back(Certificate_Status_Code::CERT_CHAIN_LOOP); + // the current path ended in a loop + continue; + } + + // the current path ends here + if(last->is_self_signed()) + { + // found a trust anchor + if(trusted) + { + cert_paths_out.push_back(path_so_far); + cert_paths_out.back().push_back(last); + + continue; + } + // found an untrustworthy root + else + { + stats.push_back(Certificate_Status_Code::CANNOT_ESTABLISH_TRUST); + continue; + } + } + + const X509_DN issuer_dn = last->issuer_dn(); + const std::vector auth_key_id = last->authority_key_id(); + + // search for trusted issuers + std::vector> trusted_issuers; + for(Certificate_Store* store : trusted_certstores) + { + auto new_issuers = store->find_all_certs(issuer_dn, auth_key_id); + trusted_issuers.insert(trusted_issuers.end(), new_issuers.begin(), new_issuers.end()); + } + + // search the supplemental certs + std::vector> misc_issuers = + ee_extras.find_all_certs(issuer_dn, auth_key_id); + + // if we could not find any issuers, the current path ends here + if(trusted_issuers.size() + misc_issuers.size() == 0) + { + stats.push_back(Certificate_Status_Code::CERT_ISSUER_NOT_FOUND); + continue; + } + + // push the latest certificate onto the path_so_far + path_so_far.push_back(last); + certs_seen.emplace(fprint); + + // push a deletion marker on the stack for backtracing later + stack.push_back({std::shared_ptr(nullptr),false}); + + for(const auto trusted_cert : trusted_issuers) + { + stack.push_back({trusted_cert,true}); + } + + for(const auto misc : misc_issuers) + { + stack.push_back({misc,false}); + } + } + } + + // could not construct any potentially valid path + if(cert_paths_out.empty()) + { + if(stats.empty()) + throw Exception("X509 path building failed for unknown reasons"); + else + // arbitrarily return the first error + return stats[0]; + } + else + { + return Certificate_Status_Code::OK; + } + } + + +void PKIX::merge_revocation_status(CertificatePathStatusCodes& chain_status, + const CertificatePathStatusCodes& crl, + const CertificatePathStatusCodes& ocsp, + bool require_rev_on_end_entity, + bool require_rev_on_intermediates) + { + if(chain_status.empty()) + throw Invalid_Argument("PKIX::merge_revocation_status chain_status was empty"); + + for(size_t i = 0; i != chain_status.size() - 1; ++i) + { + bool had_crl = false, had_ocsp = false; + + if(i < crl.size() && crl[i].size() > 0) + { + for(auto&& code : crl[i]) + { + if(code == Certificate_Status_Code::VALID_CRL_CHECKED) + { + had_crl = true; + } + chain_status[i].insert(code); + } + } + + if(i < ocsp.size() && ocsp[i].size() > 0) + { + for(auto&& code : ocsp[i]) + { + if(code == Certificate_Status_Code::OCSP_RESPONSE_GOOD || + code == Certificate_Status_Code::OSCP_NO_REVOCATION_URL || // softfail + code == Certificate_Status_Code::OSCP_SERVER_NOT_AVAILABLE) // softfail + { + had_ocsp = true; + } + + chain_status[i].insert(code); + } + } + + if(had_crl == false && had_ocsp == false) + { + if((require_rev_on_end_entity && i == 0) || + (require_rev_on_intermediates && i > 0)) + { + chain_status[i].insert(Certificate_Status_Code::NO_REVOCATION_DATA); + } + } + } + } + +Certificate_Status_Code PKIX::overall_status(const CertificatePathStatusCodes& cert_status) + { + if(cert_status.empty()) + throw Invalid_Argument("PKIX::overall_status empty cert status"); + + Certificate_Status_Code overall_status = Certificate_Status_Code::OK; + + // take the "worst" error as overall + for(const std::set& s : cert_status) + { + if(!s.empty()) + { + auto worst = *s.rbegin(); + // Leave informative OCSP/CRL confirmations on cert-level status only + if(worst >= Certificate_Status_Code::FIRST_ERROR_STATUS && worst > overall_status) + { + overall_status = worst; + } + } + } + return overall_status; + } + +Path_Validation_Result x509_path_validate( + const std::vector& end_certs, + const Path_Validation_Restrictions& restrictions, + const std::vector& trusted_roots, + const std::string& hostname, + Usage_Type usage, + std::chrono::system_clock::time_point ref_time, + std::chrono::milliseconds ocsp_timeout, + const std::vector>& ocsp_resp) + { + if(end_certs.empty()) + { + throw Invalid_Argument("x509_path_validate called with no subjects"); + } + + std::shared_ptr end_entity(std::make_shared(end_certs[0])); + std::vector> end_entity_extra; + for(size_t i = 1; i < end_certs.size(); ++i) + { + end_entity_extra.push_back(std::make_shared(end_certs[i])); + } + + std::vector>> cert_paths; + Certificate_Status_Code path_building_result = PKIX::build_all_certificate_paths(cert_paths, trusted_roots, end_entity, end_entity_extra); + + // If we cannot successfully build a chain to a trusted self-signed root, stop now + if(path_building_result != Certificate_Status_Code::OK) + { + return Path_Validation_Result(path_building_result); + } + + std::vector error_results; + // Try validating all the potentially valid paths and return the first one to validate properly + for(auto cert_path : cert_paths) + { + CertificatePathStatusCodes status = + PKIX::check_chain(cert_path, ref_time, + hostname, usage, + restrictions.minimum_key_strength(), + restrictions.trusted_hashes()); + + CertificatePathStatusCodes crl_status = + PKIX::check_crl(cert_path, trusted_roots, ref_time); + + CertificatePathStatusCodes ocsp_status; + + if(ocsp_resp.size() > 0) + { + ocsp_status = PKIX::check_ocsp(cert_path, ocsp_resp, trusted_roots, ref_time); + } + + if(ocsp_status.empty() && ocsp_timeout != std::chrono::milliseconds(0)) + { +#if defined(BOTAN_TARGET_OS_HAS_THREADS) && defined(BOTAN_HAS_HTTP_UTIL) + ocsp_status = PKIX::check_ocsp_online(cert_path, trusted_roots, ref_time, + ocsp_timeout, restrictions.ocsp_all_intermediates()); +#else + ocsp_status.resize(1); + ocsp_status[0].insert(Certificate_Status_Code::OCSP_NO_HTTP); +#endif + } + + PKIX::merge_revocation_status(status, crl_status, ocsp_status, + restrictions.require_revocation_information(), + restrictions.ocsp_all_intermediates()); + + Path_Validation_Result pvd(status, std::move(cert_path)); + if(pvd.successful_validation()) + { + return pvd; + } + else + { + error_results.push_back(std::move(pvd)); + } + } + return error_results[0]; + } + +Path_Validation_Result x509_path_validate( + const X509_Certificate& end_cert, + const Path_Validation_Restrictions& restrictions, + const std::vector& trusted_roots, + const std::string& hostname, + Usage_Type usage, + std::chrono::system_clock::time_point when, + std::chrono::milliseconds ocsp_timeout, + const std::vector>& ocsp_resp) + { + std::vector certs; + certs.push_back(end_cert); + return x509_path_validate(certs, restrictions, trusted_roots, hostname, usage, when, ocsp_timeout, ocsp_resp); + } + +Path_Validation_Result x509_path_validate( + const std::vector& end_certs, + const Path_Validation_Restrictions& restrictions, + const Certificate_Store& store, + const std::string& hostname, + Usage_Type usage, + std::chrono::system_clock::time_point when, + std::chrono::milliseconds ocsp_timeout, + const std::vector>& ocsp_resp) + { + std::vector trusted_roots; + trusted_roots.push_back(const_cast(&store)); + + return x509_path_validate(end_certs, restrictions, trusted_roots, hostname, usage, when, ocsp_timeout, ocsp_resp); + } + +Path_Validation_Result x509_path_validate( + const X509_Certificate& end_cert, + const Path_Validation_Restrictions& restrictions, + const Certificate_Store& store, + const std::string& hostname, + Usage_Type usage, + std::chrono::system_clock::time_point when, + std::chrono::milliseconds ocsp_timeout, + const std::vector>& ocsp_resp) + { + std::vector certs; + certs.push_back(end_cert); + + std::vector trusted_roots; + trusted_roots.push_back(const_cast(&store)); + + return x509_path_validate(certs, restrictions, trusted_roots, hostname, usage, when, ocsp_timeout, ocsp_resp); + } + +Path_Validation_Restrictions::Path_Validation_Restrictions(bool require_rev, + size_t key_strength, + bool ocsp_intermediates) : + m_require_revocation_information(require_rev), + m_ocsp_all_intermediates(ocsp_intermediates), + m_minimum_key_strength(key_strength) + { + if(key_strength <= 80) + m_trusted_hashes.insert("SHA-160"); + + m_trusted_hashes.insert("SHA-224"); + m_trusted_hashes.insert("SHA-256"); + m_trusted_hashes.insert("SHA-384"); + m_trusted_hashes.insert("SHA-512"); + } + +namespace { +CertificatePathStatusCodes find_warnings(const CertificatePathStatusCodes& all_statuses) + { + CertificatePathStatusCodes warnings; + for(const auto& status_set_i : all_statuses) + { + std::set warning_set_i; + for(const auto& code : status_set_i) + { + if(code >= Certificate_Status_Code::FIRST_WARNING_STATUS && + code < Certificate_Status_Code::FIRST_ERROR_STATUS) + { + warning_set_i.insert(code); + } + } + warnings.push_back(warning_set_i); + } + return warnings; + } +} + +Path_Validation_Result::Path_Validation_Result(CertificatePathStatusCodes status, + std::vector>&& cert_chain) : + m_all_status(status), + m_warnings(find_warnings(m_all_status)), + m_cert_path(cert_chain), + m_overall(PKIX::overall_status(m_all_status)) + { + } + +const X509_Certificate& Path_Validation_Result::trust_root() const + { + if(m_cert_path.empty()) + throw Exception("Path_Validation_Result::trust_root no path set"); + if(result() != Certificate_Status_Code::VERIFIED) + throw Exception("Path_Validation_Result::trust_root meaningless with invalid status"); + + return *m_cert_path[m_cert_path.size()-1]; + } + +std::set Path_Validation_Result::trusted_hashes() const + { + std::set hashes; + for(size_t i = 0; i != m_cert_path.size(); ++i) + hashes.insert(m_cert_path[i]->hash_used_for_signature()); + return hashes; + } + +bool Path_Validation_Result::successful_validation() const + { + return (result() == Certificate_Status_Code::VERIFIED || + result() == Certificate_Status_Code::OCSP_RESPONSE_GOOD || + result() == Certificate_Status_Code::VALID_CRL_CHECKED); + } + +bool Path_Validation_Result::no_warnings() const + { + for(auto status_set_i : m_warnings) + if(!status_set_i.empty()) + return false; + return true; + } + +CertificatePathStatusCodes Path_Validation_Result::warnings() const + { + return m_warnings; + } + +std::string Path_Validation_Result::result_string() const + { + return status_string(result()); + } + +const char* Path_Validation_Result::status_string(Certificate_Status_Code code) + { + if(const char* s = to_string(code)) + return s; + + return "Unknown error"; + } + +std::string Path_Validation_Result::warnings_string() const + { + const std::string sep(", "); + std::string res; + for(size_t i = 0; i < m_warnings.size(); i++) + { + for(auto code : m_warnings[i]) + res += "[" + std::to_string(i) + "] " + status_string(code) + sep; + } + // remove last sep + if(res.size() >= sep.size()) + res = res.substr(0, res.size() - sep.size()); + return res; + } +} diff --git a/src/libs/3rdparty/botan/src/lib/x509/x509path.h b/src/libs/3rdparty/botan/src/lib/x509/x509path.h new file mode 100644 index 0000000000..79ae02a10e --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/x509/x509path.h @@ -0,0 +1,454 @@ +/* +* X.509 Cert Path Validation +* (C) 2010-2011 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_X509_CERT_PATH_VALIDATION_H_ +#define BOTAN_X509_CERT_PATH_VALIDATION_H_ + +#include +#include +#include +#include +#include +#include +#include + +#if defined(BOTAN_TARGET_OS_HAS_THREADS) && defined(BOTAN_HAS_HTTP_UTIL) + #define BOTAN_HAS_ONLINE_REVOCATION_CHECKS +#endif + +namespace Botan { + +/** +* This type represents the validation status of an entire certificate path. +* There is one set of status codes for each certificate in the path. +*/ +typedef std::vector> CertificatePathStatusCodes; + +/** +* Specifies restrictions on the PKIX path validation +*/ +class BOTAN_PUBLIC_API(2,0) Path_Validation_Restrictions final + { + public: + /** + * @param require_rev if true, revocation information is required + + * @param minimum_key_strength is the minimum strength (in terms of + * operations, eg 80 means 2^80) of a signature. Signatures weaker than + * this are rejected. If more than 80, SHA-1 signatures are also + * rejected. If possible use at least setting 110. + * + * 80 bit strength requires 1024 bit RSA + * 110 bit strength requires 2k bit RSA + * 128 bit strength requires ~3k bit RSA or P-256 + * @param ocsp_all_intermediates Make OCSP requests for all CAs as + * well as end entity (if OCSP enabled in path validation request) + */ + Path_Validation_Restrictions(bool require_rev = false, + size_t minimum_key_strength = 110, + bool ocsp_all_intermediates = false); + + /** + * @param require_rev if true, revocation information is required + * @param minimum_key_strength is the minimum strength (in terms of + * operations, eg 80 means 2^80) of a signature. Signatures + * weaker than this are rejected. + * @param ocsp_all_intermediates Make OCSP requests for all CAs as + * well as end entity (if OCSP enabled in path validation request) + * @param trusted_hashes a set of trusted hashes. Any signatures + * created using a hash other than one of these will be + * rejected. + */ + Path_Validation_Restrictions(bool require_rev, + size_t minimum_key_strength, + bool ocsp_all_intermediates, + const std::set& trusted_hashes) : + m_require_revocation_information(require_rev), + m_ocsp_all_intermediates(ocsp_all_intermediates), + m_trusted_hashes(trusted_hashes), + m_minimum_key_strength(minimum_key_strength) {} + + /** + * @return whether revocation information is required + */ + bool require_revocation_information() const + { return m_require_revocation_information; } + + /** + * @return whether all intermediate CAs should also be OCSPed. If false + * then only end entity OCSP is required/requested. + */ + bool ocsp_all_intermediates() const + { return m_ocsp_all_intermediates; } + + /** + * @return trusted signature hash functions + */ + const std::set& trusted_hashes() const + { return m_trusted_hashes; } + + /** + * @return minimum required key strength + */ + size_t minimum_key_strength() const + { return m_minimum_key_strength; } + + private: + bool m_require_revocation_information; + bool m_ocsp_all_intermediates; + std::set m_trusted_hashes; + size_t m_minimum_key_strength; + }; + +/** +* Represents the result of a PKIX path validation +*/ +class BOTAN_PUBLIC_API(2,0) Path_Validation_Result final + { + public: + typedef Certificate_Status_Code Code; + + /** + * @return the set of hash functions you are implicitly + * trusting by trusting this result. + */ + std::set trusted_hashes() const; + + /** + * @return the trust root of the validation if successful + * throws an exception if the validation failed + */ + const X509_Certificate& trust_root() const; + + /** + * @return the full path from subject to trust root + * This path may be empty + */ + const std::vector>& cert_path() const { return m_cert_path; } + + /** + * @return true iff the validation was successful + */ + bool successful_validation() const; + + /** + * @return true iff no warnings occured during validation + */ + bool no_warnings() const; + + /** + * @return overall validation result code + */ + Certificate_Status_Code result() const { return m_overall; } + + /** + * @return a set of status codes for each certificate in the chain + */ + const CertificatePathStatusCodes& all_statuses() const + { return m_all_status; } + + /** + * @return the subset of status codes that are warnings + */ + CertificatePathStatusCodes warnings() const; + + /** + * @return string representation of the validation result + */ + std::string result_string() const; + + /** + * @return string representation of the warnings + */ + std::string warnings_string() const; + + /** + * @param code validation status code + * @return corresponding validation status message + */ + static const char* status_string(Certificate_Status_Code code); + + /** + * Create a Path_Validation_Result + * @param status list of validation status codes + * @param cert_chain the certificate chain that was validated + */ + Path_Validation_Result(CertificatePathStatusCodes status, + std::vector>&& cert_chain); + + /** + * Create a Path_Validation_Result + * @param status validation status code + */ + explicit Path_Validation_Result(Certificate_Status_Code status) : m_overall(status) {} + + private: + CertificatePathStatusCodes m_all_status; + CertificatePathStatusCodes m_warnings; + std::vector> m_cert_path; + Certificate_Status_Code m_overall; + }; + +/** +* PKIX Path Validation +* @param end_certs certificate chain to validate (with end entity certificate in end_certs[0]) +* @param restrictions path validation restrictions +* @param trusted_roots list of certificate stores that contain trusted certificates +* @param hostname if not empty, compared against the DNS name in end_certs[0] +* @param usage if not set to UNSPECIFIED, compared against the key usage in end_certs[0] +* @param validation_time what reference time to use for validation +* @param ocsp_timeout timeout for OCSP operations, 0 disables OCSP check +* @param ocsp_resp additional OCSP responses to consider (eg from peer) +* @return result of the path validation +* note: when enabled, OCSP check is softfail by default: if the OCSP server is not +* reachable, Path_Validation_Result::successful_validation() will return true. +* Hardfail OCSP check can be achieve by also calling Path_Validation_Result::no_warnings(). +*/ +Path_Validation_Result BOTAN_PUBLIC_API(2,0) x509_path_validate( + const std::vector& end_certs, + const Path_Validation_Restrictions& restrictions, + const std::vector& trusted_roots, + const std::string& hostname = "", + Usage_Type usage = Usage_Type::UNSPECIFIED, + std::chrono::system_clock::time_point validation_time = std::chrono::system_clock::now(), + std::chrono::milliseconds ocsp_timeout = std::chrono::milliseconds(0), + const std::vector>& ocsp_resp = {}); + +/** +* PKIX Path Validation +* @param end_cert certificate to validate +* @param restrictions path validation restrictions +* @param trusted_roots list of stores that contain trusted certificates +* @param hostname if not empty, compared against the DNS name in end_cert +* @param usage if not set to UNSPECIFIED, compared against the key usage in end_cert +* @param validation_time what reference time to use for validation +* @param ocsp_timeout timeout for OCSP operations, 0 disables OCSP check +* @param ocsp_resp additional OCSP responses to consider (eg from peer) +* @return result of the path validation +*/ +Path_Validation_Result BOTAN_PUBLIC_API(2,0) x509_path_validate( + const X509_Certificate& end_cert, + const Path_Validation_Restrictions& restrictions, + const std::vector& trusted_roots, + const std::string& hostname = "", + Usage_Type usage = Usage_Type::UNSPECIFIED, + std::chrono::system_clock::time_point validation_time = std::chrono::system_clock::now(), + std::chrono::milliseconds ocsp_timeout = std::chrono::milliseconds(0), + const std::vector>& ocsp_resp = {}); + +/** +* PKIX Path Validation +* @param end_cert certificate to validate +* @param restrictions path validation restrictions +* @param store store that contains trusted certificates +* @param hostname if not empty, compared against the DNS name in end_cert +* @param usage if not set to UNSPECIFIED, compared against the key usage in end_cert +* @param validation_time what reference time to use for validation +* @param ocsp_timeout timeout for OCSP operations, 0 disables OCSP check +* @param ocsp_resp additional OCSP responses to consider (eg from peer) +* @return result of the path validation +*/ +Path_Validation_Result BOTAN_PUBLIC_API(2,0) x509_path_validate( + const X509_Certificate& end_cert, + const Path_Validation_Restrictions& restrictions, + const Certificate_Store& store, + const std::string& hostname = "", + Usage_Type usage = Usage_Type::UNSPECIFIED, + std::chrono::system_clock::time_point validation_time = std::chrono::system_clock::now(), + std::chrono::milliseconds ocsp_timeout = std::chrono::milliseconds(0), + const std::vector>& ocsp_resp = {}); + +/** +* PKIX Path Validation +* @param end_certs certificate chain to validate +* @param restrictions path validation restrictions +* @param store store that contains trusted certificates +* @param hostname if not empty, compared against the DNS name in end_certs[0] +* @param usage if not set to UNSPECIFIED, compared against the key usage in end_certs[0] +* @param validation_time what reference time to use for validation +* @param ocsp_timeout timeout for OCSP operations, 0 disables OCSP check +* @param ocsp_resp additional OCSP responses to consider (eg from peer) +* @return result of the path validation +*/ +Path_Validation_Result BOTAN_PUBLIC_API(2,0) x509_path_validate( + const std::vector& end_certs, + const Path_Validation_Restrictions& restrictions, + const Certificate_Store& store, + const std::string& hostname = "", + Usage_Type usage = Usage_Type::UNSPECIFIED, + std::chrono::system_clock::time_point validation_time = std::chrono::system_clock::now(), + std::chrono::milliseconds ocsp_timeout = std::chrono::milliseconds(0), + const std::vector>& ocsp_resp = {}); + + +/** +* namespace PKIX holds the building blocks that are called by x509_path_validate. +* This allows custom validation logic to be written by applications and makes +* for easier testing, but unless you're positive you know what you're doing you +* probably want to just call x509_path_validate instead. +*/ +namespace PKIX { + +Certificate_Status_Code +build_all_certificate_paths(std::vector>>& cert_paths, + const std::vector& trusted_certstores, + const std::shared_ptr& end_entity, + const std::vector>& end_entity_extra); + + +/** +* Build certificate path +* @param cert_path_out output parameter, cert_path will be appended to this vector +* @param trusted_certstores list of certificate stores that contain trusted certificates +* @param end_entity the cert to be validated +* @param end_entity_extra optional list of additional untrusted certs for path building +* @return result of the path building operation (OK or error) +*/ +Certificate_Status_Code +BOTAN_PUBLIC_API(2,0) build_certificate_path(std::vector>& cert_path_out, + const std::vector& trusted_certstores, + const std::shared_ptr& end_entity, + const std::vector>& end_entity_extra); + +/** +* Check the certificate chain, but not any revocation data +* +* @param cert_path path built by build_certificate_path with OK result +* @param ref_time whatever time you want to perform the validation +* against (normally current system clock) +* @param hostname the hostname +* @param usage end entity usage checks +* @param min_signature_algo_strength 80 or 110 typically +* Note 80 allows 1024 bit RSA and SHA-1. 110 allows 2048 bit RSA and SHA-2. +* Using 128 requires ECC (P-256) or ~3000 bit RSA keys. +* @param trusted_hashes set of trusted hash functions, empty means accept any +* hash we have an OID for +* @return vector of results on per certificate in the path, each containing a set of +* results. If all codes in the set are < Certificate_Status_Code::FIRST_ERROR_STATUS, +* then the result for that certificate is successful. If all results are +*/ +CertificatePathStatusCodes +BOTAN_PUBLIC_API(2,0) check_chain(const std::vector>& cert_path, + std::chrono::system_clock::time_point ref_time, + const std::string& hostname, + Usage_Type usage, + size_t min_signature_algo_strength, + const std::set& trusted_hashes); + +/** +* Check OCSP responses for revocation information +* @param cert_path path already validated by check_chain +* @param ocsp_responses the OCSP responses to consider +* @param certstores trusted roots +* @param ref_time whatever time you want to perform the validation against +* (normally current system clock) +* @return revocation status +*/ +CertificatePathStatusCodes +BOTAN_PUBLIC_API(2,0) check_ocsp(const std::vector>& cert_path, + const std::vector>& ocsp_responses, + const std::vector& certstores, + std::chrono::system_clock::time_point ref_time); + +/** +* Check CRLs for revocation information +* @param cert_path path already validated by check_chain +* @param crls the list of CRLs to check, it is assumed that crls[i] (if not null) +* is the associated CRL for the subject in cert_path[i]. +* @param ref_time whatever time you want to perform the validation against +* (normally current system clock) +* @return revocation status +*/ +CertificatePathStatusCodes +BOTAN_PUBLIC_API(2,0) check_crl(const std::vector>& cert_path, + const std::vector>& crls, + std::chrono::system_clock::time_point ref_time); + +/** +* Check CRLs for revocation information +* @param cert_path path already validated by check_chain +* @param certstores a list of certificate stores to query for the CRL +* @param ref_time whatever time you want to perform the validation against +* (normally current system clock) +* @return revocation status +*/ +CertificatePathStatusCodes +BOTAN_PUBLIC_API(2,0) check_crl(const std::vector>& cert_path, + const std::vector& certstores, + std::chrono::system_clock::time_point ref_time); + +#if defined(BOTAN_HAS_ONLINE_REVOCATION_CHECKS) + +/** +* Check OCSP using online (HTTP) access. Current version creates a thread and +* network connection per OCSP request made. +* +* @param cert_path path already validated by check_chain +* @param trusted_certstores a list of certstores with trusted certs +* @param ref_time whatever time you want to perform the validation against +* (normally current system clock) +* @param timeout for timing out the responses, though actually this function +* may block for up to timeout*cert_path.size()*C for some small C. +* @param ocsp_check_intermediate_CAs if true also performs OCSP on any intermediate +* CA certificates. If false, only does OCSP on the end entity cert. +* @return revocation status +*/ +CertificatePathStatusCodes +BOTAN_PUBLIC_API(2,0) check_ocsp_online(const std::vector>& cert_path, + const std::vector& trusted_certstores, + std::chrono::system_clock::time_point ref_time, + std::chrono::milliseconds timeout, + bool ocsp_check_intermediate_CAs); + +/** +* Check CRL using online (HTTP) access. Current version creates a thread and +* network connection per CRL access. + +* @param cert_path path already validated by check_chain +* @param trusted_certstores a list of certstores with trusted certs +* @param certstore_to_recv_crls optional (nullptr to disable), all CRLs +* retreived will be saved to this cert store. +* @param ref_time whatever time you want to perform the validation against +* (normally current system clock) +* @param timeout for timing out the responses, though actually this function +* may block for up to timeout*cert_path.size()*C for some small C. +* @return revocation status +*/ +CertificatePathStatusCodes +BOTAN_PUBLIC_API(2,0) check_crl_online(const std::vector>& cert_path, + const std::vector& trusted_certstores, + Certificate_Store_In_Memory* certstore_to_recv_crls, + std::chrono::system_clock::time_point ref_time, + std::chrono::milliseconds timeout); + +#endif + +/** +* Find overall status (OK, error) of a validation +* @param cert_status result of merge_revocation_status or check_chain +*/ +Certificate_Status_Code BOTAN_PUBLIC_API(2,0) overall_status(const CertificatePathStatusCodes& cert_status); + +/** +* Merge the results from CRL and/or OCSP checks into chain_status +* @param chain_status the certificate status +* @param crl_status results from check_crl +* @param ocsp_status results from check_ocsp +* @param require_rev_on_end_entity require valid CRL or OCSP on end-entity cert +* @param require_rev_on_intermediates require valid CRL or OCSP on all intermediate certificates +*/ +void BOTAN_PUBLIC_API(2,0) merge_revocation_status(CertificatePathStatusCodes& chain_status, + const CertificatePathStatusCodes& crl_status, + const CertificatePathStatusCodes& ocsp_status, + bool require_rev_on_end_entity, + bool require_rev_on_intermediates); + +} + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/x509/x509self.cpp b/src/libs/3rdparty/botan/src/lib/x509/x509self.cpp new file mode 100644 index 0000000000..32f21c1015 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/x509/x509self.cpp @@ -0,0 +1,147 @@ +/* +* PKCS #10/Self Signed Cert Creation +* (C) 1999-2008,2018 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include +#include +#include +#include + +namespace Botan { + +namespace { + +/* +* Load information from the X509_Cert_Options +*/ +void load_info(const X509_Cert_Options& opts, X509_DN& subject_dn, + AlternativeName& subject_alt) + { + subject_dn.add_attribute("X520.CommonName", opts.common_name); + subject_dn.add_attribute("X520.Country", opts.country); + subject_dn.add_attribute("X520.State", opts.state); + subject_dn.add_attribute("X520.Locality", opts.locality); + subject_dn.add_attribute("X520.Organization", opts.organization); + subject_dn.add_attribute("X520.OrganizationalUnit", opts.org_unit); + subject_dn.add_attribute("X520.SerialNumber", opts.serial_number); + subject_alt = AlternativeName(opts.email, opts.uri, opts.dns, opts.ip); + subject_alt.add_othername(OIDS::lookup("PKIX.XMPPAddr"), + opts.xmpp, UTF8_STRING); + + for(auto dns : opts.more_dns) + subject_alt.add_attribute("DNS", dns); + } +} + +namespace X509 { + +/* +* Create a new self-signed X.509 certificate +*/ +X509_Certificate create_self_signed_cert(const X509_Cert_Options& opts, + const Private_Key& key, + const std::string& hash_fn, + RandomNumberGenerator& rng) + { + AlgorithmIdentifier sig_algo; + X509_DN subject_dn; + AlternativeName subject_alt; + + // for now, only the padding option is used + std::map sig_opts = { {"padding",opts.padding_scheme} }; + + const std::vector pub_key = X509::BER_encode(key); + std::unique_ptr signer(choose_sig_format(key, sig_opts, rng, hash_fn, sig_algo)); + load_info(opts, subject_dn, subject_alt); + + Extensions extensions = opts.extensions; + + Key_Constraints constraints; + if(opts.is_CA) + { + constraints = Key_Constraints(KEY_CERT_SIGN | CRL_SIGN); + } + else + { + verify_cert_constraints_valid_for_key_type(key, opts.constraints); + constraints = opts.constraints; + } + + extensions.add_new( + new Cert_Extension::Basic_Constraints(opts.is_CA, opts.path_limit), + true); + + if(constraints != NO_CONSTRAINTS) + { + extensions.add_new(new Cert_Extension::Key_Usage(constraints), true); + } + + std::unique_ptr skid(new Cert_Extension::Subject_Key_ID(pub_key, hash_fn)); + + extensions.add_new(new Cert_Extension::Authority_Key_ID(skid->get_key_id())); + extensions.add_new(skid.release()); + + extensions.add_new( + new Cert_Extension::Subject_Alternative_Name(subject_alt)); + + extensions.add_new( + new Cert_Extension::Extended_Key_Usage(opts.ex_constraints)); + + return X509_CA::make_cert(signer.get(), rng, sig_algo, pub_key, + opts.start, opts.end, + subject_dn, subject_dn, + extensions); + } + +/* +* Create a PKCS #10 certificate request +*/ +PKCS10_Request create_cert_req(const X509_Cert_Options& opts, + const Private_Key& key, + const std::string& hash_fn, + RandomNumberGenerator& rng) + { + X509_DN subject_dn; + AlternativeName subject_alt; + load_info(opts, subject_dn, subject_alt); + + Key_Constraints constraints; + if(opts.is_CA) + { + constraints = Key_Constraints(KEY_CERT_SIGN | CRL_SIGN); + } + else + { + verify_cert_constraints_valid_for_key_type(key, opts.constraints); + constraints = opts.constraints; + } + + Extensions extensions = opts.extensions; + + extensions.add_new(new Cert_Extension::Basic_Constraints(opts.is_CA, opts.path_limit)); + + if(constraints != NO_CONSTRAINTS) + { + extensions.add_new(new Cert_Extension::Key_Usage(constraints)); + } + extensions.add_new(new Cert_Extension::Extended_Key_Usage(opts.ex_constraints)); + extensions.add_new(new Cert_Extension::Subject_Alternative_Name(subject_alt)); + + return PKCS10_Request::create(key, + subject_dn, + extensions, + hash_fn, + rng, + opts.padding_scheme, + opts.challenge); + } + +} + +} diff --git a/src/libs/3rdparty/botan/src/lib/x509/x509self.h b/src/libs/3rdparty/botan/src/lib/x509/x509self.h new file mode 100644 index 0000000000..7d061acbb3 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/x509/x509self.h @@ -0,0 +1,215 @@ +/* +* X.509 Self-Signed Certificate +* (C) 1999-2007 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_X509_SELF_H_ +#define BOTAN_X509_SELF_H_ + +#include +#include +#include +#include + +namespace Botan { + +class RandomNumberGenerator; +class Private_Key; + +/** +* Options for X.509 certificates. +*/ +class BOTAN_PUBLIC_API(2,0) X509_Cert_Options final + { + public: + /** + * the subject common name + */ + std::string common_name; + + /** + * the subject counry + */ + std::string country; + + /** + * the subject organization + */ + std::string organization; + + /** + * the subject organizational unit + */ + std::string org_unit; + + /** + * the subject locality + */ + std::string locality; + + /** + * the subject state + */ + std::string state; + + /** + * the subject serial number + */ + std::string serial_number; + + /** + * the subject email adress + */ + std::string email; + + /** + * the subject URI + */ + std::string uri; + + /** + * the subject IPv4 address + */ + std::string ip; + + /** + * the subject DNS + */ + std::string dns; + + std::vector more_dns; + + /** + * the subject XMPP + */ + std::string xmpp; + + /** + * the subject challenge password + */ + std::string challenge; + + /** + * the subject notBefore + */ + X509_Time start; + /** + * the subject notAfter + */ + X509_Time end; + + /** + * Indicates whether the certificate request + */ + bool is_CA; + + /** + * Indicates the BasicConstraints path limit + */ + size_t path_limit; + + std::string padding_scheme; + + /** + * The key constraints for the subject public key + */ + Key_Constraints constraints; + + /** + * The key extended constraints for the subject public key + */ + std::vector ex_constraints; + + /** + * Additional X.509 extensions + */ + Extensions extensions; + + /** + * Mark the certificate as a CA certificate and set the path limit. + * @param limit the path limit to be set in the BasicConstraints extension. + */ + void CA_key(size_t limit = 1); + + /** + * Choose a padding scheme different from the default for the key used. + */ + void set_padding_scheme(const std::string& scheme); + + /** + * Set the notBefore of the certificate. + * @param time the notBefore value of the certificate + */ + void not_before(const std::string& time); + + /** + * Set the notAfter of the certificate. + * @param time the notAfter value of the certificate + */ + void not_after(const std::string& time); + + /** + * Add the key constraints of the KeyUsage extension. + * @param constr the constraints to set + */ + void add_constraints(Key_Constraints constr); + + /** + * Add constraints to the ExtendedKeyUsage extension. + * @param oid the oid to add + */ + void add_ex_constraint(const OID& oid); + + /** + * Add constraints to the ExtendedKeyUsage extension. + * @param name the name to look up the oid to add + */ + void add_ex_constraint(const std::string& name); + + /** + * Construct a new options object + * @param opts define the common name of this object. An example for this + * parameter would be "common_name/country/organization/organizational_unit". + * @param expire_time the expiration time (from the current clock in seconds) + */ + X509_Cert_Options(const std::string& opts = "", + uint32_t expire_time = 365 * 24 * 60 * 60); + }; + +namespace X509 { + +/** +* Create a self-signed X.509 certificate. +* @param opts the options defining the certificate to create +* @param key the private key used for signing, i.e. the key +* associated with this self-signed certificate +* @param hash_fn the hash function to use +* @param rng the rng to use +* @return newly created self-signed certificate +*/ +BOTAN_PUBLIC_API(2,0) X509_Certificate +create_self_signed_cert(const X509_Cert_Options& opts, + const Private_Key& key, + const std::string& hash_fn, + RandomNumberGenerator& rng); + +/** +* Create a PKCS#10 certificate request. +* @param opts the options defining the request to create +* @param key the key used to sign this request +* @param rng the rng to use +* @param hash_fn the hash function to use +* @return newly created PKCS#10 request +*/ +BOTAN_PUBLIC_API(2,0) PKCS10_Request create_cert_req(const X509_Cert_Options& opts, + const Private_Key& key, + const std::string& hash_fn, + RandomNumberGenerator& rng); + +} + +} + +#endif diff --git a/src/libs/botan/botan.pri b/src/libs/botan/botan.pri new file mode 100644 index 0000000000..b5b28535d1 --- /dev/null +++ b/src/libs/botan/botan.pri @@ -0,0 +1,5 @@ +msvc: BOTAN_LIB_NAME = botan +else: BOTAN_LIB_NAME = botan-2 +BOTAN_BUILD_DIR = build +!msvc: BOTAN_LIB_PREFIX = lib +BOTAN_FULL_NAME = $$BOTAN_LIB_PREFIX$${BOTAN_LIB_NAME}.$$QMAKE_EXTENSION_STATICLIB diff --git a/src/libs/botan/botan.pro b/src/libs/botan/botan.pro new file mode 100644 index 0000000000..91ce2e2995 --- /dev/null +++ b/src/libs/botan/botan.pro @@ -0,0 +1,55 @@ +TEMPLATE = aux + +DISTFILES = update-botan.sh + +include(botan.pri) +include(../../../qtcreator.pri) +BOTAN_BUILD_DIR = $$OUT_PWD/$$BOTAN_BUILD_DIR +BOTAN_FILE_PATH = $$BOTAN_BUILD_DIR/$$BOTAN_FULL_NAME +BOTAN_BUILD_DIR_FOR_SHELL = $$shell_quote($$shell_path($$BOTAN_BUILD_DIR)) +BOTAN_SOURCE_DIR = $$PWD/../3rdparty/botan + +TARGET = $$BOTAN_LIB_NAME +PRECOMPILED_HEADER = +CONFIG -= qt + +msvc: BOTAN_CC_TYPE = msvc +else: clang: BOTAN_CC_TYPE = clang +else: BOTAN_CC_TYPE = gcc +contains(QT_ARCH, i386): BOTAN_ARCH_SWITCH = "--cpu=x86" +else: contains(QT_ARCH, x86_64): BOTAN_ARCH_SWITCH = "--cpu=x86_64" +BOTAN_MODULES = aes aes_ssse3 auto_rng bigint block cbc ctr des dh dsa ec_group ecdh ecdsa entropy \ + filters hmac mode_pad pubkey rsa sha1 sha1_sse2 sha1_x86 sha2_32 sha2_32_x86 \ + sha2_64 simd system_rng,emsa_pkcs1,pbes2,pbkdf2 +OTHER_FLAGS = --amalgamation --minimized-build --disable-shared \ + --enable-modules=$$join(BOTAN_MODULES,",",,) +mingw { + BOTAN_OS_SWITCH = "--os=mingw" + OTHER_FLAGS += --without-stack-protector +} +BOTAN_CXX_FLAGS = +msvc: BOTAN_CXX_FLAGS += /wd4127 /wd4244 /wd4250 /wd4267 /wd4334 /wd4702 /wd4996 +else: BOTAN_CXX_FLAGS += -Wno-unused-parameter +macos: BOTAN_CXX_FLAGS += -mmacosx-version-min=$$QMAKE_MACOSX_DEPLOYMENT_TARGET +unix: BOTAN_CXX_FLAGS += -fPIC +!isEmpty(BOTAN_CXX_FLAGS): OTHER_FLAGS += --cxxflags=$$shell_quote($$BOTAN_CXX_FLAGS) +win32: OTHER_FLAGS += --link-method=hardlink +CONFIG(debug, debug|release): OTHER_FLAGS += --with-debug-info +CONFIGURE_FILE_PATH_FOR_SHELL = $$shell_quote($$shell_path($$BOTAN_SOURCE_DIR/configure.py)) + +configure_inputs = $$BOTAN_SOURCE_DIR/configure.py + +configure.input = configure_inputs +configure.output = $$BOTAN_BUILD_DIR/Makefile +configure.variable_out = BOTAN_MAKEFILE +configure.commands = cd $$BOTAN_BUILD_DIR_FOR_SHELL && \ + python $$CONFIGURE_FILE_PATH_FOR_SHELL \ + --cc=$$BOTAN_CC_TYPE --cc-bin=$$QMAKE_CXX \ + $$BOTAN_ARCH_SWITCH $$BOTAN_OS_SWITCH $$OTHER_FLAGS +QMAKE_EXTRA_COMPILERS += configure + +make.input = BOTAN_MAKEFILE +make.output = $$BOTAN_FILE_PATH +make.CONFIG += target_predeps +make.commands = cd $$BOTAN_BUILD_DIR_FOR_SHELL && $(MAKE) libs +QMAKE_EXTRA_COMPILERS += make diff --git a/src/libs/botan/botan.qbs b/src/libs/botan/botan.qbs new file mode 100644 index 0000000000..fa492b5734 --- /dev/null +++ b/src/libs/botan/botan.qbs @@ -0,0 +1,112 @@ +import qbs + +Product { + name: "Botan" + condition: !qtc.useSystemBotan + type: ["staticlibrary", "hpp"] + Depends { name: "cpp" } + Depends { name: "qtc" } + files: "update-botan.sh" + Group { + name: "Botan sources" + prefix: "../3rdparty/botan/" + Group { + name: "Botan configure script" + files: "configure.py" + fileTags: "botan.configure" + } + Group { + name: "Other Botan files" + files: "**/*" + excludeFiles: "configure.py" + fileTags: "botan.sources" + } + } + + Rule { + inputs: "botan.configure" + Artifact { + filePath: "Makefile" + fileTags: "botan.Makefile" + } + Artifact { + filePath: "build/include/botan/build.h" + fileTags: "hpp" + } + prepare: { + var args = [input.filePath, "--amalgamation", "--minimized-build", "--disable-shared"]; + var modules = "aes,aes_ssse3,auto_rng,bigint,block,cbc,ctr,des,dh,dsa,ec_group,ecdh," + + "ecdsa,entropy,filters,hmac,mode_pad,pubkey,rsa,sha1,sha1_sse2,sha1_x86," + + "sha2_32,sha2_32_x86,sha2_64,simd,system_rng,emsa_pkcs1,pbes2,pbkdf2"; + args.push("--enable-modules=" + modules); + var cxxFlags = []; + if (product.qbs.toolchain.contains("msvc")) { + cxxFlags.push("/wd4127", "/wd4244", "/wd4250", "/wd4267", "/wd4334", "/wd4702", + "/wd4996"); + } + else if (product.qbs.toolchain.contains("gcc")) + cxxFlags.push("-Wno-unused-parameter"); + if (product.qbs.targetOS.contains("macos")) + cxxFlags.push("-mmacosx-version-min=" + project.minimumMacosVersion); + if (product.qbs.targetOS.contains("unix")) + cxxFlags.push("-fPIC"); + if (cxxFlags.length > 0) + args.push("--cxxflags=" + cxxFlags.join(" ")); + var ccOption = "--cc="; + var tc = product.qbs.toolchain; + if (tc.contains("msvc")) + ccOption += "msvc"; + else if (tc.contains("clang")) + ccOption += "clang"; + else + ccOption += "gcc"; + args.push(ccOption); + if (!tc.contains("msvc")) + args.push("--cc-bin=" + product.cpp.compilerPath); + if (tc.contains("mingw")) { + args.push("--os=mingw", "--without-stack-protector"); + if (product.qbs.targetOS.contains("windows")) + args.push("--link-method=hardlink"); + } + var arch = product.qbs.architecture; + if (arch == "x86" || arch == "x86_64") + args.push("--cpu=" + arch); + if (product.qbs.debugInformation) + args.push("--with-debug-info"); + var cmd = new Command("python", args); + cmd.workingDirectory = product.buildDirectory; + cmd.description = "Configuring Botan"; + return cmd; + } + } + + Rule { + multiplex: true + inputs: ["botan.Makefile", "botan.sources"] + Artifact { + filePath: (product.qbs.toolchain.contains("msvc") ? "botan" : "libbotan-2") + + product.cpp.staticLibrarySuffix; + fileTags: "staticlibrary" + } + + prepare: { + var tc = product.moduleProperty("qbs", "toolchain"); + var make = "make"; + if (tc.contains("msvc")) { + make = "nmake"; + } else if (tc.contains("mingw") + && product.moduleProperty("qbs", "hostOS").contains("windows")) { + make = "mingw32-make"; + } + var cmd = new Command(make, ["libs"]); + cmd.workingDirectory = product.buildDirectory; + cmd.description = "Building Botan"; + return cmd; + } + } + + Export { + Depends { name: "cpp" } + cpp.includePaths: product.buildDirectory + "/build/include" + } +} diff --git a/src/libs/botan/botan_dependencies.pri b/src/libs/botan/botan_dependencies.pri new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/libs/botan/update-botan.sh b/src/libs/botan/update-botan.sh new file mode 100644 index 0000000000..f604fe8442 --- /dev/null +++ b/src/libs/botan/update-botan.sh @@ -0,0 +1,62 @@ +#!/bin/sh + +test $# -eq 1 || { echo "This script needs a Botan archive as its sole argument."; exit 1; } + +set -e + +script_dir=$(readlink -f $(dirname $0)) +botan_archive=$1 +botan_extracted_dir_name=$(basename -s .tgz $botan_archive) +botan_parent_dir=$script_dir/../3rdparty + +cd $botan_parent_dir + +echo "Removing old botan sources..." +rm -rf botan + +echo "Extracting new botan sources..." +tar xf $botan_archive +mv $botan_extracted_dir_name botan + +echo "Removing unneeded components..." +cd botan +rm -r doc news.rst +cd src +rm -r build-data/policy/* cli configs fuzzer python scripts tests +cd lib +rm -r codec/base32 compression ffi misc passhash pbkdf/pbkdf1 pbkdf/pgp_s2k pbkdf/scrypt prov \ + psk_db tls +cd block +rm -r aria blowfish camellia cascade cast gost_28147 idea kasumi lion misty1 noekeon seed serpent\ + shacal2 sm4 threefish_512 twofish xtea +cd ../filters +rm -r codec_filt fd_unix +cd ../hash +rm -r blake2 checksum comb4p gost_3411 keccak md4 md5 par_hash rmd160 sha3 shake skein sm3 \ + streebog tiger whirlpool +cd ../kdf +rm -r hkdf kdf1 kdf1_iso18033 kdf2 prf_tls prf_x942 sp800_108 sp800_56a sp800_56c +cd ../mac +rm -r cbc_mac cmac gmac poly1305 siphash x919_mac +cd ../modes +rm -r aead cfb xts +cd ../pk_pad +rm -r eme_oaep eme_pkcs1 eme_raw emsa_raw emsa_x931 iso9796 +cd ../pubkey +rm -r cecpq1 curve25519 dlies ecgdsa ecies eckcdsa ed25519 elgamal gost_3410 mce mceies newhope \ + rfc6979 sm2 xmss +cd ../rng +rm -r chacha_rng +cd ../stream +rm -r chacha ofb rc4 salsa20 shake_cipher +cd ../utils +rm -r boost http_util locking_allocator mem_pool poly_dbl socket sqlite3 thread_utils +cd ../x509 +rm -r certstor_sql certstor_sqlite3 + +echo "Patching..." +# Fix annoying linker warning on macOS +sed -i 's/all!haiku -> "-pthread"/all!haiku,darwin -> "-pthread"/g' \ + "$botan_parent_dir/botan/src/build-data/cc/clang.txt" + +echo "Done." diff --git a/src/libs/libs.pro b/src/libs/libs.pro index b6b40f78e7..f032a0e4b0 100644 --- a/src/libs/libs.pro +++ b/src/libs/libs.pro @@ -2,7 +2,9 @@ include(../../qtcreator.pri) TEMPLATE = subdirs -SUBDIRS = \ +!use_system_botan: SUBDIRS += botan + +SUBDIRS += \ aggregation \ extensionsystem \ utils \ @@ -29,6 +31,8 @@ for(l, SUBDIRS) { $$lv = $$QTC_LIB_DEPENDS } +!use_system_botan: ssh.depends += botan + SUBDIRS += \ utils/process_stub.pro diff --git a/src/libs/libs.qbs b/src/libs/libs.qbs index d1b205a734..715cb7d456 100644 --- a/src/libs/libs.qbs +++ b/src/libs/libs.qbs @@ -4,6 +4,7 @@ Project { name: "Libs" references: [ "aggregation/aggregation.qbs", + "botan/botan.qbs", "clangsupport/clangsupport.qbs", "cplusplus/cplusplus.qbs", "extensionsystem/extensionsystem.qbs", diff --git a/src/libs/ssh/ssh.pro b/src/libs/ssh/ssh.pro index 499540ac72..40efcaf96b 100644 --- a/src/libs/ssh/ssh.pro +++ b/src/libs/ssh/ssh.pro @@ -27,7 +27,6 @@ SOURCES = $$PWD/sshsendfacility.cpp \ $$PWD/sshkeypasswordretriever.cpp \ $$PWD/sftpfilesystemmodel.cpp \ $$PWD/sshkeycreationdialog.cpp \ - $$PWD/sshinit.cpp \ $$PWD/sshdirecttcpiptunnel.cpp \ $$PWD/sshlogging.cpp \ $$PWD/sshhostkeydatabase.cpp \ @@ -69,7 +68,6 @@ HEADERS = $$PWD/sshsendfacility_p.h \ $$PWD/sshkeycreationdialog.h \ $$PWD/ssh_global.h \ $$PWD/sshdirecttcpiptunnel_p.h \ - $$PWD/sshinit_p.h \ $$PWD/sshdirecttcpiptunnel.h \ $$PWD/sshlogging_p.h \ $$PWD/sshhostkeydatabase.h \ @@ -84,4 +82,14 @@ FORMS = $$PWD/sshkeycreationdialog.ui RESOURCES += $$PWD/ssh.qrc -include(../3rdparty/botan/botan.pri) +include(../botan/botan.pri) +use_system_botan { + CONFIG += link_pkgconfig + PKGCONFIG += botan-2 +} else { + BOTAN_BUILD_DIR = $$OUT_PWD/../botan/$$BOTAN_BUILD_DIR + INCLUDEPATH += $$BOTAN_BUILD_DIR/build/include + LIBS += $$BOTAN_BUILD_DIR/$$BOTAN_FULL_NAME + win32: LIBS += -ladvapi32 -luser32 -lws2_32 +} +msvc:QMAKE_CXXFLAGS += /wd4250 diff --git a/src/libs/ssh/ssh.qbs b/src/libs/ssh/ssh.qbs index 3aa95a16d5..b635b7037f 100644 --- a/src/libs/ssh/ssh.qbs +++ b/src/libs/ssh/ssh.qbs @@ -7,12 +7,18 @@ Project { QtcDevHeaders { } QtcLibrary { - cpp.defines: base.concat(["QTCSSH_LIBRARY"]).concat(botanDefines) + cpp.defines: base.concat("QTCSSH_LIBRARY") cpp.includePaths: botanIncludes cpp.dynamicLibraries: botanLibs cpp.enableExceptions: true + Properties { + condition: qbs.toolchain.contains("msvc") + cpp.cxxFlags: base.concat("/wd4250"); + } + Depends { name: "Qt"; submodules: ["widgets", "network" ] } + Depends { name: "Botan"; condition: !qtc.useSystemBotan } files: [ "sftpchannel.h", "sftpchannel_p.h", "sftpchannel.cpp", @@ -38,7 +44,6 @@ Project { "sshhostkeydatabase.cpp", "sshhostkeydatabase.h", "sshincomingpacket_p.h", "sshincomingpacket.cpp", - "sshinit_p.h", "sshinit.cpp", "sshkeycreationdialog.cpp", "sshkeycreationdialog.h", "sshkeycreationdialog.ui", "sshkeyexchange.cpp", "sshkeyexchange_p.h", "sshkeygenerator.cpp", "sshkeygenerator.h", @@ -54,21 +59,15 @@ Project { "sshsendfacility.cpp", "sshsendfacility_p.h", "sshtcpipforwardserver.cpp", "sshtcpipforwardserver.h", "sshtcpipforwardserver_p.h", "sshtcpiptunnel.cpp", "sshtcpiptunnel_p.h", - ].concat(botanFiles) + ] - property var useSystemBotan: Environment.getEnv("USE_SYSTEM_BOTAN") === "1" - property var botanIncludes: { - var result = ["../3rdparty"]; - if (useSystemBotan) - result.push("/usr/include/botan-1.10") - return result - } + property var botanIncludes: qtc.useSystemBotan ? ["/usr/include/botan-2"] : [] property var botanLibs: { var result = []; - if (useSystemBotan) - result.push("botan-1.10") + if (qtc.useSystemBotan) + result.push("botan-2") if (qbs.targetOS.contains("windows")) - result.push("advapi32", "user32") + result.push("advapi32", "user32", "ws2_32") else if (qbs.targetOS.contains("linux")) result.push("rt", "dl"); else if (qbs.targetOS.contains("macos")) @@ -77,57 +76,6 @@ Project { result.push("rt"); return result } - property var botanDefines: { - var result = []; - if (useSystemBotan) { - result.push("USE_SYSTEM_BOTAN") - } else { - result.push("BOTAN_DLL=") - if (qbs.toolchain.contains("msvc")) - result.push("BOTAN_BUILD_COMPILER_IS_MSVC", - "BOTAN_TARGET_OS_HAS_GMTIME_S", - "_SCL_SECURE_NO_WARNINGS") - if (qbs.toolchain.contains("gcc") || qbs.toolchain.contains("mingw")) - result.push("BOTAN_BUILD_COMPILER_IS_GCC") - if (qbs.targetOS.contains("linux")) - result.push("BOTAN_TARGET_OS_IS_LINUX", "BOTAN_TARGET_OS_HAS_CLOCK_GETTIME", - "BOTAN_TARGET_OS_HAS_DLOPEN", " BOTAN_TARGET_OS_HAS_GMTIME_R", - "BOTAN_TARGET_OS_HAS_POSIX_MLOCK", "BOTAN_HAS_DYNAMICALLY_LOADED_ENGINE", - "BOTAN_HAS_DYNAMIC_LOADER", "BOTAN_TARGET_OS_HAS_GETTIMEOFDAY", - "BOTAN_HAS_ALLOC_MMAP", "BOTAN_HAS_ENTROPY_SRC_DEV_RANDOM", - "BOTAN_HAS_ENTROPY_SRC_EGD", "BOTAN_HAS_ENTROPY_SRC_FTW", - "BOTAN_HAS_ENTROPY_SRC_UNIX", "BOTAN_HAS_MUTEX_PTHREAD", "BOTAN_HAS_PIPE_UNIXFD_IO") - if (qbs.targetOS.contains("macos")) - result.push("BOTAN_TARGET_OS_IS_DARWIN", "BOTAN_TARGET_OS_HAS_GETTIMEOFDAY", - "BOTAN_HAS_ALLOC_MMAP", "BOTAN_HAS_ENTROPY_SRC_DEV_RANDOM", - "BOTAN_HAS_ENTROPY_SRC_EGD", "BOTAN_HAS_ENTROPY_SRC_FTW", - "BOTAN_HAS_ENTROPY_SRC_UNIX", "BOTAN_HAS_MUTEX_PTHREAD", "BOTAN_HAS_PIPE_UNIXFD_IO") - if (qbs.targetOS.contains("windows")) - result.push("BOTAN_TARGET_OS_IS_WINDOWS", - "BOTAN_TARGET_OS_HAS_LOADLIBRARY", "BOTAN_TARGET_OS_HAS_WIN32_GET_SYSTEMTIME", - "BOTAN_TARGET_OS_HAS_WIN32_VIRTUAL_LOCK", "BOTAN_HAS_DYNAMICALLY_LOADED_ENGINE", - "BOTAN_HAS_DYNAMIC_LOADER", "BOTAN_HAS_ENTROPY_SRC_CAPI", - "BOTAN_HAS_ENTROPY_SRC_WIN32", "BOTAN_HAS_MUTEX_WIN32") - } - return result - } - property var botanFiles: { - var result = ["../3rdparty/botan/botan.h"]; - if (!useSystemBotan) - result.push("../3rdparty/botan/botan.cpp") - return result - } - - // For Botan. - Properties { - condition: qbs.toolchain.contains("mingw") - cpp.cxxFlags: base.concat([ - "-fpermissive", - "-finline-functions", - "-Wno-long-long" - ]) - } - cpp.cxxFlags: base Export { Depends { name: "Qt"; submodules: ["widgets", "network"] } diff --git a/src/libs/ssh/sshbotanconversions_p.h b/src/libs/ssh/sshbotanconversions_p.h index f54ca843a2..335a02323c 100644 --- a/src/libs/ssh/sshbotanconversions_p.h +++ b/src/libs/ssh/sshbotanconversions_p.h @@ -28,7 +28,8 @@ #include "sshcapabilities_p.h" #include "sshexception_p.h" -#include +#include +#include namespace QSsh { namespace Internal { @@ -45,7 +46,12 @@ inline Botan::byte *convertByteArray(QByteArray &a) inline QByteArray convertByteArray(const Botan::SecureVector &v) { - return QByteArray(reinterpret_cast(v.begin()), static_cast(v.size())); + return QByteArray(reinterpret_cast(&v.front()), static_cast(v.size())); +} + +inline QByteArray convertByteArray(const std::vector &v) +{ + return QByteArray(reinterpret_cast(&v.front()), static_cast(v.size())); } inline const char *botanKeyExchangeAlgoName(const QByteArray &rfcAlgoName) @@ -91,11 +97,11 @@ inline const char *botanEmsaAlgoName(const QByteArray &rfcAlgoName) if (rfcAlgoName == SshCapabilities::PubKeyRsa) return "EMSA3(SHA-1)"; if (rfcAlgoName == SshCapabilities::PubKeyEcdsa256) - return "EMSA1_BSI(SHA-256)"; + return "EMSA1(SHA-256)"; if (rfcAlgoName == SshCapabilities::PubKeyEcdsa384) - return "EMSA1_BSI(SHA-384)"; + return "EMSA1(SHA-384)"; if (rfcAlgoName == SshCapabilities::PubKeyEcdsa521) - return "EMSA1_BSI(SHA-512)"; + return "EMSA1(SHA-512)"; throw SshClientException(SshInternalError, SSH_TR("Unexpected host key algorithm \"%1\"") .arg(QString::fromLatin1(rfcAlgoName))); } diff --git a/src/libs/ssh/sshchannel.cpp b/src/libs/ssh/sshchannel.cpp index d48622b36f..5a3d5e4d42 100644 --- a/src/libs/ssh/sshchannel.cpp +++ b/src/libs/ssh/sshchannel.cpp @@ -29,8 +29,6 @@ #include "sshlogging_p.h" #include "sshsendfacility_p.h" -#include - #include namespace QSsh { diff --git a/src/libs/ssh/sshconnection.cpp b/src/libs/ssh/sshconnection.cpp index e1f98da06d..7981a65cb9 100644 --- a/src/libs/ssh/sshconnection.cpp +++ b/src/libs/ssh/sshconnection.cpp @@ -34,13 +34,10 @@ #include "sshdirecttcpiptunnel.h" #include "sshtcpipforwardserver.h" #include "sshexception_p.h" -#include "sshinit_p.h" #include "sshkeyexchange_p.h" #include "sshlogging_p.h" #include "sshremoteprocess.h" -#include - #include #include #include @@ -94,7 +91,6 @@ bool operator!=(const SshConnectionParameters &p1, const SshConnectionParameters SshConnection::SshConnection(const SshConnectionParameters &serverInfo, QObject *parent) : QObject(parent) { - Internal::initSsh(); qRegisterMetaType("QSsh::SshError"); qRegisterMetaType("QSsh::SftpJobId"); qRegisterMetaType("QSsh::SftpFileInfo"); @@ -947,10 +943,12 @@ void SshConnectionPrivate::closeConnection(SshErrorCode sshError, disconnect(&m_timeoutTimer, 0, this, 0); m_keepAliveTimer.stop(); disconnect(&m_keepAliveTimer, 0, this, 0); - try { - m_channelManager->closeAllChannels(SshChannelManager::CloseAllAndReset); - m_sendFacility.sendDisconnectPacket(sshError, serverErrorString); - } catch (...) {} // Nothing sensible to be done here. + if (m_state != SocketConnected) { + try { + m_channelManager->closeAllChannels(SshChannelManager::CloseAllAndReset); + m_sendFacility.sendDisconnectPacket(sshError, serverErrorString); + } catch (...) {} // Nothing sensible to be done here. + } if (m_error != SshNoError) emit error(userError); if (m_state == ConnectionEstablished) diff --git a/src/libs/ssh/sshcryptofacility.cpp b/src/libs/ssh/sshcryptofacility.cpp index 7156fd801a..83a2490caa 100644 --- a/src/libs/ssh/sshcryptofacility.cpp +++ b/src/libs/ssh/sshcryptofacility.cpp @@ -33,7 +33,16 @@ #include "sshlogging_p.h" #include "sshpacket_p.h" -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include @@ -77,11 +86,9 @@ void SshAbstractCryptoFacility::recreateKeys(const SshKeyExchange &kex) if (m_sessionId.isEmpty()) m_sessionId = kex.h(); - Algorithm_Factory &af = global_state().algorithm_factory(); const QByteArray &rfcCryptAlgoName = cryptAlgoName(kex); - BlockCipher * const cipher - = af.prototype_block_cipher(botanCryptAlgoName(rfcCryptAlgoName))->clone(); - + std::unique_ptr cipher + = BlockCipher::create_or_throw(botanCryptAlgoName(rfcCryptAlgoName)); m_cipherBlockSize = static_cast(cipher->block_size()); const QByteArray ivData = generateHash(kex, ivChar(), m_cipherBlockSize); const InitializationVector iv(convertByteArray(ivData), m_cipherBlockSize); @@ -90,15 +97,15 @@ void SshAbstractCryptoFacility::recreateKeys(const SshKeyExchange &kex) const QByteArray cryptKeyData = generateHash(kex, keyChar(), keySize); SymmetricKey cryptKey(convertByteArray(cryptKeyData), keySize); Keyed_Filter * const cipherMode - = makeCipherMode(cipher, getMode(rfcCryptAlgoName), iv, cryptKey); + = makeCipherMode(cipher.release(), getMode(rfcCryptAlgoName), iv, cryptKey); m_pipe.reset(new Pipe(cipherMode)); m_macLength = botanHMacKeyLen(hMacAlgoName(kex)); const QByteArray hMacKeyData = generateHash(kex, macChar(), macLength()); SymmetricKey hMacKey(convertByteArray(hMacKeyData), macLength()); - const HashFunction * const hMacProto - = af.prototype_hash_function(botanHMacAlgoName(hMacAlgoName(kex))); - m_hMac.reset(new HMAC(hMacProto->clone())); + std::unique_ptr hashFunc + = HashFunction::create_or_throw(botanHMacAlgoName(hMacAlgoName(kex))); + m_hMac.reset(new HMAC(hashFunc.release())); m_hMac->set_key(hMacKey); } @@ -156,12 +163,12 @@ QByteArray SshAbstractCryptoFacility::generateHash(const SshKeyExchange &kex, = kex.hash()->process(convertByteArray(data), data.size()); while (key.size() < length) { SecureVector tmpKey; - tmpKey += SecureVector(convertByteArray(k), k.size()); - tmpKey += SecureVector(convertByteArray(h), h.size()); + tmpKey.insert(tmpKey.end(), k.cbegin(), k.cend()); + tmpKey.insert(tmpKey.end(), h.cbegin(), h.cend()); tmpKey += key; key += kex.hash()->process(tmpKey); } - return QByteArray(reinterpret_cast(key.begin()), length); + return QByteArray(reinterpret_cast(&key.front()), length); } void SshAbstractCryptoFacility::checkInvariant() const @@ -192,7 +199,7 @@ Keyed_Filter *SshEncryptionFacility::makeCipherMode(BlockCipher *cipher, Mode mo { switch (mode) { case CbcMode: - return new CBC_Encryption(cipher, new Null_Padding, key, iv); + return get_cipher(cipher->name() + "/CBC/NoPadding", key, iv, ENCRYPTION); case CtrMode: return makeCtrCipherMode(cipher, iv, key); } @@ -235,7 +242,7 @@ void SshEncryptionFacility::createAuthenticationKey(const QByteArray &privKeyFil if (ecdsaKey) { m_authPubKeyBlob += AbstractSshPacket::encodeString(m_authKeyAlgoName.mid(11)); // Without "ecdsa-sha2-" prefix. m_authPubKeyBlob += AbstractSshPacket::encodeString( - convertByteArray(EC2OSP(ecdsaKey->public_point(), PointGFp::UNCOMPRESSED))); + convertByteArray(ecdsaKey->public_point().encode(PointGFp::UNCOMPRESSED))); } else { foreach (const BigInt &b, pubKeyParams) m_authPubKeyBlob += AbstractSshPacket::encodeMpInt(b); @@ -249,7 +256,7 @@ bool SshEncryptionFacility::createAuthenticationKeyFromPKCS8(const QByteArray &p try { Pipe pipe; pipe.process_msg(convertByteArray(privKeyFileContents), privKeyFileContents.size()); - m_authKey.reset(PKCS8::load_key(pipe, m_rng, SshKeyPasswordRetriever())); + m_authKey.reset(PKCS8::load_key(pipe, m_rng, &get_passphrase)); if (auto * const dsaKey = dynamic_cast(m_authKey.data())) { m_authKeyAlgoName = SshCapabilities::PubKeyDss; pubKeyParams << dsaKey->group_p() << dsaKey->group_q() @@ -338,8 +345,7 @@ bool SshEncryptionFacility::createAuthenticationKeyFromOpenSSL(const QByteArray } else if (m_authKeyAlgoName == SshCapabilities::PubKeyRsa) { BigInt p, q, e, d, n; sequence.decode(n).decode(e).decode(d).decode(p).decode(q); - RSA_PrivateKey * const rsaKey = new RSA_PrivateKey(m_rng, p, q, e, d, n); - m_authKey.reset(rsaKey); + m_authKey.reset(new RSA_PrivateKey(p, q, e, d, n)); pubKeyParams << e << n; allKeyParams << pubKeyParams << p << q << d; } else { @@ -374,7 +380,7 @@ QByteArray SshEncryptionFacility::authenticationKeySignature(const QByteArray &d { Q_ASSERT(m_authKey); - QScopedPointer signer(new PK_Signer(*m_authKey, + QScopedPointer signer(new PK_Signer(*m_authKey, m_rng, botanEmsaAlgoName(m_authKeyAlgoName))); QByteArray dataToSign = AbstractSshPacket::encodeString(sessionId()) + data; QByteArray signature @@ -417,7 +423,7 @@ Keyed_Filter *SshDecryptionFacility::makeCipherMode(BlockCipher *cipher, Mode mo { switch (mode) { case CbcMode: - return new CBC_Decryption(cipher, new Null_Padding, key, iv); + return get_cipher(cipher->name() + "/CBC/NoPadding", iv, key, DECRYPTION); case CtrMode: return makeCtrCipherMode(cipher, iv, key); } diff --git a/src/libs/ssh/sshcryptofacility_p.h b/src/libs/ssh/sshcryptofacility_p.h index 2f9b64c44c..86df75764d 100644 --- a/src/libs/ssh/sshcryptofacility_p.h +++ b/src/libs/ssh/sshcryptofacility_p.h @@ -25,7 +25,13 @@ #pragma once -#include +#include +#include +#include +#include +#include +#include +#include #include #include diff --git a/src/libs/ssh/sshinit.cpp b/src/libs/ssh/sshinit.cpp deleted file mode 100644 index a76724e551..0000000000 --- a/src/libs/ssh/sshinit.cpp +++ /dev/null @@ -1,49 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ - -#include "sshinit_p.h" - -#include - -#include -#include - -namespace QSsh { -namespace Internal { - -static bool initialized = false; -static QMutex initMutex; - -void initSsh() -{ - QMutexLocker locker(&initMutex); - if (!initialized) { - Botan::LibraryInitializer::initialize("thread_safe=true"); - initialized = true; - } -} - -} // namespace Internal -} // namespace QSsh diff --git a/src/libs/ssh/sshinit_p.h b/src/libs/ssh/sshinit_p.h deleted file mode 100644 index 8fb84e27b1..0000000000 --- a/src/libs/ssh/sshinit_p.h +++ /dev/null @@ -1,32 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ - -namespace QSsh { -namespace Internal { - -void initSsh(); - -} // namespace Internal -} // namespace QSsh diff --git a/src/libs/ssh/sshkeyexchange.cpp b/src/libs/ssh/sshkeyexchange.cpp index f513454d45..3eb013f282 100644 --- a/src/libs/ssh/sshkeyexchange.cpp +++ b/src/libs/ssh/sshkeyexchange.cpp @@ -33,7 +33,18 @@ #include "sshexception_p.h" #include "sshincomingpacket_p.h" -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include @@ -148,12 +159,13 @@ void SshKeyExchange::sendNewKeysPacket(const SshIncomingPacket &dhReply, printData("K_S", reply.k_s); SecureVector encodedK; + Botan::AutoSeeded_RNG rng; if (m_dhKey) { concatenatedData += AbstractSshPacket::encodeMpInt(m_dhKey->get_y()); concatenatedData += AbstractSshPacket::encodeMpInt(reply.f); - DH_KA_Operation dhOp(*m_dhKey); - SecureVector encodedF = BigInt::encode(reply.f); - encodedK = dhOp.agree(encodedF, encodedF.size()); + Botan::PK_Key_Agreement dhOp(*m_dhKey, rng, "Raw"); + const std::vector encodedF = BigInt::encode(reply.f); + encodedK = dhOp.derive_key(m_dhKey->group_p().bytes(), encodedF).bits_of(); printData("y", AbstractSshPacket::encodeMpInt(m_dhKey->get_y())); printData("f", AbstractSshPacket::encodeMpInt(reply.f)); m_dhKey.reset(nullptr); @@ -162,8 +174,9 @@ void SshKeyExchange::sendNewKeysPacket(const SshIncomingPacket &dhReply, concatenatedData // Q_C. += AbstractSshPacket::encodeString(convertByteArray(m_ecdhKey->public_value())); concatenatedData += AbstractSshPacket::encodeString(reply.q_s); - ECDH_KA_Operation ecdhOp(*m_ecdhKey); - encodedK = ecdhOp.agree(convertByteArray(reply.q_s), reply.q_s.count()); + Botan::PK_Key_Agreement ecdhOp(*m_ecdhKey, rng, "Raw"); + encodedK = ecdhOp.derive_key(m_ecdhKey->domain().get_p().bytes(), + convertByteArray(reply.q_s), reply.q_s.count()).bits_of(); m_ecdhKey.reset(nullptr); } @@ -173,7 +186,7 @@ void SshKeyExchange::sendNewKeysPacket(const SshIncomingPacket &dhReply, concatenatedData += m_k; printData("Concatenated data", concatenatedData); - m_hash.reset(get_hash(botanHMacAlgoName(hashAlgoForKexAlgo()))); + m_hash = HashFunction::create_or_throw(botanHMacAlgoName(hashAlgoForKexAlgo())); const SecureVector &hashResult = m_hash->process(convertByteArray(concatenatedData), concatenatedData.size()); m_h = convertByteArray(hashResult); @@ -193,8 +206,7 @@ void SshKeyExchange::sendNewKeysPacket(const SshIncomingPacket &dhReply, } else { QSSH_ASSERT_AND_RETURN(m_serverHostKeyAlgo.startsWith(SshCapabilities::PubKeyEcdsaPrefix)); const EC_Group domain(SshCapabilities::oid(m_serverHostKeyAlgo)); - const PointGFp point = OS2ECP(convertByteArray(reply.q), reply.q.count(), - domain.get_curve()); + const PointGFp point = domain.OS2ECP(convertByteArray(reply.q), reply.q.count()); ECDSA_PublicKey * const ecdsaKey = new ECDSA_PublicKey(domain, point); sigKey.reset(ecdsaKey); } diff --git a/src/libs/ssh/sshkeyexchange_p.h b/src/libs/ssh/sshkeyexchange_p.h index b56597b6df..de5828292e 100644 --- a/src/libs/ssh/sshkeyexchange_p.h +++ b/src/libs/ssh/sshkeyexchange_p.h @@ -30,6 +30,8 @@ #include #include +#include + namespace Botan { class DH_PrivateKey; class ECDH_PrivateKey; @@ -59,7 +61,7 @@ public: QByteArray k() const { return m_k; } QByteArray h() const { return m_h; } - Botan::HashFunction *hash() const { return m_hash.data(); } + Botan::HashFunction *hash() const { return m_hash.get(); } QByteArray encryptionAlgo() const { return m_encryptionAlgo; } QByteArray decryptionAlgo() const { return m_decryptionAlgo; } QByteArray hMacAlgoClientToServer() const { return m_c2sHMacAlgo; } @@ -84,7 +86,7 @@ private: QByteArray m_decryptionAlgo; QByteArray m_c2sHMacAlgo; QByteArray m_s2cHMacAlgo; - QScopedPointer m_hash; + std::unique_ptr m_hash; const SshConnectionParameters m_connParams; SshSendFacility &m_sendFacility; }; diff --git a/src/libs/ssh/sshkeygenerator.cpp b/src/libs/ssh/sshkeygenerator.cpp index eb85c1aa66..38828ee97f 100644 --- a/src/libs/ssh/sshkeygenerator.cpp +++ b/src/libs/ssh/sshkeygenerator.cpp @@ -27,11 +27,20 @@ #include "sshbotanconversions_p.h" #include "sshcapabilities_p.h" +#include "sshlogging_p.h" #include "ssh_global.h" -#include "sshinit_p.h" #include "sshpacket_p.h" -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include @@ -45,7 +54,6 @@ using namespace Internal; SshKeyGenerator::SshKeyGenerator() : m_type(Rsa) { - initSsh(); } bool SshKeyGenerator::generateKeys(KeyType type, PrivateKeyFormat format, int keySize, @@ -116,8 +124,10 @@ void SshKeyGenerator::generatePkcs8KeyString(const KeyPtr &key, bool privateKey, } pipe.end_msg(); keyData->resize(static_cast(pipe.remaining(pipe.message_count() - 1))); - pipe.read(convertByteArray(*keyData), keyData->size(), - pipe.message_count() - 1); + if (pipe.read(convertByteArray(*keyData), keyData->size(), pipe.message_count() - 1) + != std::size_t(keyData->size())) { + qCWarning(sshLog) << "short read from botan pipe"; + } } void SshKeyGenerator::generateOpenSslKeyStrings(const KeyPtr &key) @@ -146,7 +156,7 @@ void SshKeyGenerator::generateOpenSslPublicKeyString(const KeyPtr &key) } case Ecdsa: { const auto ecdsaKey = key.dynamicCast(); - q = convertByteArray(EC2OSP(ecdsaKey->public_point(), PointGFp::UNCOMPRESSED)); + q = convertByteArray(ecdsaKey->public_point().encode(PointGFp::UNCOMPRESSED)); keyId = SshCapabilities::ecdsaPubKeyAlgoForKeyWidth( static_cast(ecdsaKey->private_value().bytes())); break; diff --git a/src/libs/ssh/sshkeypasswordretriever.cpp b/src/libs/ssh/sshkeypasswordretriever.cpp index 8f13362363..6631404a03 100644 --- a/src/libs/ssh/sshkeypasswordretriever.cpp +++ b/src/libs/ssh/sshkeypasswordretriever.cpp @@ -34,20 +34,16 @@ namespace QSsh { namespace Internal { -std::string SshKeyPasswordRetriever::get_passphrase(const std::string &, const std::string &, - UI_Result &result) const +std::string get_passphrase() { const bool hasGui = dynamic_cast(QApplication::instance()); if (hasGui) { - bool ok; const QString &password = QInputDialog::getText(0, QCoreApplication::translate("QSsh::Ssh", "Password Required"), QCoreApplication::translate("QSsh::Ssh", "Please enter the password for your private key."), - QLineEdit::Password, QString(), &ok); - result = ok ? OK : CANCEL_ACTION; + QLineEdit::Password, QString()); return std::string(password.toLocal8Bit().data()); } else { - result = OK; std::string password; std::cout << "Please enter the password for your private key (set echo off beforehand!): " << std::flush; std::cin >> password; diff --git a/src/libs/ssh/sshkeypasswordretriever_p.h b/src/libs/ssh/sshkeypasswordretriever_p.h index 15301feb67..7d7bc76e69 100644 --- a/src/libs/ssh/sshkeypasswordretriever_p.h +++ b/src/libs/ssh/sshkeypasswordretriever_p.h @@ -25,19 +25,12 @@ #pragma once -#include - #include namespace QSsh { namespace Internal { -class SshKeyPasswordRetriever : public Botan::User_Interface -{ -public: - std::string get_passphrase(const std::string &what, const std::string &source, - UI_Result &result) const; -}; +std::string get_passphrase(); } // namespace Internal } // namespace QSsh diff --git a/src/libs/ssh/sshpacketparser_p.h b/src/libs/ssh/sshpacketparser_p.h index b57f22f084..db63f0a1b9 100644 --- a/src/libs/ssh/sshpacketparser_p.h +++ b/src/libs/ssh/sshpacketparser_p.h @@ -25,7 +25,7 @@ #pragma once -#include +#include #include #include diff --git a/src/libs/ssh/sshremoteprocess.cpp b/src/libs/ssh/sshremoteprocess.cpp index 5a875d1f10..3b81e0409c 100644 --- a/src/libs/ssh/sshremoteprocess.cpp +++ b/src/libs/ssh/sshremoteprocess.cpp @@ -31,8 +31,6 @@ #include "sshlogging_p.h" #include "sshsendfacility_p.h" -#include - #include #include -- cgit v1.2.1 From 2b877246cae7704f521689d66d5d825e84a3d1bf Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Thu, 19 Jul 2018 12:52:21 +0200 Subject: Doc: Add a note about debugger error on Android Qt Creator cannot debug applications on Android devices if Android Studio is running. Change-Id: I57de367ed0d4effe7b095fa66318408d868496d1 Reviewed-by: hjk --- doc/src/android/androiddev.qdoc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/doc/src/android/androiddev.qdoc b/doc/src/android/androiddev.qdoc index 13c449efea..d4f3421d5b 100644 --- a/doc/src/android/androiddev.qdoc +++ b/doc/src/android/androiddev.qdoc @@ -292,5 +292,9 @@ \note Select a \l{glossary-build-config}{debug build configuration} to build the application for debugging. -*/ + \note \QC cannot debug applications on Android devices if Android Studio is + running. If the following message is displayed in the \uicontrol Output + pane, close Android Studio and try again: \e {Ignoring second debugger - + accepting and dropping.} +*/ -- cgit v1.2.1 From 94fb8efab1d8579dd6fc2f52040ea77a74d521f8 Mon Sep 17 00:00:00 2001 From: Robert Loehning Date: Wed, 8 Aug 2018 17:44:27 +0200 Subject: Squish: Remove old default target parameters Change-Id: I72153c535ae0670cb4bfa061f34659bc7faee001 Reviewed-by: Christian Stenger --- tests/system/shared/project.py | 29 +++++++---------------------- tests/system/suite_APTW/tst_APTW03/test.py | 8 +++----- tests/system/suite_CSUP/tst_CSUP03/test.py | 3 ++- 3 files changed, 12 insertions(+), 28 deletions(-) diff --git a/tests/system/shared/project.py b/tests/system/shared/project.py index 922e5befe9..a8305e11a4 100644 --- a/tests/system/shared/project.py +++ b/tests/system/shared/project.py @@ -342,26 +342,15 @@ def createEmptyQtProject(workingDir=None, projectName=None, targets=Targets.desk __createProjectHandleLastPage__() return projectName -def createNewNonQtProject(workingDir=None, projectName=None, target=[Targets.DESKTOP_4_8_7_DEFAULT], - plainC=False, cmake=False, qbs=False): +def createNewNonQtProject(workingDir, projectName, target, plainC=False, buildSystem="qmake"): if plainC: template = "Plain C Application" else: template = "Plain C++ Application" available = __createProjectOrFileSelectType__(" Non-Qt Project", template) - if workingDir == None: - workingDir = tempDir() projectName = __createProjectSetNameAndPath__(workingDir, projectName) - buildSystem = "qmake" - if qbs: - buildSystem = "Qbs" - if cmake: - test.warning("Unsupported combination, at least one of parameters cmake and qbs must " - "be False, ignoring the value of cmake") - elif cmake: - buildSystem = "CMake" selectFromCombo("{name='BuildSystem' type='QComboBox' visible='1'}", buildSystem) clickButton(waitForObject(":Next_QPushButton")) @@ -370,9 +359,8 @@ def createNewNonQtProject(workingDir=None, projectName=None, target=[Targets.DES __createProjectHandleLastPage__() return projectName -def createNewCPPLib(projectDir = None, projectName = None, className = None, fromWelcome = False, - target = [Targets.DESKTOP_4_8_7_DEFAULT], isStatic = False, modules = ["QtCore"]): - available = __createProjectOrFileSelectType__(" Library", "C++ Library", fromWelcome, True) +def createNewCPPLib(projectDir, projectName, className, target, isStatic): + available = __createProjectOrFileSelectType__(" Library", "C++ Library", False, True) if isStatic: libType = LibType.STATIC else: @@ -383,16 +371,13 @@ def createNewCPPLib(projectDir = None, projectName = None, className = None, fro __chooseTargets__(target, available) snooze(1) clickButton(waitForObject(":Next_QPushButton")) - __createProjectHandleModuleSelection__(modules) + __createProjectHandleModuleSelection__(["QtCore"]) className = __createProjectHandleClassInformation__(className) __createProjectHandleLastPage__() return projectName, className -def createNewQtPlugin(projectDir=None, projectName=None, className=None, fromWelcome=False, - target=[Targets.DESKTOP_4_8_7_DEFAULT], baseClass="QGenericPlugin"): - available = __createProjectOrFileSelectType__(" Library", "C++ Library", fromWelcome, True) - if projectDir == None: - projectDir = tempDir() +def createNewQtPlugin(projectDir, projectName, className, target, baseClass="QGenericPlugin"): + available = __createProjectOrFileSelectType__(" Library", "C++ Library", False, True) projectName = __createProjectSetNameAndPath__(projectDir, projectName, False, LibType.QT_PLUGIN) __chooseTargets__(target, available) snooze(1) @@ -407,7 +392,7 @@ def createNewQtPlugin(projectDir=None, projectName=None, className=None, fromWel # parameter additionalFunc function to be executed inside the detailed view of each chosen kit # if present, 'Details' button will be clicked, function will be executed, # 'Details' button will be clicked again -def __chooseTargets__(targets=[Targets.DESKTOP_4_8_7_DEFAULT], availableTargets=None, additionalFunc=None): +def __chooseTargets__(targets, availableTargets=None, additionalFunc=None): if availableTargets != None: available = availableTargets else: diff --git a/tests/system/suite_APTW/tst_APTW03/test.py b/tests/system/suite_APTW/tst_APTW03/test.py index ca1378196a..f3cf82f169 100644 --- a/tests/system/suite_APTW/tst_APTW03/test.py +++ b/tests/system/suite_APTW/tst_APTW03/test.py @@ -57,8 +57,8 @@ def handleInsertVirtualFunctions(expected): def checkSimpleCppLib(projectName, static): projectName, className = createNewCPPLib(tempDir(), projectName, "MyClass", - target=Targets.desktopTargetClasses(), - isStatic=static) + Targets.desktopTargetClasses(), + static) for kit, config in iterateBuildConfigs("Release"): verifyBuildConfig(kit, config, False, True) invokeMenuItem('Build', 'Build Project "%s"' % projectName) @@ -79,10 +79,8 @@ def main(): checkSimpleCppLib("SampleApp1", False) checkSimpleCppLib("SampleApp2", True) - # Qt Plugin needs Qt4.8 for QGenericPlugin which is tested by default - targets = Targets.desktopTargetClasses() projectName, className = createNewQtPlugin(tempDir(), "SampleApp3", "MyPlugin", - target=targets) + Targets.desktopTargetClasses()) virtualFunctionsAdded = False for kit, config in iterateBuildConfigs("Debug"): is487Kit = kit in (Targets.DESKTOP_4_8_7_DEFAULT, Targets.EMBEDDED_LINUX) diff --git a/tests/system/suite_CSUP/tst_CSUP03/test.py b/tests/system/suite_CSUP/tst_CSUP03/test.py index 21bc53f5c2..c82e9a32ee 100644 --- a/tests/system/suite_CSUP/tst_CSUP03/test.py +++ b/tests/system/suite_CSUP/tst_CSUP03/test.py @@ -83,7 +83,8 @@ def main(): continue if not startCreator(useClang): continue - projectName = createNewNonQtProject() + projectName = createNewNonQtProject(tempDir(), "project_csup03", + [Targets.DESKTOP_4_8_7_DEFAULT]) checkCodeModelSettings(useClang) openDocument("%s.Sources.main\\.cpp" % projectName) editor = getEditorForFileSuffix("main.cpp") -- cgit v1.2.1 From 8c1a2eb2c01873235b76bb7ababe0821632c9eda Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Fri, 10 Aug 2018 08:16:19 +0200 Subject: Squish: Fix passing argument to helper function The code of the helper function has changed and what worked before by pure coincidence now fell apart. Passing a list to a function that tries to use it as a key for a dict results in an exception as lists are not hashable. The code is likely to change by adding a newer kit. This patch just makes the current state work without crashing instead of adding functionality that is not yet used. Amends aed1616b351e909b870e5caccd544b66b16000bf. Change-Id: I6e8a6490988700de14596ba981b5e6900133a79d Reviewed-by: Robert Loehning --- tests/system/suite_qtquick/tst_qtquick_creation/test.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/system/suite_qtquick/tst_qtquick_creation/test.py b/tests/system/suite_qtquick/tst_qtquick_creation/test.py index 3eda2c6e0e..70b2497edd 100644 --- a/tests/system/suite_qtquick/tst_qtquick_creation/test.py +++ b/tests/system/suite_qtquick/tst_qtquick_creation/test.py @@ -33,10 +33,10 @@ def main(): available = [("5.6", False), ("5.6", True)] for qtVersion, controls in available: - targ = [Targets.DESKTOP_5_6_1_DEFAULT] + targ = Targets.DESKTOP_5_6_1_DEFAULT # using a temporary directory won't mess up a potentially existing workingDir = tempDir() - checkedTargets = createNewQtQuickApplication(workingDir, targets=targ, + checkedTargets = createNewQtQuickApplication(workingDir, targets=[targ], minimumQtVersion=qtVersion, withControls = controls)[0] if len(checkedTargets) == 0: -- cgit v1.2.1 From efcec2f96c7c1ec2dedd33a057b2671a590a5200 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Fri, 10 Aug 2018 12:52:48 +0200 Subject: Update qbs submodule To HEAD of 1.12 branch. Change-Id: Idfc6e54062cdc9f3cc5edebb9f7d2aab4c0db105 Reviewed-by: Joerg Bornemann --- src/shared/qbs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shared/qbs b/src/shared/qbs index 66131652f1..349baf7988 160000 --- a/src/shared/qbs +++ b/src/shared/qbs @@ -1 +1 @@ -Subproject commit 66131652f178cd1605b8a2c0ba7023392e13ad5a +Subproject commit 349baf79883a96fdd85325a2900997fbf574f9a8 -- cgit v1.2.1 From d8c81edfad0bc58775ccb5519b0ac79f7af73524 Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Fri, 10 Aug 2018 14:49:27 +0200 Subject: Doc: Remove a note that is no longer applicable Compiling the library should not be necessary since the QML debugging library has been added to Qt. Change-Id: Id1d31cb40068fcfb7ff868ae80e3f3c9bc4b5de7 Reviewed-by: hjk --- doc/src/debugger/qtquick-debugging.qdoc | 3 --- 1 file changed, 3 deletions(-) diff --git a/doc/src/debugger/qtquick-debugging.qdoc b/doc/src/debugger/qtquick-debugging.qdoc index a708a82c34..5686bb44c6 100644 --- a/doc/src/debugger/qtquick-debugging.qdoc +++ b/doc/src/debugger/qtquick-debugging.qdoc @@ -57,9 +57,6 @@ \li Debugging is enabled by default for Qt 5.0, or later. - You might have to compile the library first, by selecting the - \uicontrol Compile link. - \image qml-link-debugging-library.png "Build Steps" \note Debugging requires opening a socket at a TCP port, -- cgit v1.2.1 From 13fbd1f867f5de6b665134c2d3783ed1d59cce89 Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Mon, 13 Aug 2018 09:38:27 +0200 Subject: Botan: Fix compile if documentation tools are present Change-Id: If5adae5840cca75e3a1429922f48ea25b9903dc3 Reviewed-by: Eike Ziller Reviewed-by: Christian Kandeler --- src/libs/botan/botan.pro | 2 +- src/libs/botan/botan.qbs | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/libs/botan/botan.pro b/src/libs/botan/botan.pro index 91ce2e2995..04feb8d329 100644 --- a/src/libs/botan/botan.pro +++ b/src/libs/botan/botan.pro @@ -22,7 +22,7 @@ BOTAN_MODULES = aes aes_ssse3 auto_rng bigint block cbc ctr des dh dsa ec_group filters hmac mode_pad pubkey rsa sha1 sha1_sse2 sha1_x86 sha2_32 sha2_32_x86 \ sha2_64 simd system_rng,emsa_pkcs1,pbes2,pbkdf2 OTHER_FLAGS = --amalgamation --minimized-build --disable-shared \ - --enable-modules=$$join(BOTAN_MODULES,",",,) + --enable-modules=$$join(BOTAN_MODULES,",",,) --without-documentation mingw { BOTAN_OS_SWITCH = "--os=mingw" OTHER_FLAGS += --without-stack-protector diff --git a/src/libs/botan/botan.qbs b/src/libs/botan/botan.qbs index fa492b5734..04acfad048 100644 --- a/src/libs/botan/botan.qbs +++ b/src/libs/botan/botan.qbs @@ -34,7 +34,8 @@ Product { fileTags: "hpp" } prepare: { - var args = [input.filePath, "--amalgamation", "--minimized-build", "--disable-shared"]; + var args = [input.filePath, "--amalgamation", "--minimized-build", "--disable-shared", + "--without-documentation"]; var modules = "aes,aes_ssse3,auto_rng,bigint,block,cbc,ctr,des,dh,dsa,ec_group,ecdh," + "ecdsa,entropy,filters,hmac,mode_pad,pubkey,rsa,sha1,sha1_sse2,sha1_x86," + "sha2_32,sha2_32_x86,sha2_64,simd,system_rng,emsa_pkcs1,pbes2,pbkdf2"; -- cgit v1.2.1 From b40b5cb79c1f8b4289fcc6ca779cc40ea5d546e0 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Mon, 13 Aug 2018 09:01:53 +0200 Subject: Fix Botan build on macOS Since some Xcode version, running clang directly from the Toolchains directory requires explicitly passing the sysroot to use. If that is not done, inclusion of some standard headers like string.h fails. Change-Id: I640eca41d4132354f1091a7514586cb582e5d05c Reviewed-by: Eike Ziller Reviewed-by: Christian Stenger --- src/libs/botan/botan.pro | 2 +- src/libs/botan/botan.qbs | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/libs/botan/botan.pro b/src/libs/botan/botan.pro index 04feb8d329..48b3b2ea35 100644 --- a/src/libs/botan/botan.pro +++ b/src/libs/botan/botan.pro @@ -30,7 +30,7 @@ mingw { BOTAN_CXX_FLAGS = msvc: BOTAN_CXX_FLAGS += /wd4127 /wd4244 /wd4250 /wd4267 /wd4334 /wd4702 /wd4996 else: BOTAN_CXX_FLAGS += -Wno-unused-parameter -macos: BOTAN_CXX_FLAGS += -mmacosx-version-min=$$QMAKE_MACOSX_DEPLOYMENT_TARGET +macos: BOTAN_CXX_FLAGS += -mmacosx-version-min=$$QMAKE_MACOSX_DEPLOYMENT_TARGET -isysroot $$shell_quote($$QMAKE_MAC_SDK.macosx.Path) unix: BOTAN_CXX_FLAGS += -fPIC !isEmpty(BOTAN_CXX_FLAGS): OTHER_FLAGS += --cxxflags=$$shell_quote($$BOTAN_CXX_FLAGS) win32: OTHER_FLAGS += --link-method=hardlink diff --git a/src/libs/botan/botan.qbs b/src/libs/botan/botan.qbs index 04acfad048..3872e900ad 100644 --- a/src/libs/botan/botan.qbs +++ b/src/libs/botan/botan.qbs @@ -6,6 +6,7 @@ Product { type: ["staticlibrary", "hpp"] Depends { name: "cpp" } Depends { name: "qtc" } + Depends { name: "xcode"; condition: qbs.toolchain.contains("xcode") } files: "update-botan.sh" Group { name: "Botan sources" @@ -47,8 +48,11 @@ Product { } else if (product.qbs.toolchain.contains("gcc")) cxxFlags.push("-Wno-unused-parameter"); - if (product.qbs.targetOS.contains("macos")) + if (product.qbs.targetOS.contains("macos")) { cxxFlags.push("-mmacosx-version-min=" + project.minimumMacosVersion); + if (product.qbs.toolchain.contains("xcode")) + cxxFlags.push("-isysroot", product.xcode.sdkPath); + } if (product.qbs.targetOS.contains("unix")) cxxFlags.push("-fPIC"); if (cxxFlags.length > 0) -- cgit v1.2.1 From cfbc780a20af30f143286465c7c38135d87a5491 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Tue, 7 Aug 2018 14:49:00 +0200 Subject: Fix Linux WMClass also for standalone desktop file Task-number: QTCREATORBUG-14707 Change-Id: I55a208bc6af58a067029a02eb8f6d114af8dd007 Reviewed-by: Christian Stenger --- dist/org.qt-project.qtcreator.desktop | 1 + 1 file changed, 1 insertion(+) diff --git a/dist/org.qt-project.qtcreator.desktop b/dist/org.qt-project.qtcreator.desktop index 26c0aa58bb..034721891d 100644 --- a/dist/org.qt-project.qtcreator.desktop +++ b/dist/org.qt-project.qtcreator.desktop @@ -5,6 +5,7 @@ Name=Qt Creator GenericName=C++ IDE for developing Qt applications X-KDE-StartupNotify=true Icon=QtProject-qtcreator +StartupWMClass=qtcreator Terminal=false Categories=Development;IDE;Qt; MimeType= text/x-c++src;text/x-c++hdr;text/x-xsrc;application/x-designer;application/vnd.qt.qmakeprofile;application/vnd.qt.xml.resource; -- cgit v1.2.1 From 493c5396ff1d1938b8614f42129355c37379a4ef Mon Sep 17 00:00:00 2001 From: David Schulz Date: Tue, 14 Aug 2018 06:55:56 +0200 Subject: GenericHighlighter: check text color against background The kate syntax highlighter format allows to directly assign a color for a specific item. This could result in a bad contrast ratio between text and background. Check the contrast ratio according to W3C Recommendation and apply if it exceeds the minimum contrast ratio for large text. (https://www.w3.org/TR/2008/REC-WCAG20-20081211/#visual-audio-contrast- contrast) Task-number: QTCREATORBUG-20919 Change-Id: If5a5d09224446df72f31027cd30e50088179d6d7 Reviewed-by: Christian Stenger --- .../texteditor/generichighlighter/highlighter.cpp | 42 +++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/src/plugins/texteditor/generichighlighter/highlighter.cpp b/src/plugins/texteditor/generichighlighter/highlighter.cpp index fd875eae28..055f390261 100644 --- a/src/plugins/texteditor/generichighlighter/highlighter.cpp +++ b/src/plugins/texteditor/generichighlighter/highlighter.cpp @@ -498,6 +498,43 @@ void Highlighter::handleContextChange(const QString &contextName, changeContext(contextName, definition, setCurrent); } + +static double luminance(const QColor &color) +{ + // calculate the luminance based on + // https://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef + auto val = [](const double &colorVal) { + return colorVal < 0.03928 ? colorVal / 12.92 : std::pow((colorVal + 0.055) / 1.055, 2.4); + }; + + static QHash cache; + QHash::iterator it = cache.find(color.rgb()); + if (it == cache.end()) { + it = cache.insert(color.rgb(), 0.2126 * val(color.redF()) + + 0.7152 * val(color.greenF()) + + 0.0722 * val(color.blueF())); + } + return it.value(); +} + +static float contrastRatio(const QColor &color1, const QColor &color2) +{ + // calculate the contrast ratio based on + // https://www.w3.org/TR/2008/REC-WCAG20-20081211/#contrast-ratiodef + auto contrast = (luminance(color1) + 0.05) / (luminance(color2) + 0.05); + if (contrast < 1) + return 1 / contrast; + return contrast; +} + + +static bool isReadableOn(const QColor &background, const QColor &foreground) +{ + // following the W3C Recommendation on contrast for large Text + // https://www.w3.org/TR/2008/REC-WCAG20-20081211/#contrast-ratiodef + return contrastRatio(background, foreground) > 3; +} + void Highlighter::applyFormat(int offset, int count, const QString &itemDataName, @@ -526,7 +563,10 @@ void Highlighter::applyFormat(int offset, // strategy). This is because the highlighter does not really know on which // definition(s) it is working. Since not many item data specify customizations I // think this approach would fit better. If there are other ideas... - if (itemData->color().isValid()) + QBrush bg = format.background(); + if (bg.style() == Qt::NoBrush) + bg = formatForCategory(C_TEXT).background(); + if (itemData->color().isValid() && isReadableOn(bg.color(), itemData->color())) format.setForeground(itemData->color()); if (itemData->isItalicSpecified()) format.setFontItalic(itemData->isItalic()); -- cgit v1.2.1 From 5a3a432396a086041ebf81dd84204f1b630e64bb Mon Sep 17 00:00:00 2001 From: Hannes Domani Date: Sun, 12 Aug 2018 15:53:57 +0200 Subject: Valgrind: Fix heob check if executable exists Task-number: QTCREATORBUG-20938 Change-Id: Id1c3cbf610b97a13209e6a767c5e881e9be18ac7 Reviewed-by: hjk Reviewed-by: Eike Ziller --- src/plugins/valgrind/memchecktool.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/plugins/valgrind/memchecktool.cpp b/src/plugins/valgrind/memchecktool.cpp index fc1b009637..6078cd240c 100644 --- a/src/plugins/valgrind/memchecktool.cpp +++ b/src/plugins/valgrind/memchecktool.cpp @@ -780,7 +780,8 @@ void MemcheckTool::heobAction() TaskHub::requestPopup(); return; } - if (!QFile::exists(executable)) { + if (!QFile::exists(executable) + && !QFile::exists(Utils::HostOsInfo::withExecutableSuffix(executable))) { const QString msg = tr("Heob: Cannot find %1.").arg(executable); TaskHub::addTask(Task::Error, msg, Debugger::Constants::ANALYZERTASK_ID); TaskHub::requestPopup(); -- cgit v1.2.1 From 24f33dc4829d74505e1450c27943a2a03248bac3 Mon Sep 17 00:00:00 2001 From: Robert Loehning Date: Tue, 24 Jul 2018 11:49:01 +0200 Subject: Squish: Update Creator's sources to v4.7.0 Task-number: QTCREATORBUG-20344 Change-Id: I7664f2f1b9f9412b9564f192319f9ed832dc142a Reviewed-by: Christian Stenger --- tests/system/README | 2 +- .../testdata/projecttree_creator.tsv | 4425 +++++++++++----- .../suite_general/tst_openqt_creator/test.py | 2 +- .../testdata/projecttree_creator.tsv | 5261 +++++++++++++++++--- 4 files changed, 7668 insertions(+), 2022 deletions(-) diff --git a/tests/system/README b/tests/system/README index 9988635940..31712b6179 100644 --- a/tests/system/README +++ b/tests/system/README @@ -53,7 +53,7 @@ Fourth - you'll have to provide some additional repositories (and for the hookin These additional repositories are located inside ~/squish-data or C:\Users\\squish-data (depending on the OS you're on). You can also just provide them inside a different folder and specify the folder with the environment variable SYSTEST_SRCPATH. This folder must contain the following: - * a QtCreator repository (or source copy) of tag v4.4.1 named 'creator' including the submodule src/shared/qbs + * a QtCreator repository (or source copy) of tag v4.7.0 named 'creator' including the submodule src/shared/qbs * a subfolder called 'creator-test-data' * a speedcrunch 0.11 repository (or source copy) inside 'creator-test-data' named 'speedcrunch' * additional Squish versions for hooking into subprocesses inside different folders inside 'creator-test-data' following the information below diff --git a/tests/system/suite_general/tst_opencreator_qbs/testdata/projecttree_creator.tsv b/tests/system/suite_general/tst_opencreator_qbs/testdata/projecttree_creator.tsv index 59f46f7a87..1ac1dac7fd 100644 --- a/tests/system/suite_general/tst_opencreator_qbs/testdata/projecttree_creator.tsv +++ b/tests/system/suite_general/tst_opencreator_qbs/testdata/projecttree_creator.tsv @@ -92,87 +92,208 @@ "qtcreator-dev.qdocconf" "4" "qtcreator-documentation.qdoc" "4" "qtcreator-ui-text.qdoc" "4" -"qbs documentation" "1" -"doc.qbs:3" "2" -"main qdocconf file" "2" -"doc.qbs:18" "3" -"qbs.qdocconf" "3" -"config" "2" -"macros.qdocconf" "3" -"qbs-project.qdocconf" "3" -"reference" "2" -"items" "3" -"convenience" "4" -"androidapk.qdoc" "5" -"appleapplicationdiskimage.qdoc" "5" -"applediskimage.qdoc" "5" -"application.qdoc" "5" -"applicationextension.qdoc" "5" -"autotestrunner.qdoc" "5" -"cppapplication.qdoc" "5" -"dynamiclibrary.qdoc" "5" -"innosetup.qdoc" "5" -"installpackage.qdoc" "5" -"javaclasscollection.qdoc" "5" -"javajarfile.qdoc" "5" -"loadablemodule.qdoc" "5" -"qtapplication.qdoc" "5" -"qtguiapplication.qdoc" "5" -"staticlibrary.qdoc" "5" -"xpcservice.qdoc" "5" -"language" "4" -"artifact.qdoc" "5" -"depends.qdoc" "5" -"export.qdoc" "5" -"filetagger.qdoc" "5" -"group.qbs" "5" -"group.qdoc" "5" -"module.qdoc" "5" -"parameter.qdoc" "5" -"parameters.qdoc" "5" -"probe.qdoc" "5" -"product.qdoc" "5" -"project.qdoc" "5" -"properties.qdoc" "5" -"propertyoptions.qdoc" "5" -"rule.qdoc" "5" -"scanner.qdoc" "5" -"subproject.qdoc" "5" -"jsextensions" "3" -"jsextension-environment.qdoc" "4" -"jsextension-file.qdoc" "4" -"jsextension-fileinfo.qdoc" "4" -"jsextension-process.qdoc" "4" -"jsextension-propertylist.qdoc" "4" -"jsextension-temporarydir.qdoc" "4" -"jsextension-textfile.qdoc" "4" -"jsextension-utilities.qdoc" "4" -"jsextensions-general.qdoc" "4" -"modules" "3" -"android-ndk-module.qdoc" "4" -"android-sdk-module.qdoc" "4" -"archiver-module.qdoc" "4" -"bundle-module.qdoc" "4" -"cpp-module.qdoc" "4" -"dmg-module.qdoc" "4" -"ib-module.qdoc" "4" -"innosetup-module.qdoc" "4" -"java-module.qdoc" "4" -"lexyacc-module.qdoc" "4" -"nodejs-module.qdoc" "4" -"nsis-module.qdoc" "4" -"qbs-module.qdoc" "4" -"qnx-module.qdoc" "4" -"qt-modules.qdoc" "4" -"typescript-module.qdoc" "4" -"wix-module.qdoc" "4" -"xcode-module.qdoc" "4" -"commands.qdoc" "3" -"list-of-tools.qdoc" "3" -"reference.qdoc" "3" -"external-resources.qdoc" "2" -"howtos.qdoc" "2" -"qbs.qdoc" "2" +"doc" "1" +"doc.qbs:5" "2" +"qbs documentation" "2" +"doc.qbs:8" "3" +"fix-imports script" "3" +"doc.qbs:37" "4" +"fix-qmlimports.py" "4" +"main qdocconf file" "3" +"doc.qbs:32" "4" +"qbs.qdocconf" "4" +"README" "4" +"config" "3" +"style" "4" +"qt5-sidebar.html" "5" +"macros.qdocconf" "4" +"qbs-project.qdocconf" "4" +"images" "3" +"qbs-build-process.png" "4" +"qbs-dmg.png" "4" +"qbs-settings-gui.png" "4" +"reference" "3" +"cli" "4" +"builtin" "5" +"cli-build.qdoc" "6" +"cli-clean.qdoc" "6" +"cli-dump-nodes-tree.qdoc" "6" +"cli-generate.qdoc" "6" +"cli-help.qdoc" "6" +"cli-install.qdoc" "6" +"cli-list-products.qdoc" "6" +"cli-resolve.qdoc" "6" +"cli-run.qdoc" "6" +"cli-shell.qdoc" "6" +"cli-status.qdoc" "6" +"cli-update-timestamps.qdoc" "6" +"cli-version.qdoc" "6" +"tools" "5" +"cli-config-ui.qdoc" "6" +"cli-config.qdoc" "6" +"cli-create-project.qdoc" "6" +"cli-setup-android.qdoc" "6" +"cli-setup-qt.qdoc" "6" +"cli-setup-toolchains.qdoc" "6" +"cli-options.qdocinc" "5" +"cli-parameters.qdocinc" "5" +"cli.qdoc" "5" +"items" "4" +"convenience" "5" +"androidapk.qdoc" "6" +"appleapplicationdiskimage.qdoc" "6" +"applediskimage.qdoc" "6" +"application.qdoc" "6" +"applicationextension.qdoc" "6" +"autotestrunner.qdoc" "6" +"cppapplication.qdoc" "6" +"dynamiclibrary.qdoc" "6" +"innosetup.qdoc" "6" +"installpackage.qdoc" "6" +"javaclasscollection.qdoc" "6" +"javajarfile.qdoc" "6" +"loadablemodule.qdoc" "6" +"qtapplication.qdoc" "6" +"qtguiapplication.qdoc" "6" +"staticlibrary.qdoc" "6" +"xpcservice.qdoc" "6" +"language" "5" +"artifact.qdoc" "6" +"depends.qdoc" "6" +"export.qdoc" "6" +"filetagger.qdoc" "6" +"group.qbs" "6" +"group.qdoc" "6" +"module.qdoc" "6" +"parameter.qdoc" "6" +"parameters.qdoc" "6" +"probe.qdoc" "6" +"product.qdoc" "6" +"profile.qdoc" "6" +"project.qdoc" "6" +"properties.qdoc" "6" +"propertyoptions.qdoc" "6" +"rule.qdoc" "6" +"scanner.qdoc" "6" +"subproject.qdoc" "6" +"jsextensions" "4" +"jsextension-binaryfile.qdoc" "5" +"jsextension-environment.qdoc" "5" +"jsextension-file.qdoc" "5" +"jsextension-fileinfo.qdoc" "5" +"jsextension-process.qdoc" "5" +"jsextension-propertylist.qdoc" "5" +"jsextension-temporarydir.qdoc" "5" +"jsextension-textfile.qdoc" "5" +"jsextension-utilities.qdoc" "5" +"jsextension-xml.qdoc" "5" +"jsextensions-general.qdoc" "5" +"modules" "4" +"android-ndk-module.qdoc" "5" +"android-sdk-module.qdoc" "5" +"archiver-module.qdoc" "5" +"bundle-module.qdoc" "5" +"cpp-module.qdoc" "5" +"cpufeatures-module.qdoc" "5" +"dmg-module.qdoc" "5" +"exporter-pkgconfig-module.qdoc" "5" +"exporter-qbs-module.qdoc" "5" +"ib-module.qdoc" "5" +"ico-module.qdoc" "5" +"innosetup-module.qdoc" "5" +"java-module.qdoc" "5" +"lexyacc-module.qdoc" "5" +"nodejs-module.qdoc" "5" +"nsis-module.qdoc" "5" +"qbs-module.qdoc" "5" +"qnx-module.qdoc" "5" +"qt-core-module.qdoc" "5" +"qt-dbus-module.qdoc" "5" +"qt-declarative-module.qdoc" "5" +"qt-gui-module.qdoc" "5" +"qt-modules.qdoc" "5" +"qt-qml-module.qdoc" "5" +"qt-quick-module.qdoc" "5" +"qt-scxml-module.qdoc" "5" +"typescript-module.qdoc" "5" +"vcs-module.qdoc" "5" +"wix-module.qdoc" "5" +"xcode-module.qdoc" "5" +"commands.qdoc" "4" +"reference.qdoc" "4" +"targets" "3" +"qbs-target-android.qdoc" "4" +"qbs-target-apple-common.qdocinc" "4" +"qbs-target-integrity.qdoc" "4" +"qbs-target-ios.qdoc" "4" +"qbs-target-linux.qdoc" "4" +"qbs-target-macos.qdoc" "4" +"qbs-target-platforms.qdoc" "4" +"qbs-target-qnx.qdoc" "4" +"qbs-target-tvos.qdoc" "4" +"qbs-target-vxworks.qdoc" "4" +"qbs-target-watchos.qdoc" "4" +"qbs-target-windows.qdoc" "4" +"templates" "3" +"images" "4" +"arrow.png" "5" +"arrow_down.png" "5" +"bg_l.png" "5" +"bg_l_blank.png" "5" +"bg_ll_blank.png" "5" +"bg_r.png" "5" +"bg_ul_blank.png" "5" +"bgrContent.png" "5" +"blu_dot.png" "5" +"box_bg.png" "5" +"breadcrumb.png" "5" +"btn_next.png" "5" +"btn_prev.png" "5" +"bullet_dn.png" "5" +"bullet_gt.png" "5" +"bullet_sq.png" "5" +"bullet_up.png" "5" +"feedbackground.png" "5" +"header.png" "5" +"header_bg.png" "5" +"home.png" "5" +"horBar.png" "5" +"ico_note.png" "5" +"ico_note_attention.png" "5" +"ico_out.png" "5" +"page.png" "5" +"page_bg.png" "5" +"qt_icon.png" "5" +"spinner.gif" "5" +"sprites-combined.png" "5" +"scripts" "4" +"functions.js" "5" +"jquery.js" "5" +"narrow.js" "5" +"superfish.js" "5" +"style" "4" +"narrow.css" "5" +"offline.css" "5" +"style.css" "5" +"style_ie6.css" "5" +"style_ie7.css" "5" +"style_ie8.css" "5" +"superfish.css" "5" +"superfish_skin.css" "5" +"classic.css" "3" +"external-resources.qdoc" "3" +"fixnavi.pl" "3" +"howtos.qdoc" "3" +"qbs-online.qdocconf" "3" +"qbs.qdoc" "3" +"qbs man page" "2" +"man.qbs:8" "3" +"additional sections" "3" +"man.qbs:25" "4" +"see-also.h2m" "4" +"man page" "3" +"man.qbs:18" "4" +"qbs.1" "4" "user doc offline" "1" "doc.qbs:17" "2" "main qdocconf file" "2" @@ -183,6 +304,7 @@ "cpu-usage-analyzer.qdoc" "4" "creator-analyze.qdoc" "4" "creator-clang-static-analyzer.qdoc" "4" +"creator-heob.qdoc" "4" "creator-valgrind-overview.qdoc" "4" "creator-valgrind.qdoc" "4" "qtquick-profiler.qdoc" "4" @@ -196,6 +318,8 @@ "creator-projects-cmake-building.qdocinc" "4" "creator-projects-cmake-deploying.qdocinc" "4" "creator-projects-cmake.qdoc" "4" +"cpp" "3" +"creator-sidebar-cpp-views.qdocinc" "4" "debugger" "3" "creator-debugger-example.qdoc" "4" "creator-debugger-setup.qdoc" "4" @@ -304,14 +428,21 @@ "qtquick-app-tutorial.qdoc" "4" "qtquick-buttons.qdoc" "4" "qtquick-components.qdoc" "4" +"qtquick-connection-editor-backend.qdoc" "4" +"qtquick-connection-editor-bindings.qdoc" "4" +"qtquick-connection-editor-properties.qdoc" "4" +"qtquick-connection-editor-signals.qdoc" "4" "qtquick-connection-editor.qdoc" "4" "qtquick-creating.qdoc" "4" "qtquick-designer.qdoc" "4" "qtquick-exporting-qml.qdoc" "4" "qtquick-iso-icon-browser.qdoc" "4" "qtquick-modules-with-plugins.qdoc" "4" +"qtquick-navigator.qdoc" "4" "qtquick-pathview-editor.qdoc" "4" -"qtquick-screens.qdoc" "4" +"qtquick-properties.qdoc" "4" +"qtquick-states-scxml.qdocinc" "4" +"qtquick-states.qdoc" "4" "qtquick-toolbars.qdoc" "4" "qtquick-ui-forms.qdoc" "4" "vcs" "3" @@ -341,6 +472,7 @@ "cpu-usage-analyzer.qdoc" "4" "creator-analyze.qdoc" "4" "creator-clang-static-analyzer.qdoc" "4" +"creator-heob.qdoc" "4" "creator-valgrind-overview.qdoc" "4" "creator-valgrind.qdoc" "4" "qtquick-profiler.qdoc" "4" @@ -354,6 +486,8 @@ "creator-projects-cmake-building.qdocinc" "4" "creator-projects-cmake-deploying.qdocinc" "4" "creator-projects-cmake.qdoc" "4" +"cpp" "3" +"creator-sidebar-cpp-views.qdocinc" "4" "debugger" "3" "creator-debugger-example.qdoc" "4" "creator-debugger-setup.qdoc" "4" @@ -462,14 +596,21 @@ "qtquick-app-tutorial.qdoc" "4" "qtquick-buttons.qdoc" "4" "qtquick-components.qdoc" "4" +"qtquick-connection-editor-backend.qdoc" "4" +"qtquick-connection-editor-bindings.qdoc" "4" +"qtquick-connection-editor-properties.qdoc" "4" +"qtquick-connection-editor-signals.qdoc" "4" "qtquick-connection-editor.qdoc" "4" "qtquick-creating.qdoc" "4" "qtquick-designer.qdoc" "4" "qtquick-exporting-qml.qdoc" "4" "qtquick-iso-icon-browser.qdoc" "4" "qtquick-modules-with-plugins.qdoc" "4" +"qtquick-navigator.qdoc" "4" "qtquick-pathview-editor.qdoc" "4" -"qtquick-screens.qdoc" "4" +"qtquick-properties.qdoc" "4" +"qtquick-states-scxml.qdocinc" "4" +"qtquick-states.qdoc" "4" "qtquick-toolbars.qdoc" "4" "qtquick-ui-forms.qdoc" "4" "vcs" "3" @@ -536,6 +677,7 @@ "doc_targets.pri" "2" "share" "1" "qtcreator" "2" +"examples.pro" "4" "commands" "4" "commands.pri" "5" "container" "4" @@ -571,12 +713,8 @@ "plaincpp" "6" "file.pro" "7" "file.pro" "7" -"qtcanvas3dapplication" "6" -"app.pro" "7" "qtquickapplication" "6" "app.pro" "7" -"qtquickcontrols2application" "6" -"app.pro" "7" "qtcreatorplugin" "5" "myplugin.pro" "6" "qtquick2-extension" "5" @@ -604,10 +742,10 @@ "examples.pro" "5" "aggregation.pro" "4" "aggregation_dependencies.pri" "4" -"clangbackendipc" "3" -"clangbackendipc-lib.pri" "4" -"clangbackendipc.pro" "4" -"clangbackendipc_dependencies.pri" "4" +"clangsupport" "3" +"clangsupport-lib.pri" "4" +"clangsupport.pro" "4" +"clangsupport_dependencies.pri" "4" "cplusplus" "3" "cplusplus-lib.pri" "4" "cplusplus.pro" "4" @@ -615,9 +753,6 @@ "extensionsystem" "3" "extensionsystem.pro" "4" "extensionsystem_dependencies.pri" "4" -"flamegraph" "3" -"flamegraph.pro" "4" -"flamegraph_dependencies.pri" "4" "glsl" "3" "glsl-lib.pri" "4" "glsl.pro" "4" @@ -651,6 +786,13 @@ "qmljs-lib.pri" "4" "qmljs.pro" "4" "qmljs_dependencies.pri" "4" +"qt-breakpad" "3" +"qtcrashhandler" "4" +"qtcrashhandler.pro" "5" +"testapp" "4" +"testapp.pro" "5" +"qtbreakpad.pri" "4" +"qtcrashhandler.pri" "4" "qtcreatorcdbext" "3" "cdb_detect.pri" "4" "qtcreatorcdbext.pro" "4" @@ -662,9 +804,9 @@ "ssh" "3" "ssh.pro" "4" "ssh_dependencies.pri" "4" -"timeline" "3" -"timeline.pro" "4" -"timeline_dependencies.pri" "4" +"tracing" "3" +"tracing.pro" "4" +"tracing_dependencies.pri" "4" "utils" "3" "mimetypes" "4" "mimetypes.pri" "5" @@ -752,8 +894,10 @@ "clangrefactoring-source.pri" "4" "clangrefactoring.pro" "4" "clangrefactoring_dependencies.pri" "4" -"clangstaticanalyzer" "3" +"clangtools" "3" "unit-tests" "4" +"clangtidy_clazy" "5" +"clangtidy_clazy.pro" "6" "mingw-includes" "5" "mingw-includes.pro" "6" "qt-essential-includes" "5" @@ -766,8 +910,8 @@ "simple-library.pro" "6" "stdc++11-includes" "5" "stdc++11-includes.pro" "6" -"clangstaticanalyzer.pro" "4" -"clangstaticanalyzer_dependencies.pri" "4" +"clangtools.pro" "4" +"clangtools_dependencies.pri" "4" "classview" "3" "classview.pro" "4" "classview_dependencies.pri" "4" @@ -882,6 +1026,7 @@ "jsonwizard.pri" "5" "projectexplorer.pro" "4" "projectexplorer_dependencies.pri" "4" +"projectexplorerunittestfiles.pri" "4" "pythoneditor" "3" "pythoneditor.pro" "4" "pythoneditor_dependencies.pri" "4" @@ -994,6 +1139,9 @@ "plugin_interface.pri" "5" "scxmleditor.pro" "4" "scxmleditor_dependencies.pri" "4" +"serialterminal" "3" +"serialterminal.pro" "4" +"serialterminal_dependencies.pri" "4" "silversearcher" "3" "silversearcher.pro" "4" "silversearcher_dependencies.pri" "4" @@ -1053,6 +1201,8 @@ "proparser.pri" "4" "qbs" "3" "doc" "4" +"man" "5" +"man.pri" "6" "doc.pri" "5" "doc_shared.pri" "5" "doc_targets.pri" "5" @@ -1068,8 +1218,6 @@ "qbs.pro" "7" "qbs-create-project" "6" "qbs-create-project.pro" "7" -"qbs-qmltypes" "6" -"qbs-qmltypes.pro" "7" "qbs-setup-android" "6" "qbs-setup-android.pro" "7" "qbs-setup-qt" "6" @@ -1104,6 +1252,10 @@ "qtprofilesetup.pro" "7" "use_installed_qtprofilesetup.pri" "7" "use_qtprofilesetup.pri" "7" +"scriptengine" "6" +"scriptengine.pro" "7" +"use_scriptengine.pri" "7" +"bundledlibs.pri" "6" "library.pri" "6" "libexec" "5" "qbs_processlauncher" "6" @@ -1114,6 +1266,8 @@ "generator" "6" "clangcompilationdb" "7" "clangcompilationdb.pro" "8" +"makefilegenerator" "7" +"makefilegenerator.pro" "8" "visualstudio" "7" "visualstudio.pro" "8" "generator.pro" "7" @@ -1125,6 +1279,7 @@ "scanner.pro" "7" "plugins.pri" "6" "plugins.pro" "6" +"json.pri" "6" "install_prefix.pri" "5" "library_dirname.pri" "5" "tests" "4" @@ -1132,6 +1287,7 @@ "api" "6" "api.pro" "7" "blackbox" "6" +"blackbox-android.pro" "7" "blackbox-apple.pro" "7" "blackbox-clangdb.pro" "7" "blackbox-java.pro" "7" @@ -1154,6 +1310,7 @@ "tests.pro" "5" "qbs.pro" "4" "qbs_version.pri" "4" +"static-res.pro" "4" "static.pro" "4" "qtlockedfile" "3" "qtlockedfile.pri" "4" @@ -1169,7 +1326,7 @@ "buildoutputparser" "3" "buildoutputparser.pro" "4" "clangbackend" "3" -"ipcsource" "4" +"source" "4" "clangbackendclangipc-source.pri" "5" "clangbackend.pro" "4" "clangpchmanagerbackend" "3" @@ -1191,6 +1348,8 @@ "utils.pri" "4" "cplusplus-update-frontend" "3" "cplusplus-update-frontend.pro" "4" +"iconlister" "3" +"iconlister.pro" "4" "iostool" "3" "iostool.pro" "4" "qml2puppet" "3" @@ -1231,13 +1390,6 @@ "algorithm.pro" "4" "changeset" "3" "changeset.pro" "4" -"clangstaticanalyzer" "3" -"clangstaticanalyzerlogfilereader" "4" -"clangstaticanalyzerlogfilereader.pro" "5" -"clangstaticanalyzerrunner" "4" -"clangstaticanalyzerrunner.pro" "5" -"clangstaticanalyzer.pro" "4" -"clangstaticanalyzertest.pri" "4" "cplusplus" "3" "ast" "4" "ast.pro" "5" @@ -1316,8 +1468,6 @@ "externaltool.pro" "4" "filesearch" "3" "filesearch.pro" "4" -"flamegraph" "3" -"flamegraph.pro" "4" "generichighlighter" "3" "highlighterengine" "4" "highlighterengine.pro" "5" @@ -1328,6 +1478,8 @@ "json.pro" "4" "mapreduce" "3" "mapreduce.pro" "4" +"pointeralgorithm" "3" +"pointeralgorithm.pro" "4" "profilewriter" "3" "profilewriter.pro" "4" "qml" "3" @@ -1368,7 +1520,13 @@ "runextensions.pro" "4" "sdktool" "3" "sdktool.pro" "4" -"timeline" "3" +"toolchaincache" "3" +"toolchaincache.pro" "4" +"tracing" "3" +"flamegraph" "4" +"flamegraph.pro" "5" +"flamegraphview" "4" +"flamegraphview.pro" "5" "timelineabstractrenderer" "4" "timelineabstractrenderer.pro" "5" "timelineitemsrenderpass" "4" @@ -1393,7 +1551,7 @@ "timelineselectionrenderpass.pro" "5" "timelinezoomcontrol" "4" "timelinezoomcontrol.pro" "5" -"timeline.pro" "4" +"tracing.pro" "4" "treeviewfind" "3" "treeviewfind.pro" "4" "utils" "3" @@ -1401,8 +1559,10 @@ "ansiescapecodehandler.pro" "5" "fileutils" "4" "fileutils.pro" "5" -"objectpool" "4" -"objectpool.pro" "5" +"fuzzymatcher" "4" +"fuzzymatcher.pro" "5" +"settings" "4" +"settings.pro" "5" "stringutils" "4" "stringutils.pro" "5" "templateengine" "4" @@ -1448,10 +1608,16 @@ "auto.pro" "3" "qttest.pri" "3" "qttestrpath.pri" "3" -"json.pro" "3" +"benchmarks" "2" +"json" "3" +"json.pro" "4" +"signals" "3" +"signals.pro" "4" "testdata_guiproject1.pro" "3" "qmlapplicationviewer.pri" "3" "manual" "2" +"clang-format-for-qtc" "3" +"clang-format-for-qtc.pro" "4" "cplusplus-tools" "3" "cplusplus-tools.pro" "4" "debugger" "3" @@ -1541,6 +1707,10 @@ "tunnel.pro" "5" "ssh.pri" "4" "ssh.pro" "4" +"widgets" "3" +"crumblepath" "4" +"crumblepath.pro" "5" +"widgets.pro" "4" "manual.pro" "3" "test1.pro" "3" "testfiles.pro" "3" @@ -1569,7 +1739,7 @@ "SharedContent" "0" "share.qbs:3" "1" "3rdparty" "1" -"share.qbs:32" "2" +"share.qbs:36" "2" "alert.xml" "3" "autoconf.xml" "3" "bash.xml" "3" @@ -1589,16 +1759,21 @@ "xml.xml" "3" "yacc.xml" "3" "Conditional" "1" -"share.qbs:43" "2" +"share.qbs:47" "2" "lrelease.xml" "3" "lupdate.xml" "3" "qmlscene.xml" "3" "qmlviewer.xml" "3" -"sort.xml" "3" "Unconditional" "1" "share.qbs:7" "2" "qtcreator" "2" -"qobjectdefs.h" "4" +"cplusplus" "3" +"examples" "4" +"clazy_example.cpp" "5" +"examples.pro" "5" +"tidy_example.cpp" "5" +"tidy_example.h" "5" +"qobjectdefs.h" "5" "debugger" "3" "boosttypes.py" "4" "cdbbridge.py" "4" @@ -1625,8 +1800,7 @@ "standard.def" "4" "qml-type-descriptions" "3" "builtins.qmltypes" "4" -"qbs-bundle.json" "4" -"qbs.qmltypes" "4" +"qbs-base.qmltypes" "4" "qmlproject-bundle.json" "4" "qmlproject.qmltypes" "4" "qmlruntime.qmltypes" "4" @@ -1634,8 +1808,6 @@ "qt-labs-folderlistmodel.qmltypes" "4" "qt-labs-gestures.qmltypes" "4" "qt-labs-particles.qmltypes" "4" -"qt4QtQuick1-bundle.json" "4" -"qt5QtQuick1-bundle.json" "4" "qt5QtQuick2-bundle.json" "4" "qtmobility-connectivity.qmltypes" "4" "qtmobility-contacts.qmltypes" "4" @@ -1823,7 +1995,6 @@ "ItemDelegate.qml" "5" "ItemsView.qml" "5" "propertyEditorQmlSources" "4" -"HelperWidgets" "5" "images" "6" "checkers.png" "7" "down-arrow.png" "7" @@ -2035,6 +2206,7 @@ "tst.qbs" "7" "tst.txt" "7" "tst_main.cpp" "7" +"tst_qml.tmpl" "7" "tst_src.cpp" "7" "tst_src.h" "7" "autotest.png" "6" @@ -2096,8 +2268,12 @@ "file.js" "7" "wizard.json" "7" "modeling" "6" -"file.qmodel" "7" -"wizard.json" "7" +"model" "7" +"file.qmodel" "8" +"wizard.json" "8" +"scratch" "7" +"file.qmodel" "8" +"wizard.json" "8" "nim" "6" "file.nim" "7" "wizard.json" "7" @@ -2154,50 +2330,54 @@ "wizard.json" "7" "file.pro" "7" "wizard.json" "7" -"qtcanvas3dapplication" "6" -"plaincanvas3d" "7" -"glcode.js" "8" -"threejs" "7" -"3rdparty" "8" -"three.js" "9" -"glcode.js" "8" -"3dapplication.png" "7" -"3dapplication@2x.png" "7" -"app.pro" "7" -"CMakeLists.txt" "7" -"file.qbs" "7" -"main.cpp" "7" -"main.qml.tpl" "7" -"qml.qrc" "7" -"wizard.json" "7" "qtquickapplication" "6" +"canvas3d" "7" +"plaincanvas3d" "8" +"glcode.js" "9" +"threejs" "8" +"3rdparty" "9" +"three.js" "10" +"glcode.js" "9" +"icon.png" "8" +"icon@2x.png" "8" +"main.qml.tpl" "8" +"qml.qrc" "8" +"wizard.json" "8" +"empty" "7" +"icon.png" "8" +"icon@2x.png" "8" +"main.qml.tpl" "8" +"qml.qrc" "8" +"wizard.json" "8" +"scroll" "7" +"icon.png" "8" +"icon@2x.png" "8" +"main.qml.tpl" "8" +"qml.qrc" "8" +"wizard.json" "8" +"stack" "7" +"HomeForm.ui.qml.tpl" "8" +"icon.png" "8" +"icon@2x.png" "8" +"main.qml.tpl" "8" +"Page1Form.ui.qml.tpl" "8" +"Page2Form.ui.qml.tpl" "8" +"qml.qrc" "8" +"wizard.json" "8" +"swipe" "7" +"icon.png" "8" +"icon@2x.png" "8" +"main.qml.tpl" "8" +"Page1Form.ui.qml.tpl" "8" +"Page2Form.ui.qml.tpl" "8" +"qml.qrc" "8" +"wizard.json" "8" "app.pro" "7" -"CMakeLists.txt" "7" -"file.qbs" "7" -"icon-empty.png" "7" -"icon-empty@2x.png" "7" -"icon-scroll.png" "7" -"icon-scroll@2x.png" "7" -"icon-stack.png" "7" -"icon-stack@2x.png" "7" -"icon-swipe.png" "7" -"icon-swipe@2x.png" "7" -"main.cpp" "7" -"main.qml.tpl" "7" -"MainForm.ui.qml.tpl" "7" -"qml.qrc" "7" -"wizard.json" "7" -"qtquickcontrols2application" "6" -"app.pro" "7" +"app.qbs" "7" "CMakeLists.txt" "7" "file.qbs" "7" "main.cpp" "7" -"main.qml.tpl" "7" -"Page1.qml.tpl" "7" -"Page1Form.ui.qml.tpl" "7" -"qml.qrc" "7" "qtquickcontrols2.conf" "7" -"wizard.json" "7" "qtquickuiprototype" "6" "app.qmlproject" "7" "qtquickuiprototype.png" "7" @@ -2280,10 +2460,10 @@ "Aggregation" "3" "aggregation.qbs:8" "4" "standard pch file (gui)" "4" -"QtcProduct.qbs:58" "5" +"QtcProduct.qbs:65" "5" "qtcreator_gui_pch.h" "6" "standard pch file (non-gui)" "4" -"QtcProduct.qbs:50" "5" +"QtcProduct.qbs:57" "5" "qtcreator_pch.h" "6" "aggregate.cpp" "4" "aggregate.h" "4" @@ -2296,15 +2476,19 @@ "myinterfaces.h" "7" "aggregate.h" "6" "aggregation_global.h" "6" -"ClangBackEndIpc" "2" -"clangbackendipc.qbs:3" "3" +"ClangSupport" "2" +"clangsupport.qbs:3" "3" "Group 3" "3" -"clangbackendipc.qbs:14" "4" +"clangsupport.qbs:14" "4" +"alivemessage.cpp" "4" +"alivemessage.h" "4" +"annotationsmessage.cpp" "4" +"annotationsmessage.h" "4" +"baseserverproxy.cpp" "4" +"baseserverproxy.h" "4" "cancelmessage.cpp" "4" "cancelmessage.h" "4" -"clangbackendipc_global.h" "4" -"clangbackendipcdebugutils.cpp" "4" -"clangbackendipcdebugutils.h" "4" +"changedfilepathcompressor.h" "4" "clangcodemodelclientinterface.cpp" "4" "clangcodemodelclientinterface.h" "4" "clangcodemodelclientmessages.h" "4" @@ -2317,39 +2501,36 @@ "clangcodemodelservermessages.h" "4" "clangcodemodelserverproxy.cpp" "4" "clangcodemodelserverproxy.h" "4" +"clangpathwatcher.h" "4" +"clangpathwatcherinterface.h" "4" +"clangpathwatchernotifier.h" "4" "clangrefactoringclientmessages.h" "4" "clangrefactoringmessages.h" "4" "clangrefactoringservermessages.h" "4" -"cmbalivemessage.cpp" "4" -"cmbalivemessage.h" "4" -"cmbcodecompletedmessage.cpp" "4" -"cmbcodecompletedmessage.h" "4" -"cmbcompletecodemessage.cpp" "4" -"cmbcompletecodemessage.h" "4" -"cmbechomessage.cpp" "4" -"cmbechomessage.h" "4" -"cmbendmessage.cpp" "4" -"cmbendmessage.h" "4" -"cmbregisterprojectsforeditormessage.cpp" "4" -"cmbregisterprojectsforeditormessage.h" "4" -"cmbregistertranslationunitsforeditormessage.cpp" "4" -"cmbregistertranslationunitsforeditormessage.h" "4" -"cmbunregisterprojectsforeditormessage.cpp" "4" -"cmbunregisterprojectsforeditormessage.h" "4" -"cmbunregistertranslationunitsforeditormessage.cpp" "4" -"cmbunregistertranslationunitsforeditormessage.h" "4" +"clangsupport_global.h" "4" +"clangsupportdebugutils.cpp" "4" +"clangsupportdebugutils.h" "4" "codecompletion.cpp" "4" "codecompletion.h" "4" "codecompletionchunk.cpp" "4" "codecompletionchunk.h" "4" +"compilermacro.h" "4" +"completionsmessage.cpp" "4" +"completionsmessage.h" "4" "connectionclient.cpp" "4" "connectionclient.h" "4" "connectionserver.cpp" "4" "connectionserver.h" "4" "diagnosticcontainer.cpp" "4" "diagnosticcontainer.h" "4" -"documentannotationschangedmessage.cpp" "4" -"documentannotationschangedmessage.h" "4" +"documentschangedmessage.cpp" "4" +"documentschangedmessage.h" "4" +"documentsclosedmessage.cpp" "4" +"documentsclosedmessage.h" "4" +"documentsopenedmessage.cpp" "4" +"documentsopenedmessage.h" "4" +"documentvisibilitychangedmessage.cpp" "4" +"documentvisibilitychangedmessage.h" "4" "dynamicastmatcherdiagnosticcontainer.cpp" "4" "dynamicastmatcherdiagnosticcontainer.h" "4" "dynamicastmatcherdiagnosticcontextcontainer.cpp" "4" @@ -2357,19 +2538,35 @@ "dynamicastmatcherdiagnosticmessagecontainer.cpp" "4" "dynamicastmatcherdiagnosticmessagecontainer.h" "4" "dynamicmatcherdiagnostics.h" "4" +"echomessage.cpp" "4" +"echomessage.h" "4" +"endmessage.cpp" "4" +"endmessage.h" "4" "filecontainer.cpp" "4" "filecontainer.h" "4" "filecontainerv2.cpp" "4" "filecontainerv2.h" "4" "filepath.cpp" "4" "filepath.h" "4" +"filepathcache.h" "4" +"filepathcaching.cpp" "4" +"filepathcaching.h" "4" +"filepathcachingfwd.h" "4" +"filepathcachinginterface.h" "4" +"filepathexceptions.h" "4" +"filepathid.cpp" "4" +"filepathid.h" "4" +"filepathstorage.h" "4" +"filepathstoragesources.h" "4" +"filepathstoragesqlitestatementfactory.h" "4" +"filepathview.h" "4" "fixitcontainer.cpp" "4" "fixitcontainer.h" "4" -"highlightingmarkcontainer.cpp" "4" -"highlightingmarkcontainer.h" "4" -"ipcclientinterface.cpp" "4" +"followsymbolmessage.cpp" "4" +"followsymbolmessage.h" "4" +"idpaths.h" "4" "ipcclientinterface.h" "4" -"ipcinterface.cpp" "4" +"ipcclientprovider.h" "4" "ipcinterface.h" "4" "ipcserverinterface.cpp" "4" "ipcserverinterface.h" "4" @@ -2377,6 +2574,7 @@ "lineprefixer.h" "4" "messageenvelop.cpp" "4" "messageenvelop.h" "4" +"nativefilepath.h" "4" "pchmanagerclientinterface.cpp" "4" "pchmanagerclientinterface.h" "4" "pchmanagerclientproxy.cpp" "4" @@ -2387,32 +2585,46 @@ "pchmanagerserverproxy.h" "4" "precompiledheadersupdatedmessage.cpp" "4" "precompiledheadersupdatedmessage.h" "4" +"processcreator.cpp" "4" +"processcreator.h" "4" +"processexception.cpp" "4" +"processexception.h" "4" +"processhandle.h" "4" +"processstartedevent.cpp" "4" +"processstartedevent.h" "4" +"projectmanagementserverinterface.h" "4" "projectpartcontainer.cpp" "4" "projectpartcontainer.h" "4" "projectpartcontainerv2.cpp" "4" "projectpartcontainerv2.h" "4" "projectpartpch.cpp" "4" "projectpartpch.h" "4" -"projectpartsdonotexistmessage.cpp" "4" -"projectpartsdonotexistmessage.h" "4" +"projectpartpchproviderinterface.h" "4" +"projectpartsremovedmessage.cpp" "4" +"projectpartsremovedmessage.h" "4" +"projectpartsupdatedmessage.cpp" "4" +"projectpartsupdatedmessage.h" "4" "readmessageblock.cpp" "4" "readmessageblock.h" "4" "refactoringclientinterface.cpp" "4" "refactoringclientinterface.h" "4" "refactoringclientproxy.cpp" "4" "refactoringclientproxy.h" "4" +"refactoringdatabaseinitializer.h" "4" "refactoringserverinterface.cpp" "4" "refactoringserverinterface.h" "4" "refactoringserverproxy.cpp" "4" "refactoringserverproxy.h" "4" "referencesmessage.cpp" "4" "referencesmessage.h" "4" -"registerunsavedfilesforeditormessage.cpp" "4" -"registerunsavedfilesforeditormessage.h" "4" -"removepchprojectpartsmessage.cpp" "4" -"removepchprojectpartsmessage.h" "4" -"requestdocumentannotations.cpp" "4" -"requestdocumentannotations.h" "4" +"removeprojectpartsmessage.cpp" "4" +"removeprojectpartsmessage.h" "4" +"requestannotationsmessage.cpp" "4" +"requestannotationsmessage.h" "4" +"requestcompletionsmessage.cpp" "4" +"requestcompletionsmessage.h" "4" +"requestfollowsymbolmessage.cpp" "4" +"requestfollowsymbolmessage.h" "4" "requestreferencesmessage.cpp" "4" "requestreferencesmessage.h" "4" "requestsourcelocationforrenamingmessage.cpp" "4" @@ -2421,8 +2633,8 @@ "requestsourcerangesanddiagnosticsforquerymessage.h" "4" "requestsourcerangesforquerymessage.cpp" "4" "requestsourcerangesforquerymessage.h" "4" -"sourcefilepathcontainerbase.cpp" "4" -"sourcefilepathcontainerbase.h" "4" +"requesttooltipmessage.cpp" "4" +"requesttooltipmessage.h" "4" "sourcelocationcontainer.cpp" "4" "sourcelocationcontainer.h" "4" "sourcelocationcontainerv2.cpp" "4" @@ -2444,23 +2656,27 @@ "sourcerangewithtextcontainer.cpp" "4" "sourcerangewithtextcontainer.h" "4" "stringcache.h" "4" -"translationunitdoesnotexistmessage.cpp" "4" -"translationunitdoesnotexistmessage.h" "4" -"unregisterunsavedfilesforeditormessage.cpp" "4" -"unregisterunsavedfilesforeditormessage.h" "4" -"updatepchprojectpartsmessage.cpp" "4" -"updatepchprojectpartsmessage.h" "4" -"updatetranslationunitsforeditormessage.cpp" "4" -"updatetranslationunitsforeditormessage.h" "4" -"updatevisibletranslationunitsmessage.cpp" "4" -"updatevisibletranslationunitsmessage.h" "4" +"stringcachealgorithms.h" "4" +"stringcachefwd.h" "4" +"tokeninfocontainer.cpp" "4" +"tokeninfocontainer.h" "4" +"tooltipinfo.cpp" "4" +"tooltipinfo.h" "4" +"tooltipmessage.cpp" "4" +"tooltipmessage.h" "4" +"unsavedfilesremovedmessage.cpp" "4" +"unsavedfilesremovedmessage.h" "4" +"unsavedfilesupdatedmessage.cpp" "4" +"unsavedfilesupdatedmessage.h" "4" +"updateprojectpartsmessage.cpp" "4" +"updateprojectpartsmessage.h" "4" "writemessageblock.cpp" "4" "writemessageblock.h" "4" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" "CPlusPlus" "2" "cplusplus.qbs:3" "3" @@ -2550,8 +2766,6 @@ "NamePrettyPrinter.h" "5" "Overview.cpp" "5" "Overview.h" "5" -"OverviewModel.cpp" "5" -"OverviewModel.h" "5" "pp-cctype.h" "5" "pp-engine.cpp" "5" "pp-engine.h" "5" @@ -2577,10 +2791,10 @@ "TypePrettyPrinter.cpp" "5" "TypePrettyPrinter.h" "5" "standard pch file (gui)" "4" -"QtcProduct.qbs:58" "5" +"QtcProduct.qbs:65" "5" "qtcreator_gui_pch.h" "6" "standard pch file (non-gui)" "4" -"QtcProduct.qbs:50" "5" +"QtcProduct.qbs:57" "5" "qtcreator_pch.h" "6" "ThirdPartyCPlusPlus" "4" "cplusplus.qbs:23" "5" @@ -2710,7 +2924,6 @@ "MatchingText.h" "6" "NamePrettyPrinter.h" "6" "Overview.h" "6" -"OverviewModel.h" "6" "pp-cctype.h" "6" "pp-engine.h" "6" "pp-scanner.h" "6" @@ -2729,10 +2942,10 @@ "ExtensionSystem" "3" "extensionsystem.qbs:8" "4" "standard pch file (gui)" "4" -"QtcProduct.qbs:58" "5" +"QtcProduct.qbs:65" "5" "qtcreator_gui_pch.h" "6" "standard pch file (non-gui)" "4" -"QtcProduct.qbs:50" "5" +"QtcProduct.qbs:57" "5" "qtcreator_pch.h" "6" "extensionsystem_global.h" "4" "invoker.cpp" "4" @@ -2776,46 +2989,23 @@ "pluginspec.h" "6" "pluginspec_p.h" "6" "pluginview.h" "6" -"FlameGraph" "2" -"flamegraph.qbs:5" "3" -"FlameGraph" "3" -"flamegraph.qbs:10" "4" -"General" "4" -"flamegraph.qbs:13" "5" -"flamegraph.cpp" "5" -"flamegraph.h" "5" -"flamegraph_global.h" "5" -"flamegraphattached.h" "5" -"QML" "4" -"flamegraph.qbs:22" "5" -"qml" "5" -"flamegraph.qrc" "6" -"/flamegraph" "7" -"FlameGraphDelegate.qml" "8" -"FlameGraphDetails.qml" "8" -"FlameGraphText.qml" "8" -"standard pch file (gui)" "4" -"QtcProduct.qbs:58" "5" -"qtcreator_gui_pch.h" "6" -"standard pch file (non-gui)" "4" -"QtcProduct.qbs:50" "5" -"qtcreator_pch.h" "6" -"FlameGraph dev headers" "3" -"flamegraph.qbs:8" "4" -"Group 1" "4" -"QtcDevHeaders.qbs:10" "5" -"flamegraph.h" "6" -"flamegraph_global.h" "6" -"flamegraphattached.h" "6" "GLSL" "2" -"glsl.qbs:3" "3" +"glsl.qbs:6" "3" +"generated parser files" "3" +"glsl.qbs:45" "4" +"glslparser.cpp" "4" +"glslparser.h" "4" +"glslparsertable.cpp" "4" +"glslparsertable_p.h" "4" +"Group 4" "3" +"glsl.qbs:56" "4" +"glsl.g" "4" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" -"glsl.g" "3" "glsl.h" "3" "glslast.cpp" "3" "glslast.h" "3" @@ -2830,10 +3020,6 @@ "glsllexer.h" "3" "glslmemorypool.cpp" "3" "glslmemorypool.h" "3" -"glslparser.cpp" "3" -"glslparser.h" "3" -"glslparsertable.cpp" "3" -"glslparsertable_p.h" "3" "glslsemantic.cpp" "3" "glslsemantic.h" "3" "glslsymbol.cpp" "3" @@ -2849,10 +3035,10 @@ "LanguageUtils" "3" "languageutils.qbs:8" "4" "standard pch file (gui)" "4" -"QtcProduct.qbs:58" "5" +"QtcProduct.qbs:65" "5" "qtcreator_gui_pch.h" "6" "standard pch file (non-gui)" "4" -"QtcProduct.qbs:50" "5" +"QtcProduct.qbs:57" "5" "qtcreator_pch.h" "6" "componentversion.cpp" "4" "componentversion.h" "4" @@ -2869,7 +3055,7 @@ "Modeling" "2" "modelinglib.qbs:3" "3" "Images" "3" -"modelinglib.qbs:341" "4" +"modelinglib.qbs:353" "4" "25x25" "5" "align-bottom.png" "6" "align-horizontal.png" "6" @@ -2918,6 +3104,7 @@ "inheritance.png" "8" "item.png" "8" "package.png" "8" +"swimlane.png" "8" "Qmt" "3" "modelinglib.qbs:21" "4" "qmt" "4" @@ -2957,6 +3144,8 @@ "dclass.h" "6" "dcomponent.cpp" "6" "dcomponent.h" "6" +"dconnection.cpp" "6" +"dconnection.h" "6" "dconstvisitor.h" "6" "ddependency.cpp" "6" "ddependency.h" "6" @@ -2974,6 +3163,8 @@ "dpackage.h" "6" "drelation.cpp" "6" "drelation.h" "6" +"dswimlane.cpp" "6" +"dswimlane.h" "6" "dvisitor.h" "6" "diagram_controller" "5" "dclonevisitor.cpp" "6" @@ -3013,6 +3204,8 @@ "classitem.h" "7" "componentitem.cpp" "7" "componentitem.h" "7" +"connectionitem.cpp" "7" +"connectionitem.h" "7" "diagramitem.cpp" "7" "diagramitem.h" "7" "itemitem.cpp" "7" @@ -3025,6 +3218,8 @@ "relationitem.h" "7" "stereotypedisplayvisitor.cpp" "7" "stereotypedisplayvisitor.h" "7" +"swimlaneitem.cpp" "7" +"swimlaneitem.h" "7" "parts" "6" "alignbuttonsitem.cpp" "7" "alignbuttonsitem.h" "7" @@ -3100,6 +3295,8 @@ "mclassmember.h" "6" "mcomponent.cpp" "6" "mcomponent.h" "6" +"mconnection.cpp" "6" +"mconnection.h" "6" "mconstvisitor.h" "6" "mdependency.cpp" "6" "mdependency.h" "6" @@ -3171,6 +3368,8 @@ "projectserializer.cpp" "6" "projectserializer.h" "6" "stereotype" "5" +"customrelation.cpp" "6" +"customrelation.h" "6" "iconshape.cpp" "6" "iconshape.h" "6" "shape.h" "6" @@ -3219,12 +3418,12 @@ "voidelementtasks.cpp" "6" "voidelementtasks.h" "6" "QStringParser" "3" -"modelinglib.qbs:303" "4" +"modelinglib.qbs:315" "4" "qstringparser" "4" "qstringparser.cpp" "5" "qstringparser.h" "5" "QtSerialization" "3" -"modelinglib.qbs:312" "4" +"modelinglib.qbs:324" "4" "qtserialization" "4" "impl" "6" "loadingrefmap.h" "7" @@ -3251,20 +3450,20 @@ "flag.cpp" "6" "savingrefmap.cpp" "6" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" "QmlDebug" "2" "qmldebug.qbs:3" "3" "QmlDebug" "3" "qmldebug.qbs:8" "4" "standard pch file (gui)" "4" -"QtcProduct.qbs:58" "5" +"QtcProduct.qbs:65" "5" "qtcreator_gui_pch.h" "6" "standard pch file (non-gui)" "4" -"QtcProduct.qbs:50" "5" +"QtcProduct.qbs:57" "5" "qtcreator_pch.h" "6" "baseenginedebugclient.cpp" "4" "baseenginedebugclient.h" "4" @@ -3281,6 +3480,10 @@ "qmldebugclient.cpp" "4" "qmldebugclient.h" "4" "qmldebugcommandlinearguments.h" "4" +"qmldebugconnection.cpp" "4" +"qmldebugconnection.h" "4" +"qmldebugconnectionmanager.cpp" "4" +"qmldebugconnectionmanager.h" "4" "qmldebugconstants.h" "4" "qmlenginecontrolclient.cpp" "4" "qmlenginecontrolclient.h" "4" @@ -3304,6 +3507,8 @@ "qmldebug_global.h" "6" "qmldebugclient.h" "6" "qmldebugcommandlinearguments.h" "6" +"qmldebugconnection.h" "6" +"qmldebugconnectionmanager.h" "6" "qmldebugconstants.h" "6" "qmlenginecontrolclient.h" "6" "qmlenginedebugclient.h" "6" @@ -3321,10 +3526,8 @@ "easinggraph.cpp" "5" "easinggraph.h" "5" "easingpane.qrc" "5" -"/" "6" -"playicon.png" "7" +"/qmleditorwidgets" "6" "qt_logo.png" "7" -"stopicon.png" "7" "General" "3" "qmleditorwidgets.qbs:15" "4" "colorbox.cpp" "4" @@ -3398,13 +3601,11 @@ "bold-h-icon.png" "7" "checkbox_indicator.png" "7" "checkbox_indicator@2x.png" "7" -"hole.png" "7" "horizontal-scale-icon.png" "7" "icon_color_gradient.png" "7" "icon_color_none.png" "7" "icon_color_solid.png" "7" "italic-h-icon.png" "7" -"lock.png" "7" "scale-icon.png" "7" "scrollbar-borderimage-horizontal.png" "7" "scrollbar-borderimage-vertical.png" "7" @@ -3417,8 +3618,8 @@ "style_strikeout@2x.png" "7" "style_underline.png" "7" "style_underline@2x.png" "7" -"tile-icon-hor - scale.png" "7" "tile-icon-hor-crop.png" "7" +"tile-icon-hor-scale.png" "7" "tile-icon-vert-crop.png" "7" "tile-icon-vert-scale.png" "7" "tile-icon.png" "7" @@ -3427,10 +3628,10 @@ "underline-h-icon.png" "7" "vertical-scale-icon.png" "7" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" "QmlJS" "2" "qmljs.qbs:3" "3" @@ -3535,10 +3736,10 @@ "qmljsparser.cpp" "6" "qmljsparser_p.h" "6" "standard pch file (gui)" "4" -"QtcProduct.qbs:58" "5" +"QtcProduct.qbs:65" "5" "qtcreator_gui_pch.h" "6" "standard pch file (non-gui)" "4" -"QtcProduct.qbs:50" "5" +"QtcProduct.qbs:57" "5" "qtcreator_pch.h" "6" "QmlJS dev headers" "3" "qmljs.qbs:6" "4" @@ -3598,19 +3799,19 @@ "qtcreator_ctrlc_stub" "2" "process_ctrlc_stub.qbs:3" "3" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" "process_ctrlc_stub.cpp" "3" "qtcreator_process_stub" "2" "process_stub.qbs:3" "3" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" "qtcreatorcdbext" "2" "qtcreatorcdbext.qbs:8" "3" @@ -3629,10 +3830,10 @@ "pyvalue.cpp" "4" "pyvalue.h" "4" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" "common.cpp" "3" "common.h" "3" @@ -3662,10 +3863,10 @@ "QtcSsh" "3" "ssh.qbs:9" "4" "standard pch file (gui)" "4" -"QtcProduct.qbs:58" "5" +"QtcProduct.qbs:65" "5" "qtcreator_gui_pch.h" "6" "standard pch file (non-gui)" "4" -"QtcProduct.qbs:50" "5" +"QtcProduct.qbs:57" "5" "qtcreator_pch.h" "6" "botan.cpp" "5" "botan.h" "5" @@ -3684,6 +3885,12 @@ "sftpoutgoingpacket_p.h" "4" "sftppacket.cpp" "4" "sftppacket_p.h" "4" +"ssh.qrc" "4" +"/ssh" "5" +"images" "6" +"dir.png" "7" +"help.png" "7" +"unknownfile.png" "7" "sshagent.cpp" "4" "sshagent_p.h" "4" "sshbotanconversions_p.h" "4" @@ -3794,70 +4001,59 @@ "Sqlite" "2" "sqlite.qbs:3" "3" "Group 4" "3" -"sqlite.qbs:31" "4" -"columndefinition.cpp" "4" -"columndefinition.h" "4" -"createtablecommand.cpp" "4" -"createtablecommand.h" "4" +"sqlite.qbs:32" "4" "createtablesqlstatementbuilder.cpp" "4" "createtablesqlstatementbuilder.h" "4" +"sqlitebasestatement.cpp" "4" +"sqlitebasestatement.h" "4" "sqlitecolumn.cpp" "4" "sqlitecolumn.h" "4" "sqlitedatabase.cpp" "4" "sqlitedatabase.h" "4" "sqlitedatabasebackend.cpp" "4" "sqlitedatabasebackend.h" "4" -"sqlitedatabaseconnection.cpp" "4" -"sqlitedatabaseconnection.h" "4" -"sqlitedatabaseconnectionproxy.cpp" "4" -"sqlitedatabaseconnectionproxy.h" "4" "sqliteexception.cpp" "4" "sqliteexception.h" "4" "sqliteglobal.cpp" "4" "sqliteglobal.h" "4" +"sqliteindex.h" "4" "sqlitereadstatement.cpp" "4" "sqlitereadstatement.h" "4" "sqlitereadwritestatement.cpp" "4" "sqlitereadwritestatement.h" "4" -"sqlitestatement.cpp" "4" -"sqlitestatement.h" "4" "sqlitetable.cpp" "4" "sqlitetable.h" "4" -"sqlitetransaction.cpp" "4" "sqlitetransaction.h" "4" -"sqliteworkerthread.cpp" "4" -"sqliteworkerthread.h" "4" "sqlitewritestatement.cpp" "4" "sqlitewritestatement.h" "4" "sqlstatementbuilder.cpp" "4" "sqlstatementbuilder.h" "4" "sqlstatementbuilderexception.cpp" "4" "sqlstatementbuilderexception.h" "4" -"tablewriteworker.cpp" "4" -"tablewriteworker.h" "4" -"tablewriteworkerproxy.cpp" "4" -"tablewriteworkerproxy.h" "4" "utf8string.cpp" "4" "utf8string.h" "4" "utf8stringvector.cpp" "4" "utf8stringvector.h" "4" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" "ThirdPartySqlite" "3" -"sqlite.qbs:20" "4" +"sqlite.qbs:21" "4" "sqlite3.c" "5" "sqlite3.h" "5" "sqlite3ext.h" "5" -"Timeline" "2" -"timeline.qbs:5" "3" -"Timeline" "3" -"timeline.qbs:10" "4" +"Tracing" "2" +"tracing.qbs:5" "3" +"Tracing" "3" +"tracing.qbs:10" "4" "General" "4" -"timeline.qbs:14" "5" +"tracing.qbs:14" "5" +"flamegraph.cpp" "5" +"flamegraph.h" "5" +"flamegraphattached.h" "5" "README" "5" "timelineabstractrenderer.cpp" "5" "timelineabstractrenderer.h" "5" @@ -3891,16 +4087,25 @@ "timelineselectionrenderpass.h" "5" "timelinetheme.cpp" "5" "timelinetheme.h" "5" +"timelinetracefile.cpp" "5" +"timelinetracefile.h" "5" +"timelinetracemanager.cpp" "5" +"timelinetracemanager.h" "5" "timelinezoomcontrol.cpp" "5" "timelinezoomcontrol.h" "5" +"traceevent.h" "5" +"traceeventtype.h" "5" +"tracestashfile.h" "5" "QML" "4" -"timeline.qbs:37" "5" +"tracing.qbs:42" "5" "qml" "5" -"timeline.qrc" "6" -"/timeline" "7" +"tracing.qrc" "6" +"/tracing" "7" "ButtonsBar.qml" "8" "CategoryLabel.qml" "8" "Detail.qml" "8" +"FlameGraphDelegate.qml" "8" +"FlameGraphView.qml" "8" "ico_edit.png" "8" "ico_edit@2x.png" "8" "ico_rangeselected.png" "8" @@ -3920,7 +4125,6 @@ "RowLabel.qml" "8" "SelectionRange.qml" "8" "SelectionRangeDetails.qml" "8" -"SynchronousReloader.qml" "8" "TimeDisplay.qml" "8" "TimelineContent.qml" "8" "timelineitems.frag" "8" @@ -3930,21 +4134,22 @@ "TimelineText.qml" "8" "TimeMarks.qml" "8" "standard pch file (gui)" "4" -"QtcProduct.qbs:58" "5" +"QtcProduct.qbs:65" "5" "qtcreator_gui_pch.h" "6" "standard pch file (non-gui)" "4" -"QtcProduct.qbs:50" "5" +"QtcProduct.qbs:57" "5" "qtcreator_pch.h" "6" "Unit test utilities" "4" -"timeline.qbs:43" "5" +"tracing.qbs:48" "5" "runscenegraphtest.cpp" "5" "runscenegraphtest.h" "5" -"Timeline dev headers" "3" -"timeline.qbs:8" "4" +"Tracing dev headers" "3" +"tracing.qbs:8" "4" "Group 1" "4" "QtcDevHeaders.qbs:10" "5" +"flamegraph.h" "6" +"flamegraphattached.h" "6" "runscenegraphtest.h" "6" -"timeline_global.h" "6" "timelineabstractrenderer.h" "6" "timelineabstractrenderer_p.h" "6" "timelineformattime.h" "6" @@ -3964,20 +4169,26 @@ "timelinerenderstate_p.h" "6" "timelineselectionrenderpass.h" "6" "timelinetheme.h" "6" +"timelinetracefile.h" "6" +"timelinetracemanager.h" "6" "timelinezoomcontrol.h" "6" +"traceevent.h" "6" +"traceeventtype.h" "6" +"tracestashfile.h" "6" +"tracing_global.h" "6" "Utils" "2" "utils.qbs:4" "3" "Utils" "3" "utils.qbs:9" "4" "ConsoleProcess_unix" "4" -"utils.qbs:287" "5" +"utils.qbs:301" "5" "consoleprocess_unix.cpp" "5" "FileUtils_osx" "4" -"utils.qbs:295" "5" +"utils.qbs:309" "5" "fileutils_mac.h" "5" "fileutils_mac.mm" "5" "MimeTypes" "4" -"utils.qbs:311" "5" +"utils.qbs:325" "5" "mimetypes" "5" "mimedatabase.cpp" "6" "mimedatabase.h" "6" @@ -3996,22 +4207,22 @@ "mimetypeparser.cpp" "6" "mimetypeparser_p.h" "6" "ProcessHandle_macos" "4" -"utils.qbs:303" "5" +"utils.qbs:317" "5" "processhandle_mac.mm" "5" "standard pch file (gui)" "4" -"QtcProduct.qbs:58" "5" +"QtcProduct.qbs:65" "5" "qtcreator_gui_pch.h" "6" "standard pch file (non-gui)" "4" -"QtcProduct.qbs:50" "5" +"QtcProduct.qbs:57" "5" "qtcreator_pch.h" "6" "Theme" "4" -"utils.qbs:256" "5" +"utils.qbs:270" "5" "theme" "5" "theme.cpp" "6" "theme.h" "6" "theme_p.h" "6" "Tooltip" "4" -"utils.qbs:266" "5" +"utils.qbs:280" "5" "tooltip" "5" "effects.h" "6" "reuse.h" "6" @@ -4020,10 +4231,15 @@ "tooltip.cpp" "6" "tooltip.h" "6" "WindowsUtils" "4" -"utils.qbs:279" "5" +"utils.qbs:293" "5" "consoleprocess_win.cpp" "5" -"optional.hpp" "5" +"optional" "5" +"optional.hpp" "6" +"variant" "5" +"variant.hpp" "6" "images" "4" +"app-on-top.png" "5" +"app-on-top@2x.png" "5" "arrow.png" "5" "arrowdown.png" "5" "arrowdown@2x.png" "5" @@ -4039,22 +4255,35 @@ "clean_pane_small@2x.png" "5" "close.png" "5" "close@2x.png" "5" +"codemodelerror.png" "5" +"codemodelerror@2x.png" "5" +"codemodelwarning.png" "5" +"codemodelwarning@2x.png" "5" "collapse.png" "5" "collapse@2x.png" "5" "compile_error_taskbar.png" "5" "compile_error_taskbar@2x.png" "5" -"crumblepath-segment-end.png" "5" -"crumblepath-segment-hover-end.png" "5" -"crumblepath-segment-hover.png" "5" -"crumblepath-segment-selected-end.png" "5" -"crumblepath-segment-selected.png" "5" -"crumblepath-segment.png" "5" +"crumblepath-segment-first-hover.png" "5" +"crumblepath-segment-first-hover@2x.png" "5" +"crumblepath-segment-first.png" "5" +"crumblepath-segment-first@2x.png" "5" +"crumblepath-segment-last-hover.png" "5" +"crumblepath-segment-last-hover@2x.png" "5" +"crumblepath-segment-last.png" "5" +"crumblepath-segment-last@2x.png" "5" +"crumblepath-segment-middle-hover.png" "5" +"crumblepath-segment-middle-hover@2x.png" "5" +"crumblepath-segment-middle.png" "5" +"crumblepath-segment-middle@2x.png" "5" +"crumblepath-segment-single-hover.png" "5" +"crumblepath-segment-single-hover@2x.png" "5" +"crumblepath-segment-single.png" "5" +"crumblepath-segment-single@2x.png" "5" "dark_fileicon.png" "5" "dark_foldericon.png" "5" "Desktop.png" "5" "desktopdevicesmall.png" "5" "desktopdevicesmall@2x.png" "5" -"dir.png" "5" "editclear.png" "5" "editclear@2x.png" "5" "editcopy.png" "5" @@ -4064,6 +4293,7 @@ "editpaste.png" "5" "editpaste@2x.png" "5" "empty14.png" "5" +"empty16.png" "5" "error.png" "5" "error@2x.png" "5" "expand.png" "5" @@ -4074,6 +4304,10 @@ "eye_closed@2x.png" "5" "eye_open.png" "5" "eye_open@2x.png" "5" +"fileexport.png" "5" +"fileexport@2x.png" "5" +"filemultiexport.png" "5" +"filemultiexport@2x.png" "5" "filenew.png" "5" "filenew@2x.png" "5" "fileopen.png" "5" @@ -4086,11 +4320,14 @@ "filtericon@2x.png" "5" "fittoview.png" "5" "fittoview@2x.png" "5" -"help.png" "5" +"home.png" "5" +"home@2x.png" "5" "iconoverlay_add.png" "5" "iconoverlay_add@2x.png" "5" "iconoverlay_add_background.png" "5" "iconoverlay_add_background@2x.png" "5" +"iconoverlay_add_small.png" "5" +"iconoverlay_add_small@2x.png" "5" "iconoverlay_error.png" "5" "iconoverlay_error@2x.png" "5" "iconoverlay_error_background.png" "5" @@ -4111,6 +4348,10 @@ "interrupt_small@2x.png" "5" "leftsidebaricon.png" "5" "leftsidebaricon@2x.png" "5" +"lightbulb.png" "5" +"lightbulb@2x.png" "5" +"lightbulbcap.png" "5" +"lightbulbcap@2x.png" "5" "linkicon.png" "5" "linkicon@2x.png" "5" "locked.png" "5" @@ -4153,6 +4394,8 @@ "progressindicator_medium@2x.png" "5" "progressindicator_small.png" "5" "progressindicator_small@2x.png" "5" +"project.png" "5" +"project@2x.png" "5" "redo.png" "5" "redo@2x.png" "5" "reload_gray.png" "5" @@ -4167,6 +4410,8 @@ "rightsidebaricon@2x.png" "5" "run_small.png" "5" "run_small@2x.png" "5" +"select.png" "5" +"select@2x.png" "5" "snapshot.png" "5" "snapshot@2x.png" "5" "splitbutton_closebottom.png" "5" @@ -4183,10 +4428,10 @@ "splitbutton_vertical@2x.png" "5" "stop_small.png" "5" "stop_small@2x.png" "5" -"triangle_vert.png" "5" +"toolbuttonexpandarrow.png" "5" +"toolbuttonexpandarrow@2x.png" "5" "undo.png" "5" "undo@2x.png" "5" -"unknownfile.png" "5" "unlocked.png" "5" "unlocked@2x.png" "5" "warning.png" "5" @@ -4208,11 +4453,10 @@ "ansiescapecodehandler.h" "4" "appmainwindow.cpp" "4" "appmainwindow.h" "4" -"asconst.h" "4" "basetreeview.cpp" "4" "basetreeview.h" "4" -"bracematcher.cpp" "4" -"bracematcher.h" "4" +"benchmarker.cpp" "4" +"benchmarker.h" "4" "buildablehelperlibrary.cpp" "4" "buildablehelperlibrary.h" "4" "categorysortfiltermodel.cpp" "4" @@ -4262,6 +4506,8 @@ "fancylineedit.h" "4" "fancymainwindow.cpp" "4" "fancymainwindow.h" "4" +"filecrumblabel.cpp" "4" +"filecrumblabel.h" "4" "fileinprojectfinder.cpp" "4" "fileinprojectfinder.h" "4" "filenamevalidatinglineedit.cpp" "4" @@ -4275,9 +4521,13 @@ "filewizardpage.cpp" "4" "filewizardpage.h" "4" "filewizardpage.ui" "4" +"fixedsizeclicklabel.cpp" "4" +"fixedsizeclicklabel.h" "4" "flowlayout.cpp" "4" "flowlayout.h" "4" "functiontraits.h" "4" +"fuzzymatcher.cpp" "4" +"fuzzymatcher.h" "4" "guard.cpp" "4" "guard.h" "4" "headerviewstretcher.cpp" "4" @@ -4296,8 +4546,8 @@ "itemviews.h" "4" "json.cpp" "4" "json.h" "4" -"linecolumnlabel.cpp" "4" -"linecolumnlabel.h" "4" +"linecolumn.h" "4" +"link.h" "4" "listutils.h" "4" "macroexpander.cpp" "4" "macroexpander.h" "4" @@ -4309,7 +4559,6 @@ "newclasswidget.cpp" "4" "newclasswidget.h" "4" "newclasswidget.ui" "4" -"objectpool.h" "4" "optional.h" "4" "osspecificaspects.h" "4" "outputformat.h" "4" @@ -4325,10 +4574,12 @@ "pathlisteditor.h" "4" "persistentsettings.cpp" "4" "persistentsettings.h" "4" +"pointeralgorithm.h" "4" "port.cpp" "4" "port.h" "4" "portlist.cpp" "4" "portlist.h" "4" +"predicates.h" "4" "processhandle.cpp" "4" "processhandle.h" "4" "progressindicator.cpp" "4" @@ -4343,7 +4594,6 @@ "proxycredentialsdialog.ui" "4" "qtcassert.cpp" "4" "qtcassert.h" "4" -"qtcfallthrough.h" "4" "qtcolorbutton.cpp" "4" "qtcolorbutton.h" "4" "QtConcurrentTools" "4" @@ -4351,6 +4601,9 @@ "qtcprocess.h" "4" "reloadpromptutils.cpp" "4" "reloadpromptutils.h" "4" +"removefiledialog.cpp" "4" +"removefiledialog.h" "4" +"removefiledialog.ui" "4" "runextensions.cpp" "4" "runextensions.h" "4" "savedaction.cpp" "4" @@ -4358,6 +4611,8 @@ "savefile.cpp" "4" "savefile.h" "4" "scopedswap.h" "4" +"settingsaccessor.cpp" "4" +"settingsaccessor.h" "4" "settingsselector.cpp" "4" "settingsselector.h" "4" "settingsutils.h" "4" @@ -4395,6 +4650,8 @@ "textfieldcombobox.h" "4" "textfileformat.cpp" "4" "textfileformat.h" "4" +"textutils.cpp" "4" +"textutils.h" "4" "treemodel.cpp" "4" "treemodel.h" "4" "treeviewcombobox.cpp" "4" @@ -4403,9 +4660,13 @@ "uncommentselection.h" "4" "unixutils.cpp" "4" "unixutils.h" "4" +"url.cpp" "4" +"url.h" "4" "utils.qrc" "4" "/utils" "5" "images" "6" +"app-on-top.png" "7" +"app-on-top@2x.png" "7" "arrow.png" "7" "arrowdown.png" "7" "arrowdown@2x.png" "7" @@ -4421,22 +4682,35 @@ "clean_pane_small@2x.png" "7" "close.png" "7" "close@2x.png" "7" +"codemodelerror.png" "7" +"codemodelerror@2x.png" "7" +"codemodelwarning.png" "7" +"codemodelwarning@2x.png" "7" "collapse.png" "7" "collapse@2x.png" "7" "compile_error_taskbar.png" "7" "compile_error_taskbar@2x.png" "7" -"crumblepath-segment-end.png" "7" -"crumblepath-segment-hover-end.png" "7" -"crumblepath-segment-hover.png" "7" -"crumblepath-segment-selected-end.png" "7" -"crumblepath-segment-selected.png" "7" -"crumblepath-segment.png" "7" +"crumblepath-segment-first-hover.png" "7" +"crumblepath-segment-first-hover@2x.png" "7" +"crumblepath-segment-first.png" "7" +"crumblepath-segment-first@2x.png" "7" +"crumblepath-segment-last-hover.png" "7" +"crumblepath-segment-last-hover@2x.png" "7" +"crumblepath-segment-last.png" "7" +"crumblepath-segment-last@2x.png" "7" +"crumblepath-segment-middle-hover.png" "7" +"crumblepath-segment-middle-hover@2x.png" "7" +"crumblepath-segment-middle.png" "7" +"crumblepath-segment-middle@2x.png" "7" +"crumblepath-segment-single-hover.png" "7" +"crumblepath-segment-single-hover@2x.png" "7" +"crumblepath-segment-single.png" "7" +"crumblepath-segment-single@2x.png" "7" "dark_fileicon.png" "7" "dark_foldericon.png" "7" "Desktop.png" "7" "desktopdevicesmall.png" "7" "desktopdevicesmall@2x.png" "7" -"dir.png" "7" "editclear.png" "7" "editclear@2x.png" "7" "editcopy.png" "7" @@ -4446,6 +4720,7 @@ "editpaste.png" "7" "editpaste@2x.png" "7" "empty14.png" "7" +"empty16.png" "7" "error.png" "7" "error@2x.png" "7" "expand.png" "7" @@ -4456,6 +4731,10 @@ "eye_closed@2x.png" "7" "eye_open.png" "7" "eye_open@2x.png" "7" +"fileexport.png" "7" +"fileexport@2x.png" "7" +"filemultiexport.png" "7" +"filemultiexport@2x.png" "7" "filenew.png" "7" "filenew@2x.png" "7" "fileopen.png" "7" @@ -4468,11 +4747,14 @@ "filtericon@2x.png" "7" "fittoview.png" "7" "fittoview@2x.png" "7" -"help.png" "7" +"home.png" "7" +"home@2x.png" "7" "iconoverlay_add.png" "7" "iconoverlay_add@2x.png" "7" "iconoverlay_add_background.png" "7" "iconoverlay_add_background@2x.png" "7" +"iconoverlay_add_small.png" "7" +"iconoverlay_add_small@2x.png" "7" "iconoverlay_error.png" "7" "iconoverlay_error@2x.png" "7" "iconoverlay_error_background.png" "7" @@ -4493,6 +4775,10 @@ "interrupt_small@2x.png" "7" "leftsidebaricon.png" "7" "leftsidebaricon@2x.png" "7" +"lightbulb.png" "7" +"lightbulb@2x.png" "7" +"lightbulbcap.png" "7" +"lightbulbcap@2x.png" "7" "linkicon.png" "7" "linkicon@2x.png" "7" "locked.png" "7" @@ -4535,6 +4821,8 @@ "progressindicator_medium@2x.png" "7" "progressindicator_small.png" "7" "progressindicator_small@2x.png" "7" +"project.png" "7" +"project@2x.png" "7" "redo.png" "7" "redo@2x.png" "7" "reload_gray.png" "7" @@ -4549,6 +4837,8 @@ "rightsidebaricon@2x.png" "7" "run_small.png" "7" "run_small@2x.png" "7" +"select.png" "7" +"select@2x.png" "7" "snapshot.png" "7" "snapshot@2x.png" "7" "splitbutton_closebottom.png" "7" @@ -4565,10 +4855,10 @@ "splitbutton_vertical@2x.png" "7" "stop_small.png" "7" "stop_small@2x.png" "7" -"triangle_vert.png" "7" +"toolbuttonexpandarrow.png" "7" +"toolbuttonexpandarrow@2x.png" "7" "undo.png" "7" "undo@2x.png" "7" -"unknownfile.png" "7" "unlocked.png" "7" "unlocked@2x.png" "7" "warning.png" "7" @@ -4589,6 +4879,7 @@ "utils_global.h" "4" "utilsicons.cpp" "4" "utilsicons.h" "4" +"variant.h" "4" "winutils.cpp" "4" "winutils.h" "4" "wizard.cpp" "4" @@ -4621,9 +4912,8 @@ "annotateditemdelegate.h" "6" "ansiescapecodehandler.h" "6" "appmainwindow.h" "6" -"asconst.h" "6" "basetreeview.h" "6" -"bracematcher.h" "6" +"benchmarker.h" "6" "buildablehelperlibrary.h" "6" "categorysortfiltermodel.h" "6" "changeset.h" "6" @@ -4650,6 +4940,7 @@ "faketooltip.h" "6" "fancylineedit.h" "6" "fancymainwindow.h" "6" +"filecrumblabel.h" "6" "fileinprojectfinder.h" "6" "filenamevalidatinglineedit.h" "6" "filesearch.h" "6" @@ -4657,8 +4948,10 @@ "fileutils.h" "6" "fileutils_mac.h" "6" "filewizardpage.h" "6" +"fixedsizeclicklabel.h" "6" "flowlayout.h" "6" "functiontraits.h" "6" +"fuzzymatcher.h" "6" "guard.h" "6" "headerviewstretcher.h" "6" "highlightingitemdelegate.h" "6" @@ -4668,14 +4961,14 @@ "icon.h" "6" "itemviews.h" "6" "json.h" "6" -"linecolumnlabel.h" "6" +"linecolumn.h" "6" +"link.h" "6" "listutils.h" "6" "macroexpander.h" "6" "mapreduce.h" "6" "navigationtreeview.h" "6" "networkaccessmanager.h" "6" "newclasswidget.h" "6" -"objectpool.h" "6" "optional.h" "6" "osspecificaspects.h" "6" "outputformat.h" "6" @@ -4685,22 +4978,25 @@ "pathchooser.h" "6" "pathlisteditor.h" "6" "persistentsettings.h" "6" +"pointeralgorithm.h" "6" "port.h" "6" "portlist.h" "6" +"predicates.h" "6" "processhandle.h" "6" "progressindicator.h" "6" "projectintropage.h" "6" "proxyaction.h" "6" "proxycredentialsdialog.h" "6" "qtcassert.h" "6" -"qtcfallthrough.h" "6" "qtcolorbutton.h" "6" "qtcprocess.h" "6" "reloadpromptutils.h" "6" +"removefiledialog.h" "6" "runextensions.h" "6" "savedaction.h" "6" "savefile.h" "6" "scopedswap.h" "6" +"settingsaccessor.h" "6" "settingsselector.h" "6" "settingsutils.h" "6" "shellcommand.h" "6" @@ -4726,12 +5022,15 @@ "textfieldcheckbox.h" "6" "textfieldcombobox.h" "6" "textfileformat.h" "6" +"textutils.h" "6" "treemodel.h" "6" "treeviewcombobox.h" "6" "uncommentselection.h" "6" "unixutils.h" "6" +"url.h" "6" "utils_global.h" "6" "utilsicons.h" "6" +"variant.h" "6" "winutils.h" "6" "wizard.h" "6" "wizardpage.h" "6" @@ -4742,22 +5041,27 @@ "Android" "3" "android.qbs:8" "4" "PluginMetaData" "4" -"QtcPlugin.qbs:51" "5" +"QtcPlugin.qbs:49" "5" "Android.json.in" "6" "standard pch file (gui)" "4" -"QtcProduct.qbs:58" "5" +"QtcProduct.qbs:65" "5" "qtcreator_gui_pch.h" "6" "standard pch file (non-gui)" "4" -"QtcProduct.qbs:50" "5" +"QtcProduct.qbs:57" "5" "qtcreator_pch.h" "6" "adbcommandswidget.cpp" "4" "adbcommandswidget.h" "4" "adbcommandswidget.ui" "4" "addnewavddialog.ui" "4" "android.qrc" "4" +"/android" "5" +"images" "6" +"androiddevice.png" "7" +"androiddevice@2x.png" "7" +"androiddevicesmall.png" "7" +"androiddevicesmall@2x.png" "7" +"download.png" "7" "android_global.h" "4" -"androidanalyzesupport.cpp" "4" -"androidanalyzesupport.h" "4" "androidavdmanager.cpp" "4" "androidavdmanager.h" "4" "androidbuildapkstep.cpp" "4" @@ -4802,10 +5106,14 @@ "androidmanifesteditorfactory.h" "4" "androidmanifesteditorwidget.cpp" "4" "androidmanifesteditorwidget.h" "4" +"androidpackageinstallationstep.cpp" "4" +"androidpackageinstallationstep.h" "4" "androidplugin.cpp" "4" "androidplugin.h" "4" "androidpotentialkit.cpp" "4" "androidpotentialkit.h" "4" +"androidqmltoolingsupport.cpp" "4" +"androidqmltoolingsupport.h" "4" "androidqtsupport.cpp" "4" "androidqtsupport.h" "4" "androidqtversion.cpp" "4" @@ -4814,17 +5122,21 @@ "androidqtversionfactory.h" "4" "androidrunconfiguration.cpp" "4" "androidrunconfiguration.h" "4" -"androidrunconfigurationwidget.cpp" "4" -"androidrunconfigurationwidget.h" "4" -"androidrunconfigurationwidget.ui" "4" "androidruncontrol.cpp" "4" "androidruncontrol.h" "4" -"androidrunnable.cpp" "4" -"androidrunnable.h" "4" "androidrunner.cpp" "4" "androidrunner.h" "4" +"androidrunnerworker.cpp" "4" +"androidrunnerworker.h" "4" "androidsdkmanager.cpp" "4" "androidsdkmanager.h" "4" +"androidsdkmanagerwidget.cpp" "4" +"androidsdkmanagerwidget.h" "4" +"androidsdkmanagerwidget.ui" "4" +"androidsdkmodel.cpp" "4" +"androidsdkmodel.h" "4" +"androidsdkpackage.cpp" "4" +"androidsdkpackage.h" "4" "androidsettingspage.cpp" "4" "androidsettingspage.h" "4" "androidsettingswidget.cpp" "4" @@ -4852,7 +5164,6 @@ "QtcDevHeaders.qbs:10" "5" "adbcommandswidget.h" "6" "android_global.h" "6" -"androidanalyzesupport.h" "6" "androidavdmanager.h" "6" "androidbuildapkstep.h" "6" "androidbuildapkwidget.h" "6" @@ -4874,17 +5185,21 @@ "androidmanifesteditor.h" "6" "androidmanifesteditorfactory.h" "6" "androidmanifesteditorwidget.h" "6" +"androidpackageinstallationstep.h" "6" "androidplugin.h" "6" "androidpotentialkit.h" "6" +"androidqmltoolingsupport.h" "6" "androidqtsupport.h" "6" "androidqtversion.h" "6" "androidqtversionfactory.h" "6" "androidrunconfiguration.h" "6" -"androidrunconfigurationwidget.h" "6" "androidruncontrol.h" "6" -"androidrunnable.h" "6" "androidrunner.h" "6" +"androidrunnerworker.h" "6" "androidsdkmanager.h" "6" +"androidsdkmanagerwidget.h" "6" +"androidsdkmodel.h" "6" +"androidsdkpackage.h" "6" "androidsettingspage.h" "6" "androidsettingswidget.h" "6" "androidsignaloperation.h" "6" @@ -4898,9 +5213,9 @@ "AutoTest" "2" "autotest.qbs:3" "3" "Auto Test Wizard" "3" -"autotest.qbs:111" "4" +"autotest.qbs:114" "4" "Google Test framework files" "3" -"autotest.qbs:94" "4" +"autotest.qbs:97" "4" "gtest" "4" "gtest_utils.cpp" "5" "gtest_utils.h" "5" @@ -4925,10 +5240,10 @@ "gtestvisitors.cpp" "5" "gtestvisitors.h" "5" "PluginMetaData" "3" -"QtcPlugin.qbs:51" "4" +"QtcPlugin.qbs:49" "4" "AutoTest.json.in" "5" "QtTest framework files" "3" -"autotest.qbs:80" "4" +"autotest.qbs:83" "4" "qtest" "4" "qttest_utils.cpp" "5" "qttest_utils.h" "5" @@ -4953,7 +5268,7 @@ "qttestvisitors.cpp" "5" "qttestvisitors.h" "5" "Quick Test framework files" "3" -"autotest.qbs:87" "4" +"autotest.qbs:90" "4" "quick" "4" "quicktest_utils.cpp" "5" "quicktest_utils.h" "5" @@ -4968,17 +5283,134 @@ "quicktestvisitors.cpp" "5" "quicktestvisitors.h" "5" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" "Test sources" "3" -"autotest.qbs:101" "4" +"autotest.qbs:104" "4" "autotestunittests.cpp" "4" "autotestunittests.h" "4" "autotestunittests.qrc" "4" +"/" "5" +"unit_test" "6" +"mixed_atp" "7" +"src" "8" +"main.cpp" "9" +"src.pro" "9" +"src.qbs" "9" +"tests" "8" +"auto" "9" +"bench" "10" +"bench.pro" "11" +"bench.qbs" "11" +"tst_benchtest.cpp" "11" +"derived" "10" +"derived.pro" "11" +"derived.qbs" "11" +"origin.cpp" "11" +"origin.h" "11" +"tst_derivedtest.cpp" "11" +"dummy" "10" +"dummy.pro" "11" +"dummy.qbs" "11" +"tst_foo.cpp" "11" +"tst_foo.h" "11" +"gui" "10" +"gui.pro" "11" +"gui.qbs" "11" +"tst_guitest.cpp" "11" +"quickauto" "10" +"bar" "11" +"tst_foo.qml" "12" +"notlisted" "11" +"tst_bla.qml" "12" +"main.cpp" "11" +"quickauto.pro" "11" +"quickauto.qbs" "11" +"TestDummy.qml" "11" +"tst_test1.qml" "11" +"tst_test2.qml" "11" +"tst_test3.qml" "11" +"quickauto2" "10" +"main.cpp" "11" +"quickauto2.pro" "11" +"quickauto2.qbs" "11" +"tst_test1.qml" "11" +"tst_test2.qml" "11" +"quickauto3" "10" +"Bar.qml" "11" +"Foo.qml" "11" +"main.cpp" "11" +"quickauto3.pro" "11" +"quickauto3.qbs" "11" +"tst_test1.qml" "11" +"tst_test2.qml" "11" +"auto.pro" "10" +"auto.qbs" "10" +"tests.pro" "9" +"tests.qbs" "9" +"mixed_atp.pro" "8" +"mixed_atp.qbs" "8" +"plain" "7" +"test_plain" "8" +"test_plain.pro" "9" +"test_plain.qbs" "9" +"tst_simple.cpp" "9" +"tst_simple.h" "9" +"plain.pro" "8" +"plain.qbs" "8" +"simple_gt" "7" +"src" "8" +"main.cpp" "9" +"src.pro" "9" +"src.qbs" "9" +"tests" "8" +"common" "9" +"functions.js" "10" +"gt1" "9" +"further.cpp" "10" +"gt1.pro" "10" +"gt1.qbs" "10" +"main.cpp" "10" +"gt2" "9" +"gt2.pro" "10" +"gt2.qbs" "10" +"main.cpp" "10" +"queuetest.h" "10" +"gt3" "9" +"dummytest.h" "10" +"gt3.pro" "10" +"gt3.qbs" "10" +"main.cpp" "10" +"gtest_dependency.pri" "9" +"tests.pro" "9" +"tests.qbs" "9" +"simple_gt.pro" "8" +"simple_gt.qbs" "8" "autotest.qrc" "3" +"/autotest" "4" +"images" "5" +"benchmark.png" "6" +"benchmark@2x.png" "6" +"data.png" "6" +"leafsort.png" "6" +"leafsort@2x.png" "6" +"run_file.png" "6" +"run_file@2x.png" "6" +"runselected_boxes.png" "6" +"runselected_boxes@2x.png" "6" +"runselected_tickmarks.png" "6" +"runselected_tickmarks@2x.png" "6" +"settingscategory_autotest.png" "6" +"settingscategory_autotest@2x.png" "6" +"sort.png" "6" +"sort@2x.png" "6" +"text.png" "6" +"text@2x.png" "6" +"visual.png" "6" +"visual@2x.png" "6" "autotest_global.h" "3" "autotestconstants.h" "3" "autotesticons.h" "3" @@ -4993,6 +5425,8 @@ "testcodeparser.h" "3" "testconfiguration.cpp" "3" "testconfiguration.h" "3" +"testeditormark.cpp" "3" +"testeditormark.h" "3" "testframeworkmanager.cpp" "3" "testframeworkmanager.h" "3" "testnavigationwidget.cpp" "3" @@ -5026,13 +5460,13 @@ "AutotoolsProjectManager" "2" "autotoolsprojectmanager.qbs:3" "3" "PluginMetaData" "3" -"QtcPlugin.qbs:51" "4" +"QtcPlugin.qbs:49" "4" "AutotoolsProjectManager.json.in" "5" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" "autogenstep.cpp" "3" "autogenstep.h" "3" @@ -5062,15 +5496,21 @@ "BareMetal" "2" "baremetal.qbs:3" "3" "PluginMetaData" "3" -"QtcPlugin.qbs:51" "4" +"QtcPlugin.qbs:49" "4" "BareMetal.json.in" "5" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" "baremetal.qrc" "3" +"/baremetal" "4" +"images" "5" +"baremetaldevice.png" "6" +"baremetaldevice@2x.png" "6" +"baremetaldevicesmall.png" "6" +"baremetaldevicesmall@2x.png" "6" "baremetalconstants.h" "3" "baremetalcustomrunconfiguration.cpp" "3" "baremetalcustomrunconfiguration.h" "3" @@ -5092,10 +5532,6 @@ "baremetalplugin.h" "3" "baremetalrunconfiguration.cpp" "3" "baremetalrunconfiguration.h" "3" -"baremetalrunconfigurationfactory.cpp" "3" -"baremetalrunconfigurationfactory.h" "3" -"baremetalrunconfigurationwidget.cpp" "3" -"baremetalrunconfigurationwidget.h" "3" "defaultgdbserverprovider.cpp" "3" "defaultgdbserverprovider.h" "3" "gdbserverprovider.cpp" "3" @@ -5115,13 +5551,13 @@ "Bazaar" "2" "bazaar.qbs:3" "3" "PluginMetaData" "3" -"QtcPlugin.qbs:51" "4" +"QtcPlugin.qbs:49" "4" "Bazaar.json.in" "5" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" "annotationhighlighter.cpp" "3" "annotationhighlighter.h" "3" @@ -5178,13 +5614,13 @@ "clangformatsettings.cpp" "5" "clangformatsettings.h" "5" "PluginMetaData" "3" -"QtcPlugin.qbs:51" "4" +"QtcPlugin.qbs:49" "4" "Beautifier.json.in" "5" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" "Uncrustify" "3" "beautifier.qbs:70" "4" @@ -5200,6 +5636,10 @@ "abstractsettings.cpp" "3" "abstractsettings.h" "3" "beautifier.qrc" "3" +"/beautifier" "4" +"images" "5" +"settingscategory_beautifier.png" "6" +"settingscategory_beautifier@2x.png" "6" "beautifierabstracttool.h" "3" "beautifierconstants.h" "3" "beautifierplugin.cpp" "3" @@ -5222,13 +5662,13 @@ "BinEditor" "2" "bineditor.qbs:3" "3" "PluginMetaData" "3" -"QtcPlugin.qbs:51" "4" +"QtcPlugin.qbs:49" "4" "BinEditor.json.in" "5" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" "bineditor_global.h" "3" "bineditorconstants.h" "3" @@ -5242,16 +5682,18 @@ "Bookmarks" "2" "bookmarks.qbs:3" "3" "PluginMetaData" "3" -"QtcPlugin.qbs:51" "4" +"QtcPlugin.qbs:49" "4" "Bookmarks.json.in" "5" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" "bookmark.cpp" "3" "bookmark.h" "3" +"bookmarkfilter.cpp" "3" +"bookmarkfilter.h" "3" "bookmarkmanager.cpp" "3" "bookmarkmanager.h" "3" "bookmarks_global.h" "3" @@ -5260,20 +5702,20 @@ "ClangCodeModel" "2" "clangcodemodel.qbs:4" "3" "Other files" "3" -"clangcodemodel.qbs:119" "4" +"clangcodemodel.qbs:135" "4" "creator-clang-codemodel.qdoc" "5" "README" "4" "PluginMetaData" "3" -"QtcPlugin.qbs:51" "4" +"QtcPlugin.qbs:49" "4" "ClangCodeModel.json.in" "5" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" "Test resources" "3" -"clangcodemodel.qbs:111" "4" +"clangcodemodel.qbs:127" "4" "completionWithProject.cpp" "5" "constructorCompletion.cpp" "5" "dotToArrowCorrection.cpp" "5" @@ -5290,7 +5732,7 @@ "objc_messages_3.mm" "5" "preprocessorKeywordsCompletion.cpp" "5" "Tests" "3" -"clangcodemodel.qbs:96" "4" +"clangcodemodel.qbs:112" "4" "test" "4" "data" "5" "clangtestdata.qrc" "6" @@ -5310,9 +5752,14 @@ "clangassistproposalitem.h" "3" "clangassistproposalmodel.cpp" "3" "clangassistproposalmodel.h" "3" -"clangbackendipcintegration.cpp" "3" -"clangbackendipcintegration.h" "3" -"clangcodemodel.qrc" "3" +"clangbackendcommunicator.cpp" "3" +"clangbackendcommunicator.h" "3" +"clangbackendlogging.cpp" "3" +"clangbackendlogging.h" "3" +"clangbackendreceiver.cpp" "3" +"clangbackendreceiver.h" "3" +"clangbackendsender.cpp" "3" +"clangbackendsender.h" "3" "clangcodemodelplugin.cpp" "3" "clangcodemodelplugin.h" "3" "clangcompletionassistinterface.cpp" "3" @@ -5326,6 +5773,8 @@ "clangcompletioncontextanalyzer.cpp" "3" "clangcompletioncontextanalyzer.h" "3" "clangconstants.h" "3" +"clangcurrentdocumentfilter.cpp" "3" +"clangcurrentdocumentfilter.h" "3" "clangdiagnosticfilter.cpp" "3" "clangdiagnosticfilter.h" "3" "clangdiagnosticmanager.cpp" "3" @@ -5340,13 +5789,19 @@ "clangfixitoperation.h" "3" "clangfixitoperationsextractor.cpp" "3" "clangfixitoperationsextractor.h" "3" +"clangfollowsymbol.cpp" "3" +"clangfollowsymbol.h" "3" "clangfunctionhintmodel.cpp" "3" "clangfunctionhintmodel.h" "3" -"clanghighlightingmarksreporter.cpp" "3" -"clanghighlightingmarksreporter.h" "3" +"clanghighlightingresultreporter.cpp" "3" +"clanghighlightingresultreporter.h" "3" +"clanghoverhandler.cpp" "3" +"clanghoverhandler.h" "3" "clangisdiagnosticrelatedtolocation.h" "3" "clangmodelmanagersupport.cpp" "3" "clangmodelmanagersupport.h" "3" +"clangoverviewmodel.cpp" "3" +"clangoverviewmodel.h" "3" "clangpreprocessorassistproposalitem.cpp" "3" "clangpreprocessorassistproposalitem.h" "3" "clangprojectsettings.cpp" "3" @@ -5354,29 +5809,127 @@ "clangprojectsettingswidget.cpp" "3" "clangprojectsettingswidget.h" "3" "clangprojectsettingswidget.ui" "3" +"clangrefactoringengine.cpp" "3" +"clangrefactoringengine.h" "3" "clangtextmark.cpp" "3" "clangtextmark.h" "3" "clanguiheaderondiskmanager.cpp" "3" "clanguiheaderondiskmanager.h" "3" "clangutils.cpp" "3" "clangutils.h" "3" -"ClangStaticAnalyzer" "2" -"clangstaticanalyzer.qbs:3" "3" +"ClangPchManager" "2" +"clangpchmanager.qbs:4" "3" +"PluginMetaData" "3" +"QtcPlugin.qbs:49" "4" +"ClangPchManager.json.in" "5" +"standard pch file (gui)" "3" +"QtcProduct.qbs:65" "4" +"qtcreator_gui_pch.h" "5" +"standard pch file (non-gui)" "3" +"QtcProduct.qbs:57" "4" +"qtcreator_pch.h" "5" +"clangpchmanager_global.h" "3" +"clangpchmanagerplugin.cpp" "3" +"clangpchmanagerplugin.h" "3" +"pchmanagerclient.cpp" "3" +"pchmanagerclient.h" "3" +"pchmanagerconnectionclient.cpp" "3" +"pchmanagerconnectionclient.h" "3" +"pchmanagernotifierinterface.cpp" "3" +"pchmanagernotifierinterface.h" "3" +"pchmanagerprojectupdater.cpp" "3" +"pchmanagerprojectupdater.h" "3" +"projectupdater.cpp" "3" +"projectupdater.h" "3" +"qtcreatorprojectupdater.cpp" "3" +"qtcreatorprojectupdater.h" "3" +"ClangRefactoring" "2" +"clangrefactoring.qbs:4" "3" +"PluginMetaData" "3" +"QtcPlugin.qbs:49" "4" +"ClangRefactoring.json.in" "5" +"standard pch file (gui)" "3" +"QtcProduct.qbs:65" "4" +"qtcreator_gui_pch.h" "5" +"standard pch file (non-gui)" "3" +"QtcProduct.qbs:57" "4" +"qtcreator_pch.h" "5" +"baseclangquerytexteditorwidget.cpp" "3" +"baseclangquerytexteditorwidget.h" "3" +"clangqueryexamplehighlighter.cpp" "3" +"clangqueryexamplehighlighter.h" "3" +"clangqueryexamplehighlightmarker.h" "3" +"clangqueryexampletexteditorwidget.cpp" "3" +"clangqueryexampletexteditorwidget.h" "3" +"clangqueryhighlighter.cpp" "3" +"clangqueryhighlighter.h" "3" +"clangqueryhighlightmarker.h" "3" +"clangqueryhoverhandler.cpp" "3" +"clangqueryhoverhandler.h" "3" +"clangqueryprojectsfindfilter.cpp" "3" +"clangqueryprojectsfindfilter.h" "3" +"clangqueryprojectsfindfilter.ui" "3" +"clangqueryprojectsfindfilterwidget.cpp" "3" +"clangqueryprojectsfindfilterwidget.h" "3" +"clangquerytexteditorwidget.cpp" "3" +"clangquerytexteditorwidget.h" "3" +"clangrefactoringplugin.cpp" "3" +"clangrefactoringplugin.h" "3" +"locatorfilter.cpp" "3" +"locatorfilter.h" "3" +"projectpartutilities.cpp" "3" +"projectpartutilities.h" "3" +"qtcreatorclangqueryfindfilter.cpp" "3" +"qtcreatorclangqueryfindfilter.h" "3" +"qtcreatoreditormanager.cpp" "3" +"qtcreatoreditormanager.h" "3" +"qtcreatorsearch.cpp" "3" +"qtcreatorsearch.h" "3" +"qtcreatorsearchhandle.cpp" "3" +"qtcreatorsearchhandle.h" "3" +"qtcreatorsymbolsfindfilter.cpp" "3" +"qtcreatorsymbolsfindfilter.h" "3" +"querysqlitestatementfactory.h" "3" +"refactoringclient.cpp" "3" +"refactoringclient.h" "3" +"refactoringconnectionclient.cpp" "3" +"refactoringconnectionclient.h" "3" +"refactoringengine.cpp" "3" +"refactoringengine.h" "3" +"refactoringprojectupdater.cpp" "3" +"refactoringprojectupdater.h" "3" +"searchhandle.cpp" "3" +"searchhandle.h" "3" +"searchinterface.h" "3" +"sourcelocations.h" "3" +"symbol.h" "3" +"symbolquery.h" "3" +"symbolqueryinterface.h" "3" +"symbolsfindfilter.cpp" "3" +"symbolsfindfilter.h" "3" +"symbolsfindfilterconfigwidget.cpp" "3" +"symbolsfindfilterconfigwidget.h" "3" +"ClangTools" "2" +"clangtools.qbs:4" "3" "Other files" "3" -"clangstaticanalyzer.qbs:75" "4" +"clangtools.qbs:111" "4" "creator-clang-static-analyzer.qdoc" "5" "PluginMetaData" "3" -"QtcPlugin.qbs:51" "4" -"ClangStaticAnalyzer.json.in" "5" +"QtcPlugin.qbs:49" "4" +"ClangTools.json.in" "5" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" "Unit test resources" "3" -"clangstaticanalyzer.qbs:68" "4" +"clangtools.qbs:104" "4" "unit-tests" "4" +"clangtidy_clazy" "5" +"clangtidy_clazy.pro" "6" +"clazy_example.cpp" "6" +"tidy_example.cpp" "6" "mingw-includes" "5" "main.cpp" "6" "mingw-includes.pro" "6" @@ -5406,54 +5959,67 @@ "stdc++11-includes.pro" "6" "stdc++11-includes.qbs" "6" "Unit tests" "3" -"clangstaticanalyzer.qbs:56" "4" -"clangstaticanalyzerpreconfiguredsessiontests.cpp" "4" -"clangstaticanalyzerpreconfiguredsessiontests.h" "4" -"clangstaticanalyzerunittests.cpp" "4" -"clangstaticanalyzerunittests.h" "4" -"clangstaticanalyzerunittests.qrc" "4" -"clangstaticanalyzer_global.h" "3" -"clangstaticanalyzerconfigwidget.cpp" "3" -"clangstaticanalyzerconfigwidget.h" "3" -"clangstaticanalyzerconfigwidget.ui" "3" -"clangstaticanalyzerconstants.h" "3" -"clangstaticanalyzerdiagnostic.cpp" "3" -"clangstaticanalyzerdiagnostic.h" "3" -"clangstaticanalyzerdiagnosticmodel.cpp" "3" -"clangstaticanalyzerdiagnosticmodel.h" "3" -"clangstaticanalyzerdiagnosticview.cpp" "3" -"clangstaticanalyzerdiagnosticview.h" "3" -"clangstaticanalyzerlogfilereader.cpp" "3" -"clangstaticanalyzerlogfilereader.h" "3" -"clangstaticanalyzerplugin.cpp" "3" -"clangstaticanalyzerplugin.h" "3" -"clangstaticanalyzerprojectsettings.cpp" "3" -"clangstaticanalyzerprojectsettings.h" "3" -"clangstaticanalyzerprojectsettingsmanager.cpp" "3" -"clangstaticanalyzerprojectsettingsmanager.h" "3" -"clangstaticanalyzerprojectsettingswidget.cpp" "3" -"clangstaticanalyzerprojectsettingswidget.h" "3" -"clangstaticanalyzerprojectsettingswidget.ui" "3" -"clangstaticanalyzerruncontrol.cpp" "3" -"clangstaticanalyzerruncontrol.h" "3" -"clangstaticanalyzerrunner.cpp" "3" -"clangstaticanalyzerrunner.h" "3" -"clangstaticanalyzersettings.cpp" "3" -"clangstaticanalyzersettings.h" "3" -"clangstaticanalyzertool.cpp" "3" -"clangstaticanalyzertool.h" "3" -"clangstaticanalyzerutils.cpp" "3" -"clangstaticanalyzerutils.h" "3" +"clangtools.qbs:92" "4" +"clangtoolspreconfiguredsessiontests.cpp" "4" +"clangtoolspreconfiguredsessiontests.h" "4" +"clangtoolsunittests.cpp" "4" +"clangtoolsunittests.h" "4" +"clangtoolsunittests.qrc" "4" +"clangfileinfo.h" "3" +"clangfixitsrefactoringchanges.cpp" "3" +"clangfixitsrefactoringchanges.h" "3" +"clangselectablefilesdialog.cpp" "3" +"clangselectablefilesdialog.h" "3" +"clangselectablefilesdialog.ui" "3" +"clangtidyclazyruncontrol.cpp" "3" +"clangtidyclazyruncontrol.h" "3" +"clangtidyclazyrunner.cpp" "3" +"clangtidyclazyrunner.h" "3" +"clangtidyclazytool.cpp" "3" +"clangtidyclazytool.h" "3" +"clangtool.cpp" "3" +"clangtool.h" "3" +"clangtoolruncontrol.cpp" "3" +"clangtoolruncontrol.h" "3" +"clangtoolrunner.cpp" "3" +"clangtoolrunner.h" "3" +"clangtools_global.h" "3" +"clangtoolsbasicsettings.cpp" "3" +"clangtoolsbasicsettings.h" "3" +"clangtoolsbasicsettings.ui" "3" +"clangtoolsconfigwidget.cpp" "3" +"clangtoolsconfigwidget.h" "3" +"clangtoolsconfigwidget.ui" "3" +"clangtoolsconstants.h" "3" +"clangtoolsdiagnostic.cpp" "3" +"clangtoolsdiagnostic.h" "3" +"clangtoolsdiagnosticmodel.cpp" "3" +"clangtoolsdiagnosticmodel.h" "3" +"clangtoolsdiagnosticview.cpp" "3" +"clangtoolsdiagnosticview.h" "3" +"clangtoolslogfilereader.cpp" "3" +"clangtoolslogfilereader.h" "3" +"clangtoolsplugin.cpp" "3" +"clangtoolsplugin.h" "3" +"clangtoolsprojectsettings.cpp" "3" +"clangtoolsprojectsettings.h" "3" +"clangtoolsprojectsettingswidget.cpp" "3" +"clangtoolsprojectsettingswidget.h" "3" +"clangtoolsprojectsettingswidget.ui" "3" +"clangtoolssettings.cpp" "3" +"clangtoolssettings.h" "3" +"clangtoolsutils.cpp" "3" +"clangtoolsutils.h" "3" "ClassView" "2" "classview.qbs:3" "3" "PluginMetaData" "3" -"QtcPlugin.qbs:51" "4" +"QtcPlugin.qbs:49" "4" "ClassView.json.in" "5" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" "classviewconstants.h" "3" "classviewmanager.cpp" "3" @@ -5479,13 +6045,13 @@ "ClearCase" "2" "clearcase.qbs:3" "3" "PluginMetaData" "3" -"QtcPlugin.qbs:51" "4" +"QtcPlugin.qbs:49" "4" "ClearCase.json.in" "5" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" "activityselector.cpp" "3" "activityselector.h" "3" @@ -5519,16 +6085,18 @@ "CMakeProjectManager" "2" "cmakeprojectmanager.qbs:3" "3" "PluginMetaData" "3" -"QtcPlugin.qbs:51" "4" +"QtcPlugin.qbs:49" "4" "CMakeProjectManager.json.in" "5" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" "builddirmanager.cpp" "3" "builddirmanager.h" "3" +"builddirparameters.cpp" "3" +"builddirparameters.h" "3" "builddirreader.cpp" "3" "builddirreader.h" "3" "cmake_global.h" "3" @@ -5541,6 +6109,8 @@ "cmakebuildsettingswidget.h" "3" "cmakebuildstep.cpp" "3" "cmakebuildstep.h" "3" +"cmakebuildtarget.cpp" "3" +"cmakebuildtarget.h" "3" "cmakecbpparser.cpp" "3" "cmakecbpparser.h" "3" "cmakeconfigitem.cpp" "3" @@ -5562,6 +6132,10 @@ "cmakeproject.cpp" "3" "cmakeproject.h" "3" "cmakeproject.qrc" "3" +"/cmakeproject" "4" +"images" "5" +"fileoverlay_cmake.png" "6" +"fileoverlay_cmake@2x.png" "6" "cmakeprojectconstants.h" "3" "cmakeprojectimporter.cpp" "3" "cmakeprojectimporter.h" "3" @@ -5575,6 +6149,11 @@ "cmakerunconfiguration.h" "3" "cmakesettingspage.cpp" "3" "cmakesettingspage.h" "3" +"cmakespecificsettings.cpp" "3" +"cmakespecificsettings.h" "3" +"cmakespecificsettingspage.cpp" "3" +"cmakespecificsettingspage.h" "3" +"cmakespecificsettingspage.ui" "3" "cmaketool.cpp" "3" "cmaketool.h" "3" "cmaketoolmanager.cpp" "3" @@ -5594,25 +6173,29 @@ "CodePaster" "2" "cpaster.qbs:3" "3" "PluginMetaData" "3" -"QtcPlugin.qbs:51" "4" +"QtcPlugin.qbs:49" "4" "CodePaster.json.in" "5" "Shared" "3" -"cpaster.qbs:52" "4" +"cpaster.qbs:53" "4" "cgi.cpp" "5" "cgi.h" "5" "splitter.cpp" "5" "splitter.h" "5" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" "authenticationdialog.cpp" "3" "authenticationdialog.h" "3" "columnindicatortextedit.cpp" "3" "columnindicatortextedit.h" "3" "cpaster.qrc" "3" +"/cpaster" "4" +"images" "5" +"settingscategory_cpaster.png" "6" +"settingscategory_cpaster@2x.png" "6" "cpasterconstants.h" "3" "cpasterplugin.cpp" "3" "cpasterplugin.h" "3" @@ -5648,7 +6231,7 @@ "Core" "3" "coreplugin.qbs:9" "4" "Action Manager" "4" -"coreplugin.qbs:112" "5" +"coreplugin.qbs:191" "5" "actionmanager" "5" "actioncontainer.cpp" "6" "actioncontainer.h" "6" @@ -5666,7 +6249,7 @@ "commandsfile.cpp" "6" "commandsfile.h" "6" "Dialogs" "4" -"coreplugin.qbs:125" "5" +"coreplugin.qbs:204" "5" "dialogs" "5" "addtovcsdialog.cpp" "6" "addtovcsdialog.h" "6" @@ -5674,6 +6257,9 @@ "externaltoolconfig.cpp" "6" "externaltoolconfig.h" "6" "externaltoolconfig.ui" "6" +"filepropertiesdialog.cpp" "6" +"filepropertiesdialog.h" "6" +"filepropertiesdialog.ui" "6" "ioptionspage.cpp" "6" "ioptionspage.h" "6" "newdialog.cpp" "6" @@ -5695,7 +6281,7 @@ "shortcutsettings.cpp" "6" "shortcutsettings.h" "6" "Editor Manager" "4" -"coreplugin.qbs:142" "5" +"coreplugin.qbs:222" "5" "editormanager" "5" "documentmodel.cpp" "6" "documentmodel.h" "6" @@ -5722,13 +6308,27 @@ "systemeditor.cpp" "6" "systemeditor.h" "6" "Find" "4" -"coreplugin.qbs:209" "5" +"coreplugin.qbs:289" "5" "find" "5" "basetextfind.cpp" "6" "basetextfind.h" "6" "currentdocumentfind.cpp" "6" "currentdocumentfind.h" "6" "find.qrc" "6" +"/find" "7" +"images" "8" +"casesensitively.png" "9" +"casesensitively@2x.png" "9" +"expand.png" "9" +"expand@2x.png" "9" +"preservecase.png" "9" +"preservecase@2x.png" "9" +"regexp.png" "9" +"regexp@2x.png" "9" +"wholewords.png" "9" +"wholewords@2x.png" "9" +"wrapindicator.png" "9" +"wrapindicator@2x.png" "9" "finddialog.ui" "6" "findplugin.cpp" "6" "findplugin.h" "6" @@ -5737,8 +6337,8 @@ "findtoolwindow.cpp" "6" "findtoolwindow.h" "6" "findwidget.ui" "6" -"highlightscrollbar.cpp" "6" -"highlightscrollbar.h" "6" +"highlightscrollbarcontroller.cpp" "6" +"highlightscrollbarcontroller.h" "6" "ifindfilter.cpp" "6" "ifindfilter.h" "6" "ifindsupport.cpp" "6" @@ -5761,12 +6361,20 @@ "searchresultwindow.h" "6" "textfindconstants.h" "6" "General" "4" -"coreplugin.qbs:32" "5" +"coreplugin.qbs:39" "5" "basefilewizard.cpp" "5" "basefilewizard.h" "5" "basefilewizardfactory.cpp" "5" "basefilewizardfactory.h" "5" "core.qrc" "5" +"/core" "6" +"images" "7" +"qtcreatorlogo-big.png" "8" +"qtcreatorlogo-big@2x.png" "8" +"settingscategory_core.png" "8" +"settingscategory_core@2x.png" "8" +"settingscategory_design.png" "8" +"settingscategory_design@2x.png" "8" "core_global.h" "5" "coreconstants.h" "5" "coreicons.cpp" "5" @@ -5777,6 +6385,7 @@ "coreplugin.h" "5" "designmode.cpp" "5" "designmode.h" "5" +"diffservice.cpp" "5" "diffservice.h" "5" "documentmanager.cpp" "5" "documentmanager.h" "5" @@ -5791,6 +6400,16 @@ "fancyactionbar.cpp" "5" "fancyactionbar.h" "5" "fancyactionbar.qrc" "5" +"/fancyactionbar" "6" +"images" "7" +"mode_Design.png" "8" +"mode_Design@2x.png" "8" +"mode_design_mask.png" "8" +"mode_design_mask@2x.png" "8" +"mode_Edit.png" "8" +"mode_Edit@2x.png" "8" +"mode_edit_mask.png" "8" +"mode_edit_mask@2x.png" "8" "fancytabwidget.cpp" "5" "fancytabwidget.h" "5" "featureprovider.cpp" "5" @@ -5839,6 +6458,8 @@ "mainwindow.h" "5" "manhattanstyle.cpp" "5" "manhattanstyle.h" "5" +"menubarfilter.cpp" "5" +"menubarfilter.h" "5" "messagebox.cpp" "5" "messagebox.h" "5" "messagemanager.cpp" "5" @@ -5874,9 +6495,6 @@ "reaper.cpp" "5" "reaper.h" "5" "reaper_p.h" "5" -"removefiledialog.cpp" "5" -"removefiledialog.h" "5" -"removefiledialog.ui" "5" "rightpane.cpp" "5" "rightpane.h" "5" "settingsdatabase.cpp" "5" @@ -5889,8 +6507,6 @@ "sidebarwidget.h" "5" "statusbarmanager.cpp" "5" "statusbarmanager.h" "5" -"statusbarwidget.cpp" "5" -"statusbarwidget.h" "5" "styleanimator.cpp" "5" "styleanimator.h" "5" "systemsettings.cpp" "5" @@ -5911,7 +6527,7 @@ "windowsupport.cpp" "5" "windowsupport.h" "5" "Locator" "4" -"coreplugin.qbs:252" "5" +"coreplugin.qbs:332" "5" "locator" "5" "basefilefilter.cpp" "6" "basefilefilter.h" "6" @@ -5945,16 +6561,21 @@ "locatorwidget.h" "6" "opendocumentsfilter.cpp" "6" "opendocumentsfilter.h" "6" +"Locator Javascript Filter" "4" +"coreplugin.qbs:371" "5" +"locator" "5" +"javascriptfilter.cpp" "6" +"javascriptfilter.h" "6" "Locator_mac" "4" -"coreplugin.qbs:291" "5" +"coreplugin.qbs:381" "5" "locator" "5" "spotlightlocatorfilter.h" "6" "spotlightlocatorfilter.mm" "6" "PluginMetaData" "4" -"QtcPlugin.qbs:51" "5" +"QtcPlugin.qbs:49" "5" "Core.json.in" "6" "Progress Manager" "4" -"coreplugin.qbs:160" "5" +"coreplugin.qbs:240" "5" "progressmanager" "5" "futureprogress.cpp" "6" "futureprogress.h" "6" @@ -5966,25 +6587,25 @@ "progressview.cpp" "6" "progressview.h" "6" "ProgressManager_mac" "4" -"coreplugin.qbs:179" "5" +"coreplugin.qbs:259" "5" "progressmanager" "5" "progressmanager_mac.mm" "6" "ProgressManager_win" "4" -"coreplugin.qbs:171" "5" +"coreplugin.qbs:251" "5" "progressmanager" "5" "progressmanager_win.cpp" "6" "ProgressManager_x11" "4" -"coreplugin.qbs:187" "5" +"coreplugin.qbs:267" "5" "progressmanager" "5" "progressmanager_x11.cpp" "6" "standard pch file (gui)" "4" -"QtcProduct.qbs:58" "5" +"QtcProduct.qbs:65" "5" "qtcreator_gui_pch.h" "6" "standard pch file (non-gui)" "4" -"QtcProduct.qbs:50" "5" +"QtcProduct.qbs:57" "5" "qtcreator_pch.h" "6" "Tests" "4" -"coreplugin.qbs:195" "5" +"coreplugin.qbs:275" "5" "locator" "5" "locator_test.cpp" "6" "locatorfiltertest.cpp" "6" @@ -6008,6 +6629,7 @@ "dialogs" "6" "addtovcsdialog.h" "7" "externaltoolconfig.h" "7" +"filepropertiesdialog.h" "7" "ioptionspage.h" "7" "newdialog.h" "7" "openwithdialog.h" "7" @@ -6036,7 +6658,7 @@ "findplugin.h" "7" "findtoolbar.h" "7" "findtoolwindow.h" "7" -"highlightscrollbar.h" "7" +"highlightscrollbarcontroller.h" "7" "ifindfilter.h" "7" "ifindsupport.h" "7" "itemviewfind.h" "7" @@ -6058,6 +6680,7 @@ "externaltoolsfilter.h" "7" "filesystemfilter.h" "7" "ilocatorfilter.h" "7" +"javascriptfilter.h" "7" "locator.h" "7" "locatorconstants.h" "7" "locatorfiltersfilter.h" "7" @@ -6113,6 +6736,7 @@ "jsexpander.h" "6" "mainwindow.h" "6" "manhattanstyle.h" "6" +"menubarfilter.h" "6" "messagebox.h" "6" "messagemanager.h" "6" "messageoutputwindow.h" "6" @@ -6130,14 +6754,12 @@ "plugindialog.h" "6" "reaper.h" "6" "reaper_p.h" "6" -"removefiledialog.h" "6" "rightpane.h" "6" "settingsdatabase.h" "6" "shellcommand.h" "6" "sidebar.h" "6" "sidebarwidget.h" "6" "statusbarmanager.h" "6" -"statusbarwidget.h" "6" "styleanimator.h" "6" "systemsettings.h" "6" "testdatadir.h" "6" @@ -6169,24 +6791,24 @@ "urlopenprotocol.cpp" "5" "urlopenprotocol.h" "5" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" "CppEditor" "2" "cppeditor.qbs:4" "3" "PluginMetaData" "3" -"QtcPlugin.qbs:51" "4" +"QtcPlugin.qbs:49" "4" "CppEditor.json.in" "5" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" "Tests" "3" -"cppeditor.qbs:83" "4" +"cppeditor.qbs:75" "4" "cppdoxygen_test.cpp" "4" "cppdoxygen_test.h" "4" "cppeditortestcase.cpp" "4" @@ -6207,6 +6829,14 @@ "cppeditor.cpp" "3" "cppeditor.h" "3" "cppeditor.qrc" "3" +"/cppeditor" "4" +"images" "5" +"dark_qt_c.png" "6" +"dark_qt_cpp.png" "6" +"dark_qt_h.png" "6" +"qt_c.png" "6" +"qt_cpp.png" "6" +"qt_h.png" "6" "cppeditor_global.h" "3" "cppeditorconstants.h" "3" "cppeditordocument.cpp" "3" @@ -6214,16 +6844,12 @@ "cppeditorenums.h" "3" "cppeditorplugin.cpp" "3" "cppeditorplugin.h" "3" -"cppelementevaluator.cpp" "3" -"cppelementevaluator.h" "3" -"cppfollowsymbolundercursor.cpp" "3" -"cppfollowsymbolundercursor.h" "3" +"cppeditorwidget.cpp" "3" +"cppeditorwidget.h" "3" "cppfunctiondecldeflink.cpp" "3" "cppfunctiondecldeflink.h" "3" "cpphighlighter.cpp" "3" "cpphighlighter.h" "3" -"cpphoverhandler.cpp" "3" -"cpphoverhandler.h" "3" "cppincludehierarchy.cpp" "3" "cppincludehierarchy.h" "3" "cppinsertvirtualmethods.cpp" "3" @@ -6249,10 +6875,6 @@ "cpptypehierarchy.h" "3" "cppuseselectionsupdater.cpp" "3" "cppuseselectionsupdater.h" "3" -"cppvirtualfunctionassistprovider.cpp" "3" -"cppvirtualfunctionassistprovider.h" "3" -"cppvirtualfunctionproposalitem.cpp" "3" -"cppvirtualfunctionproposalitem.h" "3" "resourcepreviewhoverhandler.cpp" "3" "resourcepreviewhoverhandler.h" "3" "CppTools" "2" @@ -6260,16 +6882,16 @@ "CppTools" "3" "cpptools.qbs:9" "4" "PluginMetaData" "4" -"QtcPlugin.qbs:51" "5" +"QtcPlugin.qbs:49" "5" "CppTools.json.in" "6" "standard pch file (gui)" "4" -"QtcProduct.qbs:58" "5" +"QtcProduct.qbs:65" "5" "qtcreator_gui_pch.h" "6" "standard pch file (non-gui)" "4" -"QtcProduct.qbs:50" "5" +"QtcProduct.qbs:57" "5" "qtcreator_pch.h" "6" "Tests" "4" -"cpptools.qbs:197" "5" +"cpptools.qbs:222" "5" "cppcodegen_test.cpp" "5" "cppcompletion_test.cpp" "5" "cppheadersource_test.cpp" "5" @@ -6288,6 +6910,7 @@ "typehierarchybuilder_test.cpp" "5" "abstracteditorsupport.cpp" "4" "abstracteditorsupport.h" "4" +"abstractoverviewmodel.h" "4" "baseeditordocumentparser.cpp" "4" "baseeditordocumentparser.h" "4" "baseeditordocumentprocessor.cpp" "4" @@ -6300,15 +6923,17 @@ "builtineditordocumentprocessor.h" "4" "builtinindexingsupport.cpp" "4" "builtinindexingsupport.h" "4" -"clangcompileroptionsbuilder.cpp" "4" -"clangcompileroptionsbuilder.h" "4" +"clangbasechecks.ui" "4" "clangdiagnosticconfig.cpp" "4" "clangdiagnosticconfig.h" "4" "clangdiagnosticconfigsmodel.cpp" "4" "clangdiagnosticconfigsmodel.h" "4" +"clangdiagnosticconfigsselectionwidget.cpp" "4" +"clangdiagnosticconfigsselectionwidget.h" "4" "clangdiagnosticconfigswidget.cpp" "4" "clangdiagnosticconfigswidget.h" "4" "clangdiagnosticconfigswidget.ui" "4" +"clazychecks.ui" "4" "compileroptionsbuilder.cpp" "4" "compileroptionsbuilder.h" "4" "cppcanonicalsymbol.cpp" "4" @@ -6348,6 +6973,9 @@ "cppdoxygen.h" "4" "cppeditoroutline.cpp" "4" "cppeditoroutline.h" "4" +"cppeditorwidgetinterface.h" "4" +"cppelementevaluator.cpp" "4" +"cppelementevaluator.h" "4" "cppfileiterationorder.cpp" "4" "cppfileiterationorder.h" "4" "cppfilesettingspage.cpp" "4" @@ -6355,8 +6983,12 @@ "cppfilesettingspage.ui" "4" "cppfindreferences.cpp" "4" "cppfindreferences.h" "4" +"cppfollowsymbolundercursor.cpp" "4" +"cppfollowsymbolundercursor.h" "4" "cppfunctionsfilter.cpp" "4" "cppfunctionsfilter.h" "4" +"cpphoverhandler.cpp" "4" +"cpphoverhandler.h" "4" "cppincludesfilter.cpp" "4" "cppincludesfilter.h" "4" "cppindexingsupport.cpp" "4" @@ -6373,6 +7005,8 @@ "cppmodelmanagersupport.h" "4" "cppmodelmanagersupportinternal.cpp" "4" "cppmodelmanagersupportinternal.h" "4" +"cppoverviewmodel.cpp" "4" +"cppoverviewmodel.h" "4" "cpppointerdeclarationformatter.cpp" "4" "cpppointerdeclarationformatter.h" "4" "cppprojectfile.cpp" "4" @@ -6391,6 +7025,8 @@ "cpprawprojectpart.h" "4" "cpprefactoringchanges.cpp" "4" "cpprefactoringchanges.h" "4" +"cpprefactoringengine.cpp" "4" +"cpprefactoringengine.h" "4" "cppselectionchanger.cpp" "4" "cppselectionchanger.h" "4" "cppsemanticinfo.h" "4" @@ -6399,6 +7035,11 @@ "cppsourceprocessor.cpp" "4" "cppsourceprocessor.h" "4" "cpptools.qrc" "4" +"/cpptools" "5" +"images" "6" +"settingscategory_cpp.png" "7" +"settingscategory_cpp@2x.png" "7" +"cpptools_clangtidychecks.h" "4" "cpptools_global.h" "4" "cpptools_utils.h" "4" "cpptoolsbridge.cpp" "4" @@ -6415,12 +7056,18 @@ "cpptoolsreuse.h" "4" "cpptoolssettings.cpp" "4" "cpptoolssettings.h" "4" +"cppvirtualfunctionassistprovider.cpp" "4" +"cppvirtualfunctionassistprovider.h" "4" +"cppvirtualfunctionproposalitem.cpp" "4" +"cppvirtualfunctionproposalitem.h" "4" "cppworkingcopy.cpp" "4" "cppworkingcopy.h" "4" +"cursorineditor.h" "4" "doxygengenerator.cpp" "4" "doxygengenerator.h" "4" "editordocumenthandle.cpp" "4" "editordocumenthandle.h" "4" +"followsymbolinterface.h" "4" "functionutils.cpp" "4" "functionutils.h" "4" "generatedcodemodelsupport.cpp" "4" @@ -6448,22 +7095,27 @@ "symbolfinder.h" "4" "symbolsfindfilter.cpp" "4" "symbolsfindfilter.h" "4" +"tidychecks.ui" "4" "typehierarchybuilder.cpp" "4" "typehierarchybuilder.h" "4" +"usages.h" "4" +"wrappablelineedit.cpp" "4" +"wrappablelineedit.h" "4" "CppTools dev headers" "3" "cpptools.qbs:7" "4" "Group 1" "4" "QtcDevHeaders.qbs:10" "5" "abstracteditorsupport.h" "6" +"abstractoverviewmodel.h" "6" "baseeditordocumentparser.h" "6" "baseeditordocumentprocessor.h" "6" "builtincursorinfo.h" "6" "builtineditordocumentparser.h" "6" "builtineditordocumentprocessor.h" "6" "builtinindexingsupport.h" "6" -"clangcompileroptionsbuilder.h" "6" "clangdiagnosticconfig.h" "6" "clangdiagnosticconfigsmodel.h" "6" +"clangdiagnosticconfigsselectionwidget.h" "6" "clangdiagnosticconfigswidget.h" "6" "compileroptionsbuilder.h" "6" "cppcanonicalsymbol.h" "6" @@ -6484,10 +7136,14 @@ "cppcursorinfo.h" "6" "cppdoxygen.h" "6" "cppeditoroutline.h" "6" +"cppeditorwidgetinterface.h" "6" +"cppelementevaluator.h" "6" "cppfileiterationorder.h" "6" "cppfilesettingspage.h" "6" "cppfindreferences.h" "6" +"cppfollowsymbolundercursor.h" "6" "cppfunctionsfilter.h" "6" +"cpphoverhandler.h" "6" "cppincludesfilter.h" "6" "cppindexingsupport.h" "6" "cpplocalsymbols.h" "6" @@ -6496,6 +7152,7 @@ "cppmodelmanager.h" "6" "cppmodelmanagersupport.h" "6" "cppmodelmanagersupportinternal.h" "6" +"cppoverviewmodel.h" "6" "cpppointerdeclarationformatter.h" "6" "cppprojectfile.h" "6" "cppprojectfilecategorizer.h" "6" @@ -6505,11 +7162,14 @@ "cppqtstyleindenter.h" "6" "cpprawprojectpart.h" "6" "cpprefactoringchanges.h" "6" +"cpprefactoringengine.h" "6" "cppselectionchanger.h" "6" "cppsemanticinfo.h" "6" "cppsemanticinfoupdater.h" "6" "cppsourceprocessertesthelper.h" "6" "cppsourceprocessor.h" "6" +"cppsymbolinfo.h" "6" +"cpptools_clangtidychecks.h" "6" "cpptools_global.h" "6" "cpptools_utils.h" "6" "cpptoolsbridge.h" "6" @@ -6521,9 +7181,13 @@ "cpptoolsreuse.h" "6" "cpptoolssettings.h" "6" "cpptoolstestcase.h" "6" +"cppvirtualfunctionassistprovider.h" "6" +"cppvirtualfunctionproposalitem.h" "6" "cppworkingcopy.h" "6" +"cursorineditor.h" "6" "doxygengenerator.h" "6" "editordocumenthandle.h" "6" +"followsymbolinterface.h" "6" "functionutils.h" "6" "generatedcodemodelsupport.h" "6" "includeutils.h" "6" @@ -6541,16 +7205,18 @@ "symbolfinder.h" "6" "symbolsfindfilter.h" "6" "typehierarchybuilder.h" "6" +"usages.h" "6" +"wrappablelineedit.h" "6" "CVS" "2" "cvs.qbs:3" "3" "PluginMetaData" "3" -"QtcPlugin.qbs:51" "4" +"QtcPlugin.qbs:49" "4" "CVS.json.in" "5" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" "annotationhighlighter.cpp" "3" "annotationhighlighter.h" "3" @@ -6576,10 +7242,15 @@ "Debugger" "3" "debugger.qbs:8" "4" "Analyzer" "4" -"debugger.qbs:233" "5" +"debugger.qbs:227" "5" "analyzer" "5" "analyzerbase.qrc" "6" +"/" "7" +"images" "8" +"settingscategory_analyzer.png" "9" +"settingscategory_analyzer@2x.png" "9" "analyzerconstants.h" "6" +"analyzericons.h" "6" "analyzermanager.h" "6" "analyzerrunconfigwidget.cpp" "6" "analyzerrunconfigwidget.h" "6" @@ -6604,7 +7275,7 @@ "stringinputstream.cpp" "6" "stringinputstream.h" "6" "Debugger Console" "4" -"debugger.qbs:160" "5" +"debugger.qbs:154" "5" "console" "5" "console.cpp" "6" "console.h" "6" @@ -6623,23 +7294,11 @@ "gdb" "4" "debugger.qbs:107" "5" "gdb" "5" -"attachgdbadapter.cpp" "6" -"attachgdbadapter.h" "6" -"coregdbadapter.cpp" "6" -"coregdbadapter.h" "6" "gdbengine.cpp" "6" "gdbengine.h" "6" "gdboptionspage.cpp" "6" -"gdbplainengine.cpp" "6" -"gdbplainengine.h" "6" -"remotegdbserveradapter.cpp" "6" -"remotegdbserveradapter.h" "6" -"startgdbserverdialog.cpp" "6" -"startgdbserverdialog.h" "6" -"termgdbadapter.cpp" "6" -"termgdbadapter.h" "6" "General" "4" -"debugger.qbs:36" "5" +"debugger.qbs:37" "5" "breakhandler.cpp" "5" "breakhandler.h" "5" "breakpoint.cpp" "5" @@ -6647,6 +7306,55 @@ "commonoptionspage.cpp" "5" "commonoptionspage.h" "5" "debugger.qrc" "5" +"/debugger" "6" +"images" "7" +"breakpoint_disabled.png" "8" +"breakpoint_disabled@2x.png" "8" +"breakpoint_pending_overlay.png" "8" +"breakpoint_pending_overlay@2x.png" "8" +"debugger_breakpoints.png" "8" +"debugger_continue.png" "8" +"debugger_continue@2x.png" "8" +"debugger_continue_1_mask.png" "8" +"debugger_continue_1_mask@2x.png" "8" +"debugger_continue_2_mask.png" "8" +"debugger_continue_2_mask@2x.png" "8" +"debugger_empty_14.png" "8" +"debugger_interrupt.png" "8" +"debugger_interrupt@2x.png" "8" +"debugger_interrupt_mask.png" "8" +"debugger_interrupt_mask@2x.png" "8" +"debugger_restart_small.png" "8" +"debugger_restart_small@2x.png" "8" +"debugger_reversemode.png" "8" +"debugger_reversemode@2x.png" "8" +"debugger_reversemode_background.png" "8" +"debugger_reversemode_background@2x.png" "8" +"debugger_singleinstructionmode.png" "8" +"debugger_singleinstructionmode@2x.png" "8" +"debugger_stepinto_small.png" "8" +"debugger_stepinto_small@2x.png" "8" +"debugger_stepout_small.png" "8" +"debugger_stepout_small@2x.png" "8" +"debugger_stepover_small.png" "8" +"debugger_stepover_small@2x.png" "8" +"location.png" "8" +"location@2x.png" "8" +"location_background.png" "8" +"location_background@2x.png" "8" +"mode_debug.png" "8" +"mode_debug@2x.png" "8" +"mode_debug_mask.png" "8" +"mode_debug_mask@2x.png" "8" +"pin.xpm" "8" +"recordfill.png" "8" +"recordfill@2x.png" "8" +"recordoutline.png" "8" +"recordoutline@2x.png" "8" +"settingscategory_debugger.png" "8" +"settingscategory_debugger@2x.png" "8" +"tracepointoverlay.png" "8" +"tracepointoverlay@2x.png" "8" "debugger_global.h" "5" "debuggeractions.cpp" "5" "debuggeractions.h" "5" @@ -6679,7 +7387,6 @@ "debuggerruncontrol.h" "5" "debuggersourcepathmappingwidget.cpp" "5" "debuggersourcepathmappingwidget.h" "5" -"debuggerstartparameters.h" "5" "debuggertooltipmanager.cpp" "5" "debuggertooltipmanager.h" "5" "disassembleragent.cpp" "5" @@ -6740,13 +7447,12 @@ "watchwindow.cpp" "5" "watchwindow.h" "5" "Images" "4" -"debugger.qbs:187" "5" +"debugger.qbs:181" "5" "images" "5" "breakpoint_disabled.png" "6" "breakpoint_disabled@2x.png" "6" "breakpoint_pending_overlay.png" "6" "breakpoint_pending_overlay@2x.png" "6" -"category_debug.png" "6" "debugger_breakpoints.png" "6" "debugger_continue.png" "6" "debugger_continue@2x.png" "6" @@ -6787,24 +7493,23 @@ "recordfill@2x.png" "6" "recordoutline.png" "6" "recordoutline@2x.png" "6" +"settingscategory_debugger.png" "6" +"settingscategory_debugger@2x.png" "6" "tracepointoverlay.png" "6" "tracepointoverlay@2x.png" "6" "Images/analyzer" "4" -"debugger.qbs:199" "5" -"analyzer_category.png" "6" -"Images/qml" "4" "debugger.qbs:193" "5" -"app-on-top.png" "6" -"app-on-top@2x.png" "6" -"select.png" "6" -"select@2x.png" "6" +"settingscategory_analyzer.png" "6" +"settingscategory_analyzer@2x.png" "6" +"Images/qml" "4" +"debugger.qbs:187" "5" "lldb" "4" -"debugger.qbs:122" "5" +"debugger.qbs:116" "5" "lldb" "5" "lldbengine.cpp" "6" "lldbengine.h" "6" "Name Demangler" "4" -"debugger.qbs:136" "5" +"debugger.qbs:130" "5" "namedemangler" "5" "demanglerexceptions.h" "6" "globalparsestate.cpp" "6" @@ -6814,15 +7519,15 @@ "parsetreenodes.cpp" "6" "parsetreenodes.h" "6" "pdb" "4" -"debugger.qbs:130" "5" +"debugger.qbs:124" "5" "pdb" "5" "pdbengine.cpp" "6" "pdbengine.h" "6" "PluginMetaData" "4" -"QtcPlugin.qbs:51" "5" +"QtcPlugin.qbs:49" "5" "Debugger.json.in" "6" "QML Debugger" "4" -"debugger.qbs:147" "5" +"debugger.qbs:141" "5" "qml" "5" "interactiveinterpreter.cpp" "6" "interactiveinterpreter.h" "6" @@ -6836,15 +7541,15 @@ "qmlinspectoragent.h" "6" "qmlv8debuggerclientconstants.h" "6" "RegisterPostMortem" "4" -"debugger.qbs:215" "5" +"debugger.qbs:209" "5" "registerpostmortemaction.cpp" "5" "registerpostmortemaction.h" "5" "RegistryAccess" "4" -"debugger.qbs:205" "5" +"debugger.qbs:199" "5" "registryaccess.cpp" "6" "registryaccess.h" "6" "shared" "4" -"debugger.qbs:174" "5" +"debugger.qbs:168" "5" "shared" "5" "backtrace.cpp" "6" "backtrace.h" "6" @@ -6858,24 +7563,30 @@ "symbolpathsdialog.h" "6" "symbolpathsdialog.ui" "6" "standard pch file (gui)" "4" -"QtcProduct.qbs:58" "5" +"QtcProduct.qbs:65" "5" "qtcreator_gui_pch.h" "6" "standard pch file (non-gui)" "4" -"QtcProduct.qbs:50" "5" +"QtcProduct.qbs:57" "5" "qtcreator_pch.h" "6" "Unit test resources" "4" -"debugger.qbs:261" "5" +"debugger.qbs:256" "5" "main.cpp" "6" "simple.pro" "6" "Unit tests" "4" -"debugger.qbs:253" "5" +"debugger.qbs:248" "5" "debuggerunittests.qrc" "5" +"/" "6" +"unit-tests" "7" +"simple" "8" +"main.cpp" "9" +"simple.pro" "9" "Debugger dev headers" "3" "debugger.qbs:6" "4" "Group 1" "4" "QtcDevHeaders.qbs:10" "5" "analyzer" "6" "analyzerconstants.h" "7" +"analyzericons.h" "7" "analyzermanager.h" "7" "analyzerrunconfigwidget.h" "7" "analyzerutils.h" "7" @@ -6896,13 +7607,7 @@ "consoleproxymodel.h" "7" "consoleview.h" "7" "gdb" "6" -"attachgdbadapter.h" "7" -"coregdbadapter.h" "7" "gdbengine.h" "7" -"gdbplainengine.h" "7" -"remotegdbserveradapter.h" "7" -"startgdbserverdialog.h" "7" -"termgdbadapter.h" "7" "lldb" "6" "lldbengine.h" "7" "namedemangler" "6" @@ -6946,7 +7651,6 @@ "debuggerrunconfigurationaspect.h" "6" "debuggerruncontrol.h" "6" "debuggersourcepathmappingwidget.h" "6" -"debuggerstartparameters.h" "6" "debuggertooltipmanager.h" "6" "disassembleragent.h" "6" "disassemblerlines.h" "6" @@ -7029,7 +7733,7 @@ "settingspage.cpp" "4" "settingspage.h" "4" "PluginMetaData" "3" -"QtcPlugin.qbs:51" "4" +"QtcPlugin.qbs:49" "4" "Designer.json.in" "5" "Shared Sources" "3" "designer.qbs:55" "4" @@ -7041,10 +7745,10 @@ "widgethost.h" "5" "widgethostconstants.h" "5" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" "Tests" "3" "designer.qbs:78" "4" @@ -7052,17 +7756,27 @@ "DiffEditor" "2" "diffeditor.qbs:3" "3" "PluginMetaData" "3" -"QtcPlugin.qbs:51" "4" +"QtcPlugin.qbs:49" "4" "DiffEditor.json.in" "5" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" +"descriptionwidgetwatcher.cpp" "3" +"descriptionwidgetwatcher.h" "3" "diffeditor.cpp" "3" "diffeditor.h" "3" "diffeditor.qrc" "3" +"/diffeditor" "4" +"images" "5" +"sidebysidediff.png" "6" +"sidebysidediff@2x.png" "6" +"topbar.png" "6" +"topbar@2x.png" "6" +"unifieddiff.png" "6" +"unifieddiff@2x.png" "6" "diffeditor_global.h" "3" "diffeditorconstants.h" "3" "diffeditorcontroller.cpp" "3" @@ -7091,13 +7805,13 @@ "EmacsKeys" "2" "emacskeys.qbs:3" "3" "PluginMetaData" "3" -"QtcPlugin.qbs:51" "4" +"QtcPlugin.qbs:49" "4" "EmacsKeys.json.in" "5" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" "emacskeysconstants.h" "3" "emacskeysplugin.cpp" "3" @@ -7107,18 +7821,22 @@ "FakeVim" "2" "fakevim.qbs:3" "3" "PluginMetaData" "3" -"QtcPlugin.qbs:51" "4" +"QtcPlugin.qbs:49" "4" "FakeVim.json.in" "5" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" "Tests" "3" "fakevim.qbs:30" "4" "fakevim_test.cpp" "4" "fakevim.qrc" "3" +"/fakevim" "4" +"images" "5" +"settingscategory_fakevim.png" "6" +"settingscategory_fakevim@2x.png" "6" "fakevimactions.cpp" "3" "fakevimactions.h" "3" "fakevimhandler.cpp" "3" @@ -7130,16 +7848,16 @@ "GenericProjectManager" "2" "genericprojectmanager.qbs:4" "3" "PluginMetaData" "3" -"QtcPlugin.qbs:51" "4" +"QtcPlugin.qbs:49" "4" "GenericProjectManager.json.in" "5" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" "Tests" "3" -"genericprojectmanager.qbs:39" "4" +"genericprojectmanager.qbs:40" "4" "genericprojectplugin_test.cpp" "4" "filesselectionwizardpage.cpp" "3" "filesselectionwizardpage.h" "3" @@ -7160,7 +7878,7 @@ "Git" "2" "git.qbs:3" "3" "Gerrit" "3" -"git.qbs:76" "4" +"git.qbs:78" "4" "gerrit" "4" "authenticationdialog.cpp" "5" "authenticationdialog.h" "5" @@ -7186,13 +7904,13 @@ "gerritserver.cpp" "5" "gerritserver.h" "5" "PluginMetaData" "3" -"QtcPlugin.qbs:51" "4" +"QtcPlugin.qbs:49" "4" "Git.json.in" "5" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" "annotationhighlighter.cpp" "3" "annotationhighlighter.h" "3" @@ -7207,12 +7925,17 @@ "branchdialog.ui" "3" "branchmodel.cpp" "3" "branchmodel.h" "3" +"branchutils.cpp" "3" +"branchutils.h" "3" "changeselectiondialog.cpp" "3" "changeselectiondialog.h" "3" "changeselectiondialog.ui" "3" "commitdata.cpp" "3" "commitdata.h" "3" "git.qrc" "3" +"/git" "4" +"images" "5" +"arrowup.png" "6" "gitclient.cpp" "3" "gitclient.h" "3" "gitconstants.h" "3" @@ -7254,13 +7977,13 @@ "GLSLEditor" "2" "glsleditor.qbs:3" "3" "PluginMetaData" "3" -"QtcPlugin.qbs:51" "4" +"QtcPlugin.qbs:49" "4" "GLSLEditor.json.in" "5" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" "glslautocompleter.cpp" "3" "glslautocompleter.h" "3" @@ -7269,6 +7992,9 @@ "glsleditor.cpp" "3" "glsleditor.h" "3" "glsleditor.qrc" "3" +"/glsleditor" "4" +"images" "5" +"glslfile.png" "6" "glsleditorconstants.h" "3" "glsleditorplugin.cpp" "3" "glsleditorplugin.h" "3" @@ -7279,13 +8005,13 @@ "HelloWorld" "2" "helloworld.qbs:3" "3" "PluginMetaData" "3" -"QtcPlugin.qbs:51" "4" +"QtcPlugin.qbs:49" "4" "HelloWorld.json.in" "5" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" "helloworldplugin.cpp" "3" "helloworldplugin.h" "3" @@ -7294,10 +8020,10 @@ "Help" "2" "help.qbs:3" "3" "PluginMetaData" "3" -"QtcPlugin.qbs:51" "4" +"QtcPlugin.qbs:49" "4" "Help.json.in" "5" "Shared Sources" "3" -"help.qbs:53" "4" +"help.qbs:64" "4" "bookmarkdialog.ui" "5" "bookmarkmanager.cpp" "5" "bookmarkmanager.h" "5" @@ -7313,7 +8039,7 @@ "topicchooser.h" "5" "topicchooser.ui" "5" "Sources" "3" -"help.qbs:25" "4" +"help.qbs:28" "4" "centralwidget.cpp" "4" "centralwidget.h" "4" "docsettingspage.cpp" "4" @@ -7326,6 +8052,14 @@ "generalsettingspage.h" "4" "generalsettingspage.ui" "4" "help.qrc" "4" +"/help" "5" +"images" "6" +"mode_help.png" "7" +"mode_help@2x.png" "7" +"mode_help_mask.png" "7" +"mode_help_mask@2x.png" "7" +"settingscategory_help.png" "7" +"settingscategory_help@2x.png" "7" "helpconstants.h" "4" "helpfindsupport.cpp" "4" "helpfindsupport.h" "4" @@ -7361,21 +8095,25 @@ "xbelsupport.cpp" "4" "xbelsupport.h" "4" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" +"WebEngine Sources" "3" +"help.qbs:56" "4" +"webenginehelpviewer.cpp" "4" +"webenginehelpviewer.h" "4" "ImageViewer" "2" "imageviewer.qbs:3" "3" "PluginMetaData" "3" -"QtcPlugin.qbs:51" "4" +"QtcPlugin.qbs:49" "4" "ImageViewer.json.in" "5" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" "exportdialog.cpp" "3" "exportdialog.h" "3" @@ -7391,21 +8129,29 @@ "imageviewerplugin.cpp" "3" "imageviewerplugin.h" "3" "imageviewertoolbar.ui" "3" +"multiexportdialog.cpp" "3" +"multiexportdialog.h" "3" "Ios" "2" "ios.qbs:3" "3" "PluginMetaData" "3" -"QtcPlugin.qbs:51" "4" +"QtcPlugin.qbs:49" "4" "Ios.json.in" "5" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" "createsimulatordialog.cpp" "3" "createsimulatordialog.h" "3" "createsimulatordialog.ui" "3" "ios.qrc" "3" +"/ios" "4" +"images" "5" +"iosdevice.png" "6" +"iosdevice@2x.png" "6" +"iosdevicesmall.png" "6" +"iosdevicesmall@2x.png" "6" "iosbuildconfiguration.cpp" "3" "iosbuildconfiguration.h" "3" "iosbuildsettingswidget.cpp" "3" @@ -7432,8 +8178,6 @@ "iosdevicefactory.h" "3" "iosdsymbuildstep.cpp" "3" "iosdsymbuildstep.h" "3" -"iosmanager.cpp" "3" -"iosmanager.h" "3" "iosplugin.cpp" "3" "iosplugin.h" "3" "iospresetbuildstep.ui" "3" @@ -7445,8 +8189,6 @@ "iosqtversionfactory.h" "3" "iosrunconfiguration.cpp" "3" "iosrunconfiguration.h" "3" -"iosrunfactories.cpp" "3" -"iosrunfactories.h" "3" "iosrunner.cpp" "3" "iosrunner.h" "3" "iossettingspage.cpp" "3" @@ -7504,13 +8246,13 @@ "Macros" "2" "macros.qbs:3" "3" "PluginMetaData" "3" -"QtcPlugin.qbs:51" "4" +"QtcPlugin.qbs:49" "4" "Macros.json.in" "5" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" "actionmacrohandler.cpp" "3" "actionmacrohandler.h" "3" @@ -7532,6 +8274,9 @@ "macrooptionswidget.h" "3" "macrooptionswidget.ui" "3" "macros.qrc" "3" +"/macros" "4" +"images" "5" +"macro.png" "6" "macrosconstants.h" "3" "macrosplugin.cpp" "3" "macrosplugin.h" "3" @@ -7545,13 +8290,13 @@ "Mercurial" "2" "mercurial.qbs:3" "3" "PluginMetaData" "3" -"QtcPlugin.qbs:51" "4" +"QtcPlugin.qbs:49" "4" "Mercurial.json.in" "5" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" "annotationhighlighter.cpp" "3" "annotationhighlighter.h" "3" @@ -7586,16 +8331,18 @@ "ModelEditor" "2" "modeleditor.qbs:5" "3" "PluginMetaData" "3" -"QtcPlugin.qbs:51" "4" +"QtcPlugin.qbs:49" "4" "ModelEditor.json.in" "5" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" "resources" "3" "modeleditor.qrc" "4" +"/modeleditor" "5" +"up.png" "6" "actionhandler.cpp" "3" "actionhandler.h" "3" "classviewcontroller.cpp" "3" @@ -7654,19 +8401,21 @@ "General" "3" "nim.qbs:15" "4" "nim.qrc" "4" +"/nim" "5" +"images" "6" +"settingscategory_nim.png" "7" +"settingscategory_nim@2x.png" "7" "nimconstants.h" "4" "nimplugin.cpp" "4" "nimplugin.h" "4" "PluginMetaData" "3" -"QtcPlugin.qbs:51" "4" +"QtcPlugin.qbs:49" "4" "Nim.json.in" "5" "Project" "3" "nim.qbs:34" "4" "project" "4" "nimbuildconfiguration.cpp" "5" "nimbuildconfiguration.h" "5" -"nimbuildconfigurationfactory.cpp" "5" -"nimbuildconfigurationfactory.h" "5" "nimbuildconfigurationwidget.cpp" "5" "nimbuildconfigurationwidget.h" "5" "nimcompilerbuildstep.cpp" "5" @@ -7674,31 +8423,23 @@ "nimcompilerbuildstepconfigwidget.cpp" "5" "nimcompilerbuildstepconfigwidget.h" "5" "nimcompilerbuildstepconfigwidget.ui" "5" -"nimcompilerbuildstepfactory.cpp" "5" -"nimcompilerbuildstepfactory.h" "5" "nimcompilercleanstep.cpp" "5" "nimcompilercleanstep.h" "5" "nimcompilercleanstepconfigwidget.cpp" "5" "nimcompilercleanstepconfigwidget.h" "5" "nimcompilercleanstepconfigwidget.ui" "5" -"nimcompilercleanstepfactory.cpp" "5" -"nimcompilercleanstepfactory.h" "5" "nimproject.cpp" "5" "nimproject.h" "5" "nimprojectnode.cpp" "5" "nimprojectnode.h" "5" "nimrunconfiguration.cpp" "5" "nimrunconfiguration.h" "5" -"nimrunconfigurationfactory.cpp" "5" -"nimrunconfigurationfactory.h" "5" -"nimrunconfigurationwidget.cpp" "5" -"nimrunconfigurationwidget.h" "5" "nimtoolchain.cpp" "5" "nimtoolchain.h" "5" "nimtoolchainfactory.cpp" "5" "nimtoolchainfactory.h" "5" "Settings" "3" -"nim.qbs:57" "4" +"nim.qbs:52" "4" "settings" "4" "nimcodestylepreferencesfactory.cpp" "5" "nimcodestylepreferencesfactory.h" "5" @@ -7710,13 +8451,13 @@ "nimsettings.cpp" "5" "nimsettings.h" "5" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" "Tools" "3" -"nim.qbs:68" "4" +"nim.qbs:63" "4" "tools" "4" "nimlexer.cpp" "5" "nimlexer.h" "5" @@ -7724,13 +8465,13 @@ "Perforce" "2" "perforce.qbs:3" "3" "PluginMetaData" "3" -"QtcPlugin.qbs:51" "4" +"QtcPlugin.qbs:49" "4" "Perforce.json.in" "5" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" "annotationhighlighter.cpp" "3" "annotationhighlighter.h" "3" @@ -7763,7 +8504,7 @@ "ProjectExplorer" "3" "projectexplorer.qbs:8" "4" "CustomWizard" "4" -"projectexplorer.qbs:182" "5" +"projectexplorer.qbs:180" "5" "customwizard" "5" "customwizard.cpp" "6" "customwizard.h" "6" @@ -7774,7 +8515,7 @@ "customwizardscriptgenerator.cpp" "6" "customwizardscriptgenerator.h" "6" "Device Support" "4" -"projectexplorer.qbs:193" "5" +"projectexplorer.qbs:191" "5" "devicesupport" "5" "desktopdevice.cpp" "6" "desktopdevice.h" "6" @@ -7824,7 +8565,7 @@ "sshdeviceprocesslist.cpp" "6" "sshdeviceprocesslist.h" "6" "General" "4" -"projectexplorer.qbs:19" "5" +"projectexplorer.qbs:18" "5" "abi.cpp" "5" "abi.h" "5" "abiwidget.cpp" "5" @@ -7845,8 +8586,6 @@ "baseprojectwizarddialog.h" "5" "buildconfiguration.cpp" "5" "buildconfiguration.h" "5" -"buildconfigurationmodel.cpp" "5" -"buildconfigurationmodel.h" "5" "buildenvironmentwidget.cpp" "5" "buildenvironmentwidget.h" "5" "buildinfo.cpp" "5" @@ -7879,8 +8618,6 @@ "currentprojectfilter.h" "5" "currentprojectfind.cpp" "5" "currentprojectfind.h" "5" -"customexecutableconfigurationwidget.cpp" "5" -"customexecutableconfigurationwidget.h" "5" "customexecutablerunconfiguration.cpp" "5" "customexecutablerunconfiguration.h" "5" "customparser.cpp" "5" @@ -7896,8 +8633,6 @@ "deployablefile.h" "5" "deployconfiguration.cpp" "5" "deployconfiguration.h" "5" -"deployconfigurationmodel.cpp" "5" -"deployconfigurationmodel.h" "5" "deploymentdata.h" "5" "deploymentdatamodel.cpp" "5" "deploymentdatamodel.h" "5" @@ -7979,9 +8714,96 @@ "project.h" "5" "projectconfiguration.cpp" "5" "projectconfiguration.h" "5" +"projectconfigurationmodel.cpp" "5" +"projectconfigurationmodel.h" "5" "projectexplorer.cpp" "5" "projectexplorer.h" "5" "projectexplorer.qrc" "5" +"/projectexplorer" "6" +"images" "7" +"analyzer_overlay_small.png" "8" +"analyzer_overlay_small@2x.png" "8" +"build.png" "8" +"build@2x.png" "8" +"build_hammerhandle_mask.png" "8" +"build_hammerhandle_mask@2x.png" "8" +"build_hammerhead_mask.png" "8" +"build_hammerhead_mask@2x.png" "8" +"buildhammerhandle.png" "8" +"buildhammerhandle@2x.png" "8" +"buildhammerhead.png" "8" +"buildhammerhead@2x.png" "8" +"BuildSettings.png" "8" +"buildstepdisable.png" "8" +"buildstepdisable@2x.png" "8" +"buildstepmovedown.png" "8" +"buildstepmovedown@2x.png" "8" +"buildstepmoveup.png" "8" +"buildstepmoveup@2x.png" "8" +"buildstepremove.png" "8" +"buildstepremove@2x.png" "8" +"cancelbuild_overlay.png" "8" +"cancelbuild_overlay@2x.png" "8" +"closetab.png" "8" +"CodeStyleSettings.png" "8" +"continue_1_small.png" "8" +"continue_1_small@2x.png" "8" +"continue_2_small.png" "8" +"continue_2_small@2x.png" "8" +"debugger_beetle_mask.png" "8" +"debugger_beetle_mask@2x.png" "8" +"debugger_overlay_small.png" "8" +"debugger_overlay_small@2x.png" "8" +"debugger_start.png" "8" +"debugger_start@2x.png" "8" +"desktopdevice.png" "8" +"desktopdevice@2x.png" "8" +"devicestatusindicator.png" "8" +"devicestatusindicator@2x.png" "8" +"EditorSettings.png" "8" +"fileoverlay_cpp.png" "8" +"fileoverlay_cpp@2x.png" "8" +"fileoverlay_h.png" "8" +"fileoverlay_h@2x.png" "8" +"fileoverlay_qml.png" "8" +"fileoverlay_qml@2x.png" "8" +"fileoverlay_qrc.png" "8" +"fileoverlay_qrc@2x.png" "8" +"fileoverlay_qt.png" "8" +"fileoverlay_qt@2x.png" "8" +"fileoverlay_scxml.png" "8" +"fileoverlay_scxml@2x.png" "8" +"fileoverlay_ui.png" "8" +"fileoverlay_ui@2x.png" "8" +"fileoverlay_unknown.png" "8" +"fileoverlay_unknown@2x.png" "8" +"MaemoDevice.png" "8" +"mode_project.png" "8" +"mode_project@2x.png" "8" +"mode_project_mask.png" "8" +"mode_project_mask@2x.png" "8" +"ProjectDependencies.png" "8" +"projectexplorer.png" "8" +"rebuildhammerhandles.png" "8" +"rebuildhammerhandles@2x.png" "8" +"rebuildhammerheads.png" "8" +"rebuildhammerheads@2x.png" "8" +"run.png" "8" +"run@2x.png" "8" +"run_mask.png" "8" +"run_mask@2x.png" "8" +"RunSettings.png" "8" +"session.png" "8" +"settingscategory_buildrun.png" "8" +"settingscategory_buildrun@2x.png" "8" +"settingscategory_devices.png" "8" +"settingscategory_devices@2x.png" "8" +"settingscategory_kits.png" "8" +"settingscategory_kits@2x.png" "8" +"Simulator.png" "8" +"targetpanel_bottom.png" "8" +"unconfigured.png" "8" +"window.png" "8" "projectexplorer_export.h" "5" "projectexplorer_global.h" "5" "projectexplorerconstants.h" "5" @@ -7995,6 +8817,8 @@ "projectfilewizardextension.h" "5" "projectimporter.cpp" "5" "projectimporter.h" "5" +"projectmacro.cpp" "5" +"projectmacro.h" "5" "projectmacroexpander.cpp" "5" "projectmacroexpander.h" "5" "projectmanager.h" "5" @@ -8019,10 +8843,6 @@ "runconfiguration.h" "5" "runconfigurationaspects.cpp" "5" "runconfigurationaspects.h" "5" -"runconfigurationmodel.cpp" "5" -"runconfigurationmodel.h" "5" -"runnables.cpp" "5" -"runnables.h" "5" "runsettingspropertiespage.cpp" "5" "runsettingspropertiespage.h" "5" "selectablefilesmodel.cpp" "5" @@ -8036,12 +8856,12 @@ "sessionmodel.h" "5" "sessionview.cpp" "5" "sessionview.h" "5" -"settingsaccessor.cpp" "5" -"settingsaccessor.h" "5" "showineditortaskhandler.cpp" "5" "showineditortaskhandler.h" "5" "showoutputtaskhandler.cpp" "5" "showoutputtaskhandler.h" "5" +"subscription.cpp" "5" +"subscription.h" "5" "target.cpp" "5" "target.h" "5" "targetsettingspanel.cpp" "5" @@ -8066,6 +8886,10 @@ "toolchainmanager.h" "5" "toolchainoptionspage.cpp" "5" "toolchainoptionspage.h" "5" +"toolchainsettingsaccessor.cpp" "5" +"toolchainsettingsaccessor.h" "5" +"userfileaccessor.cpp" "5" +"userfileaccessor.h" "5" "vcsannotatetaskhandler.cpp" "5" "vcsannotatetaskhandler.h" "5" "waitforstopdialog.cpp" "5" @@ -8073,7 +8897,7 @@ "xcodebuildparser.cpp" "5" "xcodebuildparser.h" "5" "Images" "4" -"projectexplorer.qbs:222" "5" +"projectexplorer.qbs:220" "5" "images" "5" "analyzer_overlay_small.png" "6" "analyzer_overlay_small@2x.png" "6" @@ -8084,7 +8908,10 @@ "build_hammerhandle_mask@2x.png" "6" "build_hammerhead_mask.png" "6" "build_hammerhead_mask@2x.png" "6" -"build_small.png" "6" +"buildhammerhandle.png" "6" +"buildhammerhandle@2x.png" "6" +"buildhammerhead.png" "6" +"buildhammerhead@2x.png" "6" "BuildSettings.png" "6" "buildstepdisable.png" "6" "buildstepdisable@2x.png" "6" @@ -8094,7 +8921,8 @@ "buildstepmoveup@2x.png" "6" "buildstepremove.png" "6" "buildstepremove@2x.png" "6" -"category_buildrun.png" "6" +"cancelbuild_overlay.png" "6" +"cancelbuild_overlay@2x.png" "6" "closetab.png" "6" "CodeStyleSettings.png" "6" "continue_1_small.png" "6" @@ -8147,12 +8975,18 @@ "run_mask@2x.png" "6" "RunSettings.png" "6" "session.png" "6" +"settingscategory_buildrun.png" "6" +"settingscategory_buildrun@2x.png" "6" +"settingscategory_devices.png" "6" +"settingscategory_devices@2x.png" "6" +"settingscategory_kits.png" "6" +"settingscategory_kits@2x.png" "6" "Simulator.png" "6" "targetpanel_bottom.png" "6" "unconfigured.png" "6" "window.png" "6" "JsonWizard" "4" -"projectexplorer.qbs:163" "5" +"projectexplorer.qbs:161" "5" "jsonwizard" "5" "jsonfieldpage.cpp" "6" "jsonfieldpage.h" "6" @@ -8180,24 +9014,24 @@ "jsonwizardscannergenerator.cpp" "6" "jsonwizardscannergenerator.h" "6" "PluginMetaData" "4" -"QtcPlugin.qbs:51" "5" +"QtcPlugin.qbs:49" "5" "ProjectExplorer.json.in" "6" "Project Welcome Page" "4" -"projectexplorer.qbs:155" "5" +"projectexplorer.qbs:153" "5" "projectwelcomepage.cpp" "5" "projectwelcomepage.h" "5" "standard pch file (gui)" "4" -"QtcProduct.qbs:58" "5" +"QtcProduct.qbs:65" "5" "qtcreator_gui_pch.h" "6" "standard pch file (non-gui)" "4" -"QtcProduct.qbs:50" "5" +"QtcProduct.qbs:57" "5" "qtcreator_pch.h" "6" "Tests" "4" -"projectexplorer.qbs:241" "5" +"projectexplorer.qbs:239" "5" "outputparser_test.cpp" "5" "outputparser_test.h" "5" "WindowsToolChains" "4" -"projectexplorer.qbs:228" "5" +"projectexplorer.qbs:226" "5" "abstractmsvctoolchain.cpp" "5" "abstractmsvctoolchain.h" "5" "msvctoolchain.cpp" "5" @@ -8261,7 +9095,6 @@ "appoutputpane.h" "6" "baseprojectwizarddialog.h" "6" "buildconfiguration.h" "6" -"buildconfigurationmodel.h" "6" "buildenvironmentwidget.h" "6" "buildinfo.h" "6" "buildmanager.h" "6" @@ -8278,7 +9111,6 @@ "copytaskhandler.h" "6" "currentprojectfilter.h" "6" "currentprojectfind.h" "6" -"customexecutableconfigurationwidget.h" "6" "customexecutablerunconfiguration.h" "6" "customparser.h" "6" "customparserconfigdialog.h" "6" @@ -8286,7 +9118,6 @@ "dependenciespanel.h" "6" "deployablefile.h" "6" "deployconfiguration.h" "6" -"deployconfigurationmodel.h" "6" "deploymentdata.h" "6" "deploymentdatamodel.h" "6" "deploymentdataview.h" "6" @@ -8332,6 +9163,7 @@ "processstep.h" "6" "project.h" "6" "projectconfiguration.h" "6" +"projectconfigurationmodel.h" "6" "projectexplorer.h" "6" "projectexplorer_export.h" "6" "projectexplorer_global.h" "6" @@ -8341,6 +9173,7 @@ "projectexplorersettingspage.h" "6" "projectfilewizardextension.h" "6" "projectimporter.h" "6" +"projectmacro.h" "6" "projectmacroexpander.h" "6" "projectmanager.h" "6" "projectmodels.h" "6" @@ -8354,17 +9187,15 @@ "removetaskhandler.h" "6" "runconfiguration.h" "6" "runconfigurationaspects.h" "6" -"runconfigurationmodel.h" "6" -"runnables.h" "6" "runsettingspropertiespage.h" "6" "selectablefilesmodel.h" "6" "session.h" "6" "sessiondialog.h" "6" "sessionmodel.h" "6" "sessionview.h" "6" -"settingsaccessor.h" "6" "showineditortaskhandler.h" "6" "showoutputtaskhandler.h" "6" +"subscription.h" "6" "target.h" "6" "targetsettingspanel.h" "6" "targetsetuppage.h" "6" @@ -8377,6 +9208,8 @@ "toolchainconfigwidget.h" "6" "toolchainmanager.h" "6" "toolchainoptionspage.h" "6" +"toolchainsettingsaccessor.h" "6" +"userfileaccessor.h" "6" "vcsannotatetaskhandler.h" "6" "waitforstopdialog.h" "6" "windebuginterface.h" "6" @@ -8384,10 +9217,10 @@ "ptracepreload" "2" "ptracepreload.qbs:3" "3" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" "ptracepreload.c" "3" "PythonEditor" "2" @@ -8407,24 +9240,28 @@ "pythonscanner.cpp" "4" "pythonscanner.h" "4" "PluginMetaData" "3" -"QtcPlugin.qbs:51" "4" +"QtcPlugin.qbs:49" "4" "PythonEditor.json.in" "5" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" "QbsProjectManager" "2" -"qbsprojectmanager.qbs:4" "3" +"qbsprojectmanager.qbs:5" "3" "PluginMetaData" "3" -"QtcPlugin.qbs:51" "4" +"QtcPlugin.qbs:49" "4" "QbsProjectManager.json.in" "5" +"qbs qml type info" "3" +"qbsprojectmanager.qbs:124" "4" +"qbs-bundle.json" "5" +"qbs.qmltypes" "5" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" "customqbspropertiesdialog.cpp" "3" "customqbspropertiesdialog.h" "3" @@ -8471,6 +9308,12 @@ "qbsprojectmanager.cpp" "3" "qbsprojectmanager.h" "3" "qbsprojectmanager.qrc" "3" +"/qbsprojectmanager" "4" +"images" "5" +"groups.png" "6" +"groups@2x.png" "6" +"productgear.png" "6" +"productgear@2x.png" "6" "qbsprojectmanager_global.h" "3" "qbsprojectmanagerconstants.h" "3" "qbsprojectmanagerplugin.cpp" "3" @@ -8484,20 +9327,16 @@ "QmakeAndroidSupport" "2" "qmakeandroidsupport.qbs:3" "3" "PluginMetaData" "3" -"QtcPlugin.qbs:51" "4" +"QtcPlugin.qbs:49" "4" "QmakeAndroidSupport.json.in" "5" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" "androidextralibrarylistmodel.cpp" "3" "androidextralibrarylistmodel.h" "3" -"androidpackageinstallationfactory.cpp" "3" -"androidpackageinstallationfactory.h" "3" -"androidpackageinstallationstep.cpp" "3" -"androidpackageinstallationstep.h" "3" "androidqmakebuildconfigurationfactory.cpp" "3" "androidqmakebuildconfigurationfactory.h" "3" "createandroidmanifestwizard.cpp" "3" @@ -8507,10 +9346,6 @@ "qmakeandroidbuildapkwidget.cpp" "3" "qmakeandroidbuildapkwidget.h" "3" "qmakeandroidbuildapkwidget.ui" "3" -"qmakeandroidrunconfiguration.cpp" "3" -"qmakeandroidrunconfiguration.h" "3" -"qmakeandroidrunfactories.cpp" "3" -"qmakeandroidrunfactories.h" "3" "qmakeandroidsupport.cpp" "3" "qmakeandroidsupport.h" "3" "qmakeandroidsupportplugin.cpp" "3" @@ -8542,7 +9377,7 @@ "plugingenerator.h" "6" "pluginoptions.h" "6" "General" "4" -"qmakeprojectmanager.qbs:24" "5" +"qmakeprojectmanager.qbs:25" "5" "addlibrarywizard.cpp" "5" "addlibrarywizard.h" "5" "desktopqmakerunconfiguration.cpp" "5" @@ -8590,28 +9425,33 @@ "qmakeprojectmanager.cpp" "5" "qmakeprojectmanager.h" "5" "qmakeprojectmanager.qrc" "5" +"/qmakeprojectmanager" "6" +"images" "7" +"dark_headers.png" "8" +"dark_sources.png" "8" +"dark_unknown.png" "8" +"qmakeprojectmanager.png" "8" +"qmakeprojectmanager@2x.png" "8" "qmakeprojectmanager_global.h" "5" "qmakeprojectmanagerconstants.h" "5" "qmakeprojectmanagerplugin.cpp" "5" "qmakeprojectmanagerplugin.h" "5" -"qmakerunconfigurationfactory.cpp" "5" -"qmakerunconfigurationfactory.h" "5" "qmakestep.cpp" "5" "qmakestep.h" "5" "qmakestep.ui" "5" "qtmodulesinfo.cpp" "5" "qtmodulesinfo.h" "5" "PluginMetaData" "4" -"QtcPlugin.qbs:51" "5" +"QtcPlugin.qbs:49" "5" "QmakeProjectManager.json.in" "6" "standard pch file (gui)" "4" -"QtcProduct.qbs:58" "5" +"QtcProduct.qbs:65" "5" "qtcreator_gui_pch.h" "6" "standard pch file (non-gui)" "4" -"QtcProduct.qbs:50" "5" +"QtcProduct.qbs:57" "5" "qtcreator_pch.h" "6" "Wizard Images" "4" -"qmakeprojectmanager.qbs:100" "5" +"qmakeprojectmanager.qbs:96" "5" "console.png" "6" "gui.png" "6" "lib.png" "6" @@ -8643,14 +9483,16 @@ "subdirsprojectwizard.h" "6" "subdirsprojectwizarddialog.cpp" "6" "subdirsprojectwizarddialog.h" "6" -"testwizard.cpp" "6" -"testwizard.h" "6" -"testwizarddialog.cpp" "6" -"testwizarddialog.h" "6" -"testwizardpage.cpp" "6" -"testwizardpage.h" "6" -"testwizardpage.ui" "6" "wizards.qrc" "6" +"/wizards" "7" +"images" "8" +"console.png" "9" +"console@2x.png" "9" +"gui.png" "9" +"gui@2x.png" "9" +"lib.png" "9" +"lib@2x.png" "9" +"qtquickapp.png" "9" "QmakeProjectManager dev headers" "3" "qmakeprojectmanager.qbs:6" "4" "Group 1" "4" @@ -8678,9 +9520,6 @@ "simpleprojectwizard.h" "7" "subdirsprojectwizard.h" "7" "subdirsprojectwizarddialog.h" "7" -"testwizard.h" "7" -"testwizarddialog.h" "7" -"testwizardpage.h" "7" "addlibrarywizard.h" "6" "applicationlauncher.h" "6" "desktopqmakerunconfiguration.h" "6" @@ -8707,7 +9546,6 @@ "qmakeprojectmanager_global.h" "6" "qmakeprojectmanagerconstants.h" "6" "qmakeprojectmanagerplugin.h" "6" -"qmakerunconfigurationfactory.h" "6" "qmakestep.h" "6" "qtmodulesinfo.h" "6" "QML designer projects" "2" @@ -8769,10 +9607,10 @@ "componentsplugin.qbs:46" "5" "componentsplugin.json" "5" "standard pch file (gui)" "4" -"QtcProduct.qbs:58" "5" +"QtcProduct.qbs:65" "5" "qtcreator_gui_pch.h" "6" "standard pch file (non-gui)" "4" -"QtcProduct.qbs:50" "5" +"QtcProduct.qbs:57" "5" "qtcreator_pch.h" "6" "iwidgetplugin.h" "5" "addtabdesigneraction.cpp" "4" @@ -8784,6 +9622,56 @@ "componentsplugin.cpp" "4" "componentsplugin.h" "4" "componentsplugin.qrc" "4" +"/componentsplugin" "5" +"images" "6" +"button.png" "7" +"button16.png" "7" +"checkbox.png" "7" +"checkbox16.png" "7" +"column-layouts-icon-16px.png" "7" +"column-layouts-icon.png" "7" +"combobox.png" "7" +"combobox16.png" "7" +"grid-layouts-icon-16px.png" "7" +"grid-layouts-icon.png" "7" +"item-icon.png" "7" +"item-icon16.png" "7" +"label.png" "7" +"label16.png" "7" +"progressbar.png" "7" +"progressbar16.png" "7" +"radiobutton.png" "7" +"radiobutton16.png" "7" +"row-layouts-icon-16px.png" "7" +"row-layouts-icon.png" "7" +"slider.png" "7" +"slider16.png" "7" +"splitview-layouts-icon-16px.png" "7" +"splitview-layouts-icon.png" "7" +"stack-layouts-icon-16px.png" "7" +"stack-layouts-icon.png" "7" +"textarea.png" "7" +"textarea16.png" "7" +"textfield.png" "7" +"textfield16.png" "7" +"window.png" "7" +"window16.png" "7" +"components.metainfo" "6" +"/propertyEditorQmlSources/QtQuick" "5" +"Controls" "6" +"ApplicationWindowSpecifics.qml" "7" +"ButtonSpecifics.qml" "7" +"CheckBoxSpecifics.qml" "7" +"ComboBoxSpecifics.qml" "7" +"CurrentIndexComboBox.qml" "7" +"OrientationCombobox.qml" "7" +"RadioButtonSpecifics.qml" "7" +"SliderSpecifics.qml" "7" +"SplitViewSpecifics.qml" "7" +"TabPositionComboBox.qml" "7" +"TabViewSpecifics.qml" "7" +"TextAreaSpecifics.qml" "7" +"TextFieldSpecifics.qml" "7" "entertabdesigneraction.cpp" "4" "entertabdesigneraction.h" "4" "tabviewindexmodel.cpp" "4" @@ -8793,7 +9681,7 @@ "QmlDesigner" "4" "qmldesignerplugin.qbs:9" "5" "extension" "5" -"qmldesignerplugin.qbs:584" "6" +"qmldesignerplugin.qbs:590" "6" "qmldesignerextension" "6" "colortool" "7" "colortool.cpp" "8" @@ -8807,6 +9695,8 @@ "bindingmodel.cpp" "8" "bindingmodel.h" "8" "connectioneditor.qrc" "8" +"/connectionview" "9" +"stylesheet.css" "10" "connectionmodel.cpp" "8" "connectionmodel.h" "8" "connectionview.cpp" "8" @@ -8845,7 +9735,7 @@ "qmldesignerextension_global.h" "7" "qmldesignerextensionconstants.h" "7" "Group 4" "5" -"qmldesignerplugin.qbs:73" "6" +"qmldesignerplugin.qbs:74" "6" "addarraymembervisitor.cpp" "7" "addarraymembervisitor.h" "7" "addobjectvisitor.cpp" "7" @@ -8877,7 +9767,7 @@ "removeuiobjectmembervisitor.cpp" "7" "removeuiobjectmembervisitor.h" "7" "Group 5" "5" -"qmldesignerplugin.qbs:109" "6" +"qmldesignerplugin.qbs:110" "6" "commands" "7" "changeauxiliarycommand.cpp" "8" "changeauxiliarycommand.h" "8" @@ -8962,7 +9852,7 @@ "enumeration.cpp" "8" "enumeration.h" "8" "Group 8" "5" -"qmldesignerplugin.qbs:210" "6" +"qmldesignerplugin.qbs:211" "6" "designercore" "6" "exceptions" "7" "exception.cpp" "8" @@ -9025,6 +9915,8 @@ "qmlmodelnodefacade.h" "8" "qmlobjectnode.h" "8" "qmlstate.h" "8" +"qmltimeline.h" "8" +"qmltimelinekeyframegroup.h" "8" "removebasestateexception.h" "8" "rewriterview.h" "8" "rewritingexception.h" "8" @@ -9102,6 +9994,8 @@ "qmlstate.cpp" "8" "qmltextgenerator.cpp" "8" "qmltextgenerator.h" "8" +"qmltimeline.cpp" "8" +"qmltimelinekeyframegroup.cpp" "8" "rewriteaction.cpp" "8" "rewriteaction.h" "8" "rewriteactioncompressor.cpp" "8" @@ -9121,7 +10015,7 @@ "rewritertransaction.cpp" "7" "rewritertransaction.h" "7" "Group 9" "5" -"qmldesignerplugin.qbs:366" "6" +"qmldesignerplugin.qbs:371" "6" "components" "6" "componentcore" "7" "abstractaction.cpp" "8" @@ -9129,12 +10023,26 @@ "abstractactiongroup.cpp" "8" "abstractactiongroup.h" "8" "actioninterface.h" "8" +"addimagesdialog.cpp" "8" +"addimagesdialog.h" "8" "addsignalhandlerdialog.cpp" "8" "addsignalhandlerdialog.h" "8" "addsignalhandlerdialog.ui" "8" "changestyleaction.cpp" "8" "changestyleaction.h" "8" "componentcore.qrc" "8" +"/qmldesigner/icon/designeractions" "9" +"images" "10" +"column.png" "11" +"column@2x.png" "11" +"grid.png" "11" +"grid@2x.png" "11" +"lower.png" "11" +"lower@2x.png" "11" +"raise.png" "11" +"raise@2x.png" "11" +"row.png" "11" +"row@2x.png" "11" "componentcore_constants.h" "8" "crumblebar.cpp" "8" "crumblebar.h" "8" @@ -9158,6 +10066,8 @@ "selectioncontext.h" "8" "theme.cpp" "8" "theme.h" "8" +"zoomaction.cpp" "8" +"zoomaction.h" "8" "debugview" "7" "debugview.cpp" "8" "debugview.h" "8" @@ -9186,6 +10096,13 @@ "dragtool.cpp" "8" "dragtool.h" "8" "formeditor.qrc" "8" +"/icon/layout" "9" +"no_snapping.png" "10" +"no_snapping@2x.png" "10" +"snapping.png" "10" +"snapping@2x.png" "10" +"snapping_and_anchoring.png" "10" +"snapping_and_anchoring@2x.png" "10" "formeditorgraphicsview.cpp" "8" "formeditorgraphicsview.h" "8" "formeditoritem.cpp" "8" @@ -9242,13 +10159,13 @@ "snappinglinecreator.h" "8" "toolbox.cpp" "8" "toolbox.h" "8" -"zoomaction.cpp" "8" -"zoomaction.h" "8" "importmanager" "7" "importlabel.cpp" "8" "importlabel.h" "8" "importmanager.css" "8" "importmanager.qrc" "8" +"/importmanager" "9" +"importmanager.css" "10" "importmanagercombobox.cpp" "8" "importmanagercombobox.h" "8" "importmanagerview.cpp" "8" @@ -9272,6 +10189,10 @@ "customfilesystemmodel.cpp" "8" "customfilesystemmodel.h" "8" "itemlibrary.qrc" "8" +"/ItemLibrary" "9" +"images" "10" +"item-default-icon.png" "11" +"item-invalid-icon.png" "11" "itemlibraryimageprovider.cpp" "8" "itemlibraryimageprovider.h" "8" "itemlibraryitem.cpp" "8" @@ -9294,6 +10215,19 @@ "nameitemdelegate.cpp" "8" "nameitemdelegate.h" "8" "navigator.qrc" "8" +"/navigator/icon" "9" +"arrowdown.png" "10" +"arrowdown@2x.png" "10" +"arrowleft.png" "10" +"arrowleft@2x.png" "10" +"arrowright.png" "10" +"arrowright@2x.png" "10" +"arrowup.png" "10" +"arrowup@2x.png" "10" +"export_checked.png" "10" +"export_checked@2x.png" "10" +"export_unchecked.png" "10" +"export_unchecked@2x.png" "10" "navigatortreemodel.cpp" "8" "navigatortreemodel.h" "8" "navigatortreeview.cpp" "8" @@ -9309,7 +10243,6 @@ "fileresourcesmodel.h" "8" "gradientmodel.cpp" "8" "gradientmodel.h" "8" -"propertyeditor.qrc" "8" "propertyeditorcontextobject.cpp" "8" "propertyeditorcontextobject.h" "8" "propertyeditorqmlbackend.cpp" "8" @@ -9330,6 +10263,16 @@ "quick2propertyeditorview.h" "8" "resources" "7" "resources.qrc" "8" +"/qmldesigner" "9" +"images" "10" +"spliteditorhorizontally.png" "11" +"spliteditorhorizontally@2x.png" "11" +"spliteditorvertically.png" "11" +"spliteditorvertically@2x.png" "11" +"centerwidget.css" "10" +"formeditorstylesheet.css" "10" +"scrollbar.css" "10" +"stylesheet.css" "10" "stateseditor" "7" "stateseditorimageprovider.cpp" "8" "stateseditorimageprovider.h" "8" @@ -9347,19 +10290,19 @@ "texteditorwidget.cpp" "8" "texteditorwidget.h" "8" "PluginMetaData" "5" -"QtcPlugin.qbs:51" "6" +"QtcPlugin.qbs:49" "6" "QmlDesigner.json.in" "7" "SharedMemory (Generic)" "5" -"qmldesignerplugin.qbs:202" "6" +"qmldesignerplugin.qbs:203" "6" "sharedmemory_qt.cpp" "7" "SharedMemory (Unix)" "5" -"qmldesignerplugin.qbs:194" "6" +"qmldesignerplugin.qbs:195" "6" "sharedmemory_unix.cpp" "7" "standard pch file (gui)" "5" -"QtcProduct.qbs:58" "6" +"QtcProduct.qbs:65" "6" "qtcreator_gui_pch.h" "7" "standard pch file (non-gui)" "5" -"QtcProduct.qbs:50" "6" +"QtcProduct.qbs:57" "6" "qtcreator_pch.h" "7" "designersettings.cpp" "5" "designersettings.h" "5" @@ -9394,6 +10337,7 @@ "abstractaction.h" "9" "abstractactiongroup.h" "9" "actioninterface.h" "9" +"addimagesdialog.h" "9" "addsignalhandlerdialog.h" "9" "changestyleaction.h" "9" "componentcore_constants.h" "9" @@ -9408,6 +10352,7 @@ "qmldesignericonprovider.h" "9" "selectioncontext.h" "9" "theme.h" "9" +"zoomaction.h" "9" "debugview" "8" "debugview.h" "9" "debugviewwidget.h" "9" @@ -9451,7 +10396,6 @@ "snapper.h" "9" "snappinglinecreator.h" "9" "toolbox.h" "9" -"zoomaction.h" "9" "importmanager" "8" "importlabel.h" "9" "importmanagercombobox.h" "9" @@ -9582,6 +10526,8 @@ "qmlmodelnodefacade.h" "9" "qmlobjectnode.h" "9" "qmlstate.h" "9" +"qmltimeline.h" "9" +"qmltimelinekeyframegroup.h" "9" "removebasestateexception.h" "9" "rewriterview.h" "9" "rewritingexception.h" "9" @@ -9706,10 +10652,10 @@ "sources" "4" "qtquickplugin.qbs:16" "5" "standard pch file (gui)" "4" -"QtcProduct.qbs:58" "5" +"QtcProduct.qbs:65" "5" "qtcreator_gui_pch.h" "6" "standard pch file (non-gui)" "4" -"QtcProduct.qbs:50" "5" +"QtcProduct.qbs:57" "5" "qtcreator_pch.h" "6" "iwidgetplugin.h" "5" "qtquickplugin.cpp" "4" @@ -9774,13 +10720,13 @@ "QmlJSEditor" "2" "qmljseditor.qbs:3" "3" "PluginMetaData" "3" -"QtcPlugin.qbs:51" "4" +"QtcPlugin.qbs:49" "4" "QmlJSEditor.json.in" "5" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" "qmlexpressionundercursor.cpp" "3" "qmlexpressionundercursor.h" "3" @@ -9828,6 +10774,8 @@ "qmljssemantichighlighter.h" "3" "qmljssemanticinfoupdater.cpp" "3" "qmljssemanticinfoupdater.h" "3" +"qmljstextmark.cpp" "3" +"qmljstextmark.h" "3" "qmljswrapinloader.cpp" "3" "qmljswrapinloader.h" "3" "qmloutlinemodel.cpp" "3" @@ -9839,13 +10787,13 @@ "QmlJSTools" "2" "qmljstools.qbs:3" "3" "PluginMetaData" "3" -"QtcPlugin.qbs:51" "4" +"QtcPlugin.qbs:49" "4" "QmlJSTools.json.in" "5" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" "Tests" "3" "qmljstools.qbs:50" "4" @@ -9872,6 +10820,10 @@ "qmljssemanticinfo.cpp" "3" "qmljssemanticinfo.h" "3" "qmljstools.qrc" "3" +"/qmljstools" "4" +"images" "5" +"settingscategory_qml.png" "6" +"settingscategory_qml@2x.png" "6" "qmljstools_global.h" "3" "qmljstoolsconstants.h" "3" "qmljstoolsplugin.cpp" "3" @@ -9903,6 +10855,8 @@ "qmlnote.cpp" "4" "qmlnote.h" "4" "qmlprofiler_global.h" "4" +"qmlprofileractions.cpp" "4" +"qmlprofileractions.h" "4" "qmlprofileranimationsmodel.cpp" "4" "qmlprofileranimationsmodel.h" "4" "qmlprofilerattachdialog.cpp" "4" @@ -9962,23 +10916,29 @@ "scenegraphtimelinemodel.cpp" "4" "scenegraphtimelinemodel.h" "4" "PluginMetaData" "3" -"QtcPlugin.qbs:51" "4" +"QtcPlugin.qbs:49" "4" "QmlProfiler.json.in" "5" "QML" "3" -"qmlprofiler.qbs:67" "4" +"qmlprofiler.qbs:68" "4" "qml" "4" "qmlprofiler.qrc" "5" +"/qmlprofiler" "6" +"bindingloops.frag" "7" +"bindingloops.vert" "7" +"QmlProfilerFlameGraphView.qml" "7" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" "Unit tests" "3" -"qmlprofiler.qbs:73" "4" +"qmlprofiler.qbs:74" "4" "tests" "4" "debugmessagesmodel_test.cpp" "5" "debugmessagesmodel_test.h" "5" +"fakedebugserver.cpp" "5" +"fakedebugserver.h" "5" "flamegraphmodel_test.cpp" "5" "flamegraphmodel_test.h" "5" "flamegraphview_test.cpp" "5" @@ -10009,12 +10969,24 @@ "qmlprofilerclientmanager_test.h" "5" "qmlprofilerconfigwidget_test.cpp" "5" "qmlprofilerconfigwidget_test.h" "5" +"qmlprofilerdetailsrewriter_test.cpp" "5" +"qmlprofilerdetailsrewriter_test.h" "5" +"qmlprofilertool_test.cpp" "5" +"qmlprofilertool_test.h" "5" +"qmlprofilertraceclient_test.cpp" "5" +"qmlprofilertraceclient_test.h" "5" "qmlprofilertraceview_test.cpp" "5" "qmlprofilertraceview_test.h" "5" +"tests.qrc" "5" +"/qmlprofiler/tests" "6" +"check.dat" "7" +"qmlprofilerdetailsrewriter_test.cpp" "7" +"Test.qml" "7" +"traces.dat" "7" "QmlProjectManager" "2" "qmlprojectmanager.qbs:3" "3" "File Format" "3" -"qmlprojectmanager.qbs:31" "4" +"qmlprojectmanager.qbs:30" "4" "fileformat" "4" "filefilteritems.cpp" "5" "filefilteritems.h" "5" @@ -10027,6 +10999,9 @@ "qmlproject.cpp" "4" "qmlproject.h" "4" "qmlproject.qrc" "4" +"/qmlproject" "5" +"images" "6" +"qmlproject.png" "7" "qmlprojectconstants.h" "4" "qmlprojectenvironmentaspect.cpp" "4" "qmlprojectenvironmentaspect.h" "4" @@ -10038,40 +11013,40 @@ "qmlprojectplugin.h" "4" "qmlprojectrunconfiguration.cpp" "4" "qmlprojectrunconfiguration.h" "4" -"qmlprojectrunconfigurationfactory.cpp" "4" -"qmlprojectrunconfigurationfactory.h" "4" "qmlprojectrunconfigurationwidget.cpp" "4" "qmlprojectrunconfigurationwidget.h" "4" "PluginMetaData" "3" -"QtcPlugin.qbs:51" "4" +"QtcPlugin.qbs:49" "4" "QmlProjectManager.json.in" "5" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" "Qnx" "2" "qnx.qbs:3" "3" "PluginMetaData" "3" -"QtcPlugin.qbs:51" "4" +"QtcPlugin.qbs:49" "4" "Qnx.json.in" "5" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" "pathchooserdelegate.cpp" "3" "pathchooserdelegate.h" "3" "qnx.qrc" "3" +"/qnx" "4" +"images" "5" +"qnxdevice.png" "6" +"qnxdevice@2x.png" "6" +"qnxdevicesmall.png" "6" +"qnxdevicesmall@2x.png" "6" "qnx_export.h" "3" "qnxanalyzesupport.cpp" "3" "qnxanalyzesupport.h" "3" -"qnxattachdebugdialog.cpp" "3" -"qnxattachdebugdialog.h" "3" -"qnxattachdebugsupport.cpp" "3" -"qnxattachdebugsupport.h" "3" "qnxbaseqtconfigwidget.cpp" "3" "qnxbaseqtconfigwidget.h" "3" "qnxconfiguration.cpp" "3" @@ -10083,13 +11058,9 @@ "qnxdebugsupport.h" "3" "qnxdeployconfiguration.cpp" "3" "qnxdeployconfiguration.h" "3" -"qnxdeployconfigurationfactory.cpp" "3" -"qnxdeployconfigurationfactory.h" "3" "qnxdeployqtlibrariesdialog.cpp" "3" "qnxdeployqtlibrariesdialog.h" "3" "qnxdeployqtlibrariesdialog.ui" "3" -"qnxdeploystepfactory.cpp" "3" -"qnxdeploystepfactory.h" "3" "qnxdevice.cpp" "3" "qnxdevice.h" "3" "qnxdevicefactory.cpp" "3" @@ -10112,8 +11083,6 @@ "qnxqtversionfactory.h" "3" "qnxrunconfiguration.cpp" "3" "qnxrunconfiguration.h" "3" -"qnxrunconfigurationfactory.cpp" "3" -"qnxrunconfigurationfactory.h" "3" "qnxsettingspage.cpp" "3" "qnxsettingspage.h" "3" "qnxsettingswidget.cpp" "3" @@ -10136,7 +11105,7 @@ "gettingstartedwelcomepage.cpp" "5" "gettingstartedwelcomepage.h" "5" "PluginMetaData" "4" -"QtcPlugin.qbs:51" "5" +"QtcPlugin.qbs:49" "5" "QtSupport.json.in" "6" "Pro Parser" "4" "qtsupport.qbs:26" "5" @@ -10147,6 +11116,11 @@ "proitems.cpp" "6" "proitems.h" "6" "proparser.qrc" "6" +"/qmake/features" "7" +"spec_post.prf" "8" +"spec_pre.prf" "8" +"/qmake/override_features" "7" +"objective_c.prf" "8" "prowriter.cpp" "6" "prowriter.h" "6" "qmake_global.h" "6" @@ -10167,10 +11141,10 @@ "desktopqtversionfactory.cpp" "5" "desktopqtversionfactory.h" "5" "standard pch file (gui)" "4" -"QtcProduct.qbs:58" "5" +"QtcProduct.qbs:65" "5" "qtcreator_gui_pch.h" "6" "standard pch file (non-gui)" "4" -"QtcProduct.qbs:50" "5" +"QtcProduct.qbs:57" "5" "qtcreator_pch.h" "6" "baseqtversion.cpp" "4" "baseqtversion.h" "4" @@ -10204,6 +11178,21 @@ "qtprojectimporter.cpp" "4" "qtprojectimporter.h" "4" "qtsupport.qrc" "4" +"/qtsupport" "5" +"images" "6" +"icons" "7" +"qteventicon.png" "8" +"qteventicon@2x.png" "8" +"tutorialicon.png" "8" +"tutorialicon@2x.png" "8" +"videotutorialicon.png" "8" +"videotutorialicon@2x.png" "8" +"dark_forms.png" "7" +"dark_qml.png" "7" +"dark_qt_project.png" "7" +"dark_qt_qrc.png" "7" +"images_areaofinterest.xml" "6" +"qtcreator_tutorials.xml" "6" "qtsupport_global.h" "4" "qtsupportconstants.h" "4" "qtsupportplugin.cpp" "4" @@ -10253,13 +11242,13 @@ "RemoteLinux" "3" "remotelinux.qbs:8" "4" "PluginMetaData" "4" -"QtcPlugin.qbs:51" "5" +"QtcPlugin.qbs:49" "5" "RemoteLinux.json.in" "6" "standard pch file (gui)" "4" -"QtcProduct.qbs:58" "5" +"QtcProduct.qbs:65" "5" "qtcreator_gui_pch.h" "6" "standard pch file (non-gui)" "4" -"QtcProduct.qbs:50" "5" +"QtcProduct.qbs:57" "5" "qtcreator_pch.h" "6" "images" "4" "embeddedtarget.png" "5" @@ -10269,8 +11258,6 @@ "abstractremotelinuxdeployservice.h" "4" "abstractremotelinuxdeploystep.cpp" "4" "abstractremotelinuxdeploystep.h" "4" -"abstractremotelinuxrunsupport.cpp" "4" -"abstractremotelinuxrunsupport.h" "4" "abstractuploadandinstallpackageservice.cpp" "4" "abstractuploadandinstallpackageservice.h" "4" "deploymenttimeinfo.cpp" "4" @@ -10293,8 +11280,6 @@ "genericlinuxdeviceconfigurationwizardpages.cpp" "4" "genericlinuxdeviceconfigurationwizardpages.h" "4" "genericlinuxdeviceconfigurationwizardsetuppage.ui" "4" -"genericremotelinuxdeploystepfactory.cpp" "4" -"genericremotelinuxdeploystepfactory.h" "4" "linuxdevice.cpp" "4" "linuxdevice.h" "4" "linuxdeviceprocess.cpp" "4" @@ -10306,10 +11291,11 @@ "publickeydeploymentdialog.cpp" "4" "publickeydeploymentdialog.h" "4" "remotelinux.qrc" "4" +"/remotelinux" "5" +"images" "6" +"embeddedtarget.png" "7" "remotelinux_constants.h" "4" "remotelinux_export.h" "4" -"remotelinuxanalyzesupport.cpp" "4" -"remotelinuxanalyzesupport.h" "4" "remotelinuxcheckforfreediskspaceservice.cpp" "4" "remotelinuxcheckforfreediskspaceservice.h" "4" "remotelinuxcheckforfreediskspacestep.cpp" "4" @@ -10321,29 +11307,28 @@ "remotelinuxcustomcommanddeployservice.h" "4" "remotelinuxcustomrunconfiguration.cpp" "4" "remotelinuxcustomrunconfiguration.h" "4" -"remotelinuxcustomrunconfigurationwidget.ui" "4" "remotelinuxdebugsupport.cpp" "4" "remotelinuxdebugsupport.h" "4" "remotelinuxdeployconfiguration.cpp" "4" "remotelinuxdeployconfiguration.h" "4" -"remotelinuxdeployconfigurationfactory.cpp" "4" -"remotelinuxdeployconfigurationfactory.h" "4" "remotelinuxenvironmentaspect.cpp" "4" "remotelinuxenvironmentaspect.h" "4" "remotelinuxenvironmentaspectwidget.cpp" "4" "remotelinuxenvironmentaspectwidget.h" "4" "remotelinuxenvironmentreader.cpp" "4" "remotelinuxenvironmentreader.h" "4" +"remotelinuxkillappservice.cpp" "4" +"remotelinuxkillappservice.h" "4" +"remotelinuxkillappstep.cpp" "4" +"remotelinuxkillappstep.h" "4" "remotelinuxpackageinstaller.cpp" "4" "remotelinuxpackageinstaller.h" "4" "remotelinuxplugin.cpp" "4" "remotelinuxplugin.h" "4" +"remotelinuxqmltoolingsupport.cpp" "4" +"remotelinuxqmltoolingsupport.h" "4" "remotelinuxrunconfiguration.cpp" "4" "remotelinuxrunconfiguration.h" "4" -"remotelinuxrunconfigurationfactory.cpp" "4" -"remotelinuxrunconfigurationfactory.h" "4" -"remotelinuxrunconfigurationwidget.cpp" "4" -"remotelinuxrunconfigurationwidget.h" "4" "remotelinuxsignaloperation.cpp" "4" "remotelinuxsignaloperation.h" "4" "remotelinuxutils.cpp" "4" @@ -10363,7 +11348,6 @@ "abstractpackagingstep.h" "6" "abstractremotelinuxdeployservice.h" "6" "abstractremotelinuxdeploystep.h" "6" -"abstractremotelinuxrunsupport.h" "6" "abstractuploadandinstallpackageservice.h" "6" "deploymenttimeinfo.h" "6" "embeddedlinuxqtversion.h" "6" @@ -10374,7 +11358,6 @@ "genericlinuxdeviceconfigurationwidget.h" "6" "genericlinuxdeviceconfigurationwizard.h" "6" "genericlinuxdeviceconfigurationwizardpages.h" "6" -"genericremotelinuxdeploystepfactory.h" "6" "linuxdevice.h" "6" "linuxdeviceprocess.h" "6" "linuxdevicetester.h" "6" @@ -10382,7 +11365,6 @@ "publickeydeploymentdialog.h" "6" "remotelinux_constants.h" "6" "remotelinux_export.h" "6" -"remotelinuxanalyzesupport.h" "6" "remotelinuxcheckforfreediskspaceservice.h" "6" "remotelinuxcheckforfreediskspacestep.h" "6" "remotelinuxcustomcommanddeploymentstep.h" "6" @@ -10390,15 +11372,15 @@ "remotelinuxcustomrunconfiguration.h" "6" "remotelinuxdebugsupport.h" "6" "remotelinuxdeployconfiguration.h" "6" -"remotelinuxdeployconfigurationfactory.h" "6" "remotelinuxenvironmentaspect.h" "6" "remotelinuxenvironmentaspectwidget.h" "6" "remotelinuxenvironmentreader.h" "6" +"remotelinuxkillappservice.h" "6" +"remotelinuxkillappstep.h" "6" "remotelinuxpackageinstaller.h" "6" "remotelinuxplugin.h" "6" +"remotelinuxqmltoolingsupport.h" "6" "remotelinuxrunconfiguration.h" "6" -"remotelinuxrunconfigurationfactory.h" "6" -"remotelinuxrunconfigurationwidget.h" "6" "remotelinuxsignaloperation.h" "6" "remotelinuxutils.h" "6" "sshkeydeployer.h" "6" @@ -10422,7 +11404,7 @@ "resourcenode.cpp" "5" "resourcenode.h" "5" "PluginMetaData" "4" -"QtcPlugin.qbs:51" "5" +"QtcPlugin.qbs:49" "5" "ResourceEditor.json.in" "6" "QRC Editor" "4" "resourceeditor.qbs:29" "5" @@ -10437,10 +11419,10 @@ "undocommands.cpp" "6" "undocommands_p.h" "6" "standard pch file (gui)" "4" -"QtcProduct.qbs:58" "5" +"QtcProduct.qbs:65" "5" "qtcreator_gui_pch.h" "6" "standard pch file (non-gui)" "4" -"QtcProduct.qbs:50" "5" +"QtcProduct.qbs:57" "5" "qtcreator_pch.h" "6" "ResourceEditor dev headers" "3" "resourceeditor.qbs:6" "4" @@ -10480,6 +11462,40 @@ "colortoolbutton.cpp" "5" "colortoolbutton.h" "5" "common.qrc" "5" +"/scxmleditor" "6" +"images" "7" +"adjust_height.png" "8" +"adjust_height@2x.png" "8" +"adjust_size.png" "8" +"adjust_size@2x.png" "8" +"adjust_width.png" "8" +"adjust_width@2x.png" "8" +"align_bottom.png" "8" +"align_bottom@2x.png" "8" +"align_horizontal.png" "8" +"align_horizontal@2x.png" "8" +"align_left.png" "8" +"align_left@2x.png" "8" +"align_right.png" "8" +"align_right@2x.png" "8" +"align_top.png" "8" +"align_top@2x.png" "8" +"align_vertical.png" "8" +"align_vertical@2x.png" "8" +"colorthemes.png" "8" +"final.png" "8" +"font_color.png" "8" +"history.png" "8" +"icon-export-canvas.png" "8" +"icon-export-canvas@2x.png" "8" +"initial.png" "8" +"more_colors.png" "8" +"navigator.png" "8" +"parallel.png" "8" +"parallel_icon.png" "8" +"state.png" "8" +"state_color.png" "8" +"statistics.png" "8" "dragshapebutton.cpp" "5" "dragshapebutton.h" "5" "graphicsview.cpp" "5" @@ -10633,13 +11649,13 @@ "warningitem.h" "5" "warningprovider.h" "5" "PluginMetaData" "3" -"QtcPlugin.qbs:51" "4" +"QtcPlugin.qbs:49" "4" "ScxmlEditor.json.in" "5" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" "scxmlcontext.cpp" "3" "scxmlcontext.h" "3" @@ -10657,16 +11673,40 @@ "scxmleditorstack.h" "3" "scxmltexteditor.cpp" "3" "scxmltexteditor.h" "3" +"SerialTerminal" "2" +"serialterminal.qbs:3" "3" +"PluginMetaData" "3" +"QtcPlugin.qbs:49" "4" +"SerialTerminal.json.in" "5" +"standard pch file (gui)" "3" +"QtcProduct.qbs:65" "4" +"qtcreator_gui_pch.h" "5" +"standard pch file (non-gui)" "3" +"QtcProduct.qbs:57" "4" +"qtcreator_pch.h" "5" +"consolelineedit.cpp" "3" +"consolelineedit.h" "3" +"serialcontrol.cpp" "3" +"serialcontrol.h" "3" +"serialdevicemodel.cpp" "3" +"serialdevicemodel.h" "3" +"serialoutputpane.cpp" "3" +"serialoutputpane.h" "3" +"serialterminalconstants.h" "3" +"serialterminalplugin.cpp" "3" +"serialterminalplugin.h" "3" +"serialterminalsettings.cpp" "3" +"serialterminalsettings.h" "3" "SilverSearcher" "2" "silversearcher.qbs:3" "3" "PluginMetaData" "3" -"QtcPlugin.qbs:51" "4" +"QtcPlugin.qbs:49" "4" "SilverSearcher.json.in" "5" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" "Tests" "3" "silversearcher.qbs:16" "4" @@ -10681,13 +11721,13 @@ "Subversion" "2" "subversion.qbs:3" "3" "PluginMetaData" "3" -"QtcPlugin.qbs:51" "4" +"QtcPlugin.qbs:49" "4" "Subversion.json.in" "5" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" "annotationhighlighter.cpp" "3" "annotationhighlighter.h" "3" @@ -10710,13 +11750,13 @@ "TaskList" "2" "tasklist.qbs:3" "3" "PluginMetaData" "3" -"QtcPlugin.qbs:51" "4" +"QtcPlugin.qbs:49" "4" "TaskList.json.in" "5" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" "stopmonitoringhandler.cpp" "3" "stopmonitoringhandler.h" "3" @@ -10730,7 +11770,7 @@ "TextEditor" "3" "texteditor.qbs:8" "4" "CodeAssist" "4" -"texteditor.qbs:151" "5" +"texteditor.qbs:149" "5" "codeassist" "5" "assistenums.h" "6" "assistinterface.cpp" "6" @@ -10742,6 +11782,8 @@ "codeassistant.h" "6" "completionassistprovider.cpp" "6" "completionassistprovider.h" "6" +"documentcontentcompletion.cpp" "6" +"documentcontentcompletion.h" "6" "functionhintproposal.cpp" "6" "functionhintproposal.h" "6" "functionhintproposalwidget.cpp" "6" @@ -10766,17 +11808,13 @@ "ifunctionhintproposalmodel.h" "6" "keywordscompletionassist.cpp" "6" "keywordscompletionassist.h" "6" -"quickfixassistprocessor.cpp" "6" -"quickfixassistprocessor.h" "6" -"quickfixassistprovider.cpp" "6" -"quickfixassistprovider.h" "6" "runner.cpp" "6" "runner.h" "6" "textdocumentmanipulator.cpp" "6" "textdocumentmanipulator.h" "6" "textdocumentmanipulatorinterface.h" "6" "GenericHighlighter" "4" -"texteditor.qbs:201" "5" +"texteditor.qbs:197" "5" "generichighlighter" "5" "context.cpp" "6" "context.h" "6" @@ -10816,10 +11854,10 @@ "specificrules.cpp" "6" "specificrules.h" "6" "PluginMetaData" "4" -"QtcPlugin.qbs:51" "5" +"QtcPlugin.qbs:49" "5" "TextEditor.json.in" "6" "Snippets" "4" -"texteditor.qbs:245" "5" +"texteditor.qbs:241" "5" "snippets" "5" "reuse.h" "6" "snippet.cpp" "6" @@ -10838,13 +11876,13 @@ "snippetssettingspage.h" "6" "snippetssettingspage.ui" "6" "standard pch file (gui)" "4" -"QtcProduct.qbs:58" "5" +"QtcProduct.qbs:65" "5" "qtcreator_gui_pch.h" "6" "standard pch file (non-gui)" "4" -"QtcProduct.qbs:50" "5" +"QtcProduct.qbs:57" "5" "qtcreator_pch.h" "6" "Tests" "4" -"texteditor.qbs:268" "5" +"texteditor.qbs:264" "5" "texteditor_test.cpp" "5" "autocompleter.cpp" "4" "autocompleter.h" "4" @@ -10888,8 +11926,6 @@ "completionsettingspage.cpp" "4" "completionsettingspage.h" "4" "completionsettingspage.ui" "4" -"convenience.cpp" "4" -"convenience.h" "4" "displaysettings.cpp" "4" "displaysettings.h" "4" "displaysettingspage.cpp" "4" @@ -10957,6 +11993,12 @@ "texteditor.cpp" "4" "texteditor.h" "4" "texteditor.qrc" "4" +"/texteditor" "5" +"images" "6" +"finddocuments.png" "7" +"settingscategory_texteditor.png" "7" +"settingscategory_texteditor@2x.png" "7" +"snippet.png" "7" "texteditor_global.h" "4" "texteditor_p.h" "4" "texteditoractionhandler.cpp" "4" @@ -10987,6 +12029,7 @@ "assistproposaliteminterface.h" "7" "codeassistant.h" "7" "completionassistprovider.h" "7" +"documentcontentcompletion.h" "7" "functionhintproposal.h" "7" "functionhintproposalwidget.h" "7" "genericproposal.h" "7" @@ -10999,8 +12042,6 @@ "iassistprovider.h" "7" "ifunctionhintproposalmodel.h" "7" "keywordscompletionassist.h" "7" -"quickfixassistprocessor.h" "7" -"quickfixassistprovider.h" "7" "runner.h" "7" "textdocumentmanipulator.h" "7" "textdocumentmanipulatorinterface.h" "7" @@ -11052,7 +12093,6 @@ "commentssettings.h" "6" "completionsettings.h" "6" "completionsettingspage.h" "6" -"convenience.h" "6" "displaysettings.h" "6" "displaysettingspage.h" "6" "extraencodingsettings.h" "6" @@ -11099,13 +12139,13 @@ "Todo" "2" "todo.qbs:3" "3" "PluginMetaData" "3" -"QtcPlugin.qbs:51" "4" +"QtcPlugin.qbs:49" "4" "Todo.json.in" "5" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" "constants.h" "3" "cpptodoitemsscanner.cpp" "3" @@ -11144,19 +12184,29 @@ "todoplugin.cpp" "3" "todoplugin.h" "3" "todoplugin.qrc" "3" +"/todoplugin" "4" +"images" "5" +"bug.png" "6" +"bug@2x.png" "6" +"bugfill.png" "6" +"bugfill@2x.png" "6" +"settingscategory_todo.png" "6" +"settingscategory_todo@2x.png" "6" +"tasklist.png" "6" +"tasklist@2x.png" "6" "todoprojectsettingswidget.cpp" "3" "todoprojectsettingswidget.h" "3" "todoprojectsettingswidget.ui" "3" "UpdateInfo" "2" "updateinfo.qbs:3" "3" "PluginMetaData" "3" -"QtcPlugin.qbs:51" "4" +"QtcPlugin.qbs:49" "4" "UpdateInfo.json.in" "5" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" "settingspage.cpp" "3" "settingspage.h" "3" @@ -11166,7 +12216,7 @@ "Valgrind" "2" "valgrind.qbs:4" "3" "Callgrind" "3" -"valgrind.qbs:43" "4" +"valgrind.qbs:42" "4" "callgrind" "4" "callgrindabstractmodel.h" "5" "callgrindcallmodel.cpp" "5" @@ -11212,14 +12262,17 @@ "callgrindtool.h" "4" "callgrindvisualisation.cpp" "4" "callgrindvisualisation.h" "4" -"memcheckengine.cpp" "4" -"memcheckengine.h" "4" "memcheckerrorview.cpp" "4" "memcheckerrorview.h" "4" "memchecktool.cpp" "4" "memchecktool.h" "4" "suppressiondialog.cpp" "4" "suppressiondialog.h" "4" +"valgrind.qrc" "4" +"/valgrind" "5" +"images" "6" +"suppressoverlay.png" "7" +"suppressoverlay@2x.png" "7" "valgrindconfigwidget.cpp" "4" "valgrindconfigwidget.h" "4" "valgrindconfigwidget.ui" "4" @@ -11231,25 +12284,23 @@ "valgrindrunner.h" "4" "valgrindsettings.cpp" "4" "valgrindsettings.h" "4" -"workarounds.cpp" "4" -"workarounds.h" "4" "PluginMetaData" "3" -"QtcPlugin.qbs:51" "4" +"QtcPlugin.qbs:49" "4" "Valgrind.json.in" "5" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" "Test sources" "3" -"valgrind.qbs:81" "4" +"valgrind.qbs:80" "4" "valgrindmemcheckparsertest.cpp" "4" "valgrindmemcheckparsertest.h" "4" "valgrindtestrunnertest.cpp" "4" "valgrindtestrunnertest.h" "4" "XML Protocol" "3" -"valgrind.qbs:63" "4" +"valgrind.qbs:62" "4" "xmlprotocol" "4" "announcethread.cpp" "5" "announcethread.h" "5" @@ -11276,18 +12327,14 @@ "VcsBase" "2" "vcsbase.qbs:3" "3" "PluginMetaData" "3" -"QtcPlugin.qbs:51" "4" +"QtcPlugin.qbs:49" "4" "VcsBase.json.in" "5" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" -"images" "3" -"diff.png" "4" -"removesubmitfield.png" "4" -"submit.png" "4" "wizard" "3" "vcscommandpage.cpp" "4" "vcscommandpage.h" "4" @@ -11324,6 +12371,18 @@ "submitfilemodel.cpp" "3" "submitfilemodel.h" "3" "vcsbase.qrc" "3" +"/vcsbase" "4" +"images" "5" +"diff_arrows.png" "6" +"diff_arrows@2x.png" "6" +"diff_documents.png" "6" +"diff_documents@2x.png" "6" +"settingscategory_vcs.png" "6" +"settingscategory_vcs@2x.png" "6" +"submit_arrow.png" "6" +"submit_arrow@2x.png" "6" +"submit_db.png" "6" +"submit_db@2x.png" "6" "vcsbase_global.h" "3" "vcsbaseclient.cpp" "3" "vcsbaseclient.h" "3" @@ -11353,26 +12412,50 @@ "Welcome" "2" "welcome.qbs:3" "3" "PluginMetaData" "3" -"QtcPlugin.qbs:51" "4" +"QtcPlugin.qbs:49" "4" "Welcome.json.in" "5" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" "welcome.qrc" "3" +"/welcome" "4" +"images" "5" +"blogs.png" "6" +"blogs@2x.png" "6" +"community.png" "6" +"community@2x.png" "6" +"expandarrow.png" "6" +"expandarrow@2x.png" "6" +"mode_welcome.png" "6" +"mode_welcome@2x.png" "6" +"mode_welcome_mask.png" "6" +"mode_welcome_mask@2x.png" "6" +"new.png" "6" +"new@2x.png" "6" +"open.png" "6" +"open@2x.png" "6" +"project.png" "6" +"project@2x.png" "6" +"qtaccount.png" "6" +"qtaccount@2x.png" "6" +"session.png" "6" +"session@2x.png" "6" +"userguide.png" "6" +"userguide@2x.png" "6" "welcomeplugin.cpp" "3" "WinRt" "2" "winrt.qbs:3" "3" "PluginMetaData" "3" -"QtcPlugin.qbs:51" "4" +"QtcPlugin.qbs:49" "4" "WinRt.json.in" "5" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" "winrtconstants.h" "3" "winrtdebugsupport.cpp" "3" @@ -11398,12 +12481,8 @@ "winrtqtversionfactory.h" "3" "winrtrunconfiguration.cpp" "3" "winrtrunconfiguration.h" "3" -"winrtrunconfigurationwidget.cpp" "3" -"winrtrunconfigurationwidget.h" "3" "winrtruncontrol.cpp" "3" "winrtruncontrol.h" "3" -"winrtrunfactories.cpp" "3" -"winrtrunfactories.h" "3" "winrtrunnerhelper.cpp" "3" "winrtrunnerhelper.h" "3" "precompiled headers" "1" @@ -11432,44 +12511,729 @@ "apps.qbs:3" "3" "qbs-config" "3" "config.qbs:3" "4" +"logging" "4" +"QbsApp.qbs:23" "5" +"coloredoutput.cpp" "6" +"coloredoutput.h" "6" +"consolelogger.cpp" "6" +"consolelogger.h" "6" +"configcommand.h" "4" +"configcommandexecutor.cpp" "4" +"configcommandexecutor.h" "4" +"configcommandlineparser.cpp" "4" +"configcommandlineparser.h" "4" +"configmain.cpp" "4" "qbs-config-ui" "3" "config-ui.qbs:3" "4" +"Group 2" "4" +"config-ui.qbs:16" "5" +"fgapp.mm" "5" +"Info.plist" "5" +"logging" "4" +"QbsApp.qbs:23" "5" +"coloredoutput.cpp" "6" +"coloredoutput.h" "6" +"consolelogger.cpp" "6" +"consolelogger.h" "6" +"commandlineparser.cpp" "4" +"commandlineparser.h" "4" +"main.cpp" "4" +"mainwindow.cpp" "4" +"mainwindow.h" "4" +"mainwindow.ui" "4" "qbs-create-project" "3" "qbs-create-project.qbs:3" "4" -"qbs-qmltypes" "3" -"qbs-qmltypes.qbs:3" "4" +"logging" "4" +"QbsApp.qbs:23" "5" +"coloredoutput.cpp" "6" +"coloredoutput.h" "6" +"consolelogger.cpp" "6" +"consolelogger.h" "6" +"create-project-main.cpp" "4" +"createproject.cpp" "4" +"createproject.h" "4" "qbs-setup-android" "3" "qbs-setup-android.qbs:3" "4" +"logging" "4" +"QbsApp.qbs:23" "5" +"coloredoutput.cpp" "6" +"coloredoutput.h" "6" +"consolelogger.cpp" "6" +"consolelogger.h" "6" +"MinGW specific files" "4" +"qbs-setup-android.qbs:12" "5" +"qbs-setup-android.exe.manifest" "5" +"qbs-setup-android.rc" "5" +"android-setup.cpp" "4" +"android-setup.h" "4" +"commandlineparser.cpp" "4" +"commandlineparser.h" "4" +"main.cpp" "4" "qbs-setup-qt" "3" "qbs-setup-qt.qbs:3" "4" +"logging" "4" +"QbsApp.qbs:23" "5" +"coloredoutput.cpp" "6" +"coloredoutput.h" "6" +"consolelogger.cpp" "6" +"consolelogger.h" "6" +"MinGW specific files" "4" +"qbs-setup-qt.qbs:13" "5" +"qbs-setup-qt.exe.manifest" "5" +"qbs-setup-qt.rc" "5" +"commandlineparser.cpp" "4" +"commandlineparser.h" "4" +"main.cpp" "4" +"setupqt.cpp" "4" +"setupqt.h" "4" "qbs-setup-toolchains" "3" "qbs-setup-toolchains.qbs:3" "4" +"logging" "4" +"QbsApp.qbs:23" "5" +"coloredoutput.cpp" "6" +"coloredoutput.h" "6" +"consolelogger.cpp" "6" +"consolelogger.h" "6" +"MinGW specific files" "4" +"qbs-setup-toolchains.qbs:17" "5" +"qbs-setup-toolchains.exe.manifest" "5" +"qbs-setup-toolchains.rc" "5" +"commandlineparser.cpp" "4" +"commandlineparser.h" "4" +"main.cpp" "4" +"msvcprobe.cpp" "4" +"msvcprobe.h" "4" +"probe.cpp" "4" +"probe.h" "4" +"xcodeprobe.cpp" "4" +"xcodeprobe.h" "4" "qbs_app" "3" -"qbs.qbs:3" "4" +"qbs.qbs:4" "4" +"logging" "4" +"QbsApp.qbs:23" "5" +"coloredoutput.cpp" "6" +"coloredoutput.h" "6" +"consolelogger.cpp" "6" +"consolelogger.h" "6" +"parser" "4" +"qbs.qbs:29" "5" +"parser" "5" +"commandlineoption.cpp" "6" +"commandlineoption.h" "6" +"commandlineoptionpool.cpp" "6" +"commandlineoptionpool.h" "6" +"commandlineparser.cpp" "6" +"commandlineparser.h" "6" +"commandpool.cpp" "6" +"commandpool.h" "6" +"commandtype.h" "6" +"parsercommand.cpp" "6" +"parsercommand.h" "6" +"application.cpp" "4" +"application.h" "4" +"commandlinefrontend.cpp" "4" +"commandlinefrontend.h" "4" +"consoleprogressobserver.cpp" "4" +"consoleprogressobserver.h" "4" +"ctrlchandler.cpp" "4" +"ctrlchandler.h" "4" +"main.cpp" "4" +"qbstool.cpp" "4" +"qbstool.h" "4" +"status.cpp" "4" +"status.h" "4" +"bundledqt" "2" +"bundledqt.qbs:4" "3" +"QPA plugin" "3" +"bundledqt.qbs:65" "4" +"Qt libraries" "3" +"bundledqt.qbs:30" "4" +"qt.conf" "3" +"bundledqt.qbs:22" "4" +"qt.conf" "4" "libexec" "2" "libexec.qbs:3" "3" "qbs_processlauncher" "3" "qbs_processlauncher.qbs:4" "4" +"protocol sources" "4" +"qbs_processlauncher.qbs:24" "5" +"launcherpackets.cpp" "6" +"launcherpackets.h" "6" +"launcherlogging.cpp" "4" +"launcherlogging.h" "4" +"launchersockethandler.cpp" "4" +"launchersockethandler.h" "4" +"processlauncher-main.cpp" "4" "libs" "2" "libs.qbs:3" "3" "qbscore" "3" -"corelib.qbs:3" "4" +"corelib.qbs:4" "4" +"api" "4" +"corelib.qbs:69" "5" +"api" "5" +"internaljobs.cpp" "6" +"internaljobs.h" "6" +"jobs.cpp" "6" +"languageinfo.cpp" "6" +"project.cpp" "6" +"project_p.h" "6" +"projectdata.cpp" "6" +"projectdata_p.h" "6" +"propertymap_p.h" "6" +"rulecommand.cpp" "6" +"rulecommand_p.h" "6" +"runenvironment.cpp" "6" +"transformerdata.cpp" "6" +"transformerdata_p.h" "6" +"buildgraph" "4" +"corelib.qbs:104" "5" +"buildgraph" "5" +"abstractcommandexecutor.cpp" "6" +"abstractcommandexecutor.h" "6" +"artifact.cpp" "6" +"artifact.h" "6" +"artifactcleaner.cpp" "6" +"artifactcleaner.h" "6" +"artifactsscriptvalue.cpp" "6" +"artifactsscriptvalue.h" "6" +"artifactvisitor.cpp" "6" +"artifactvisitor.h" "6" +"buildgraph.cpp" "6" +"buildgraph.h" "6" +"buildgraphloader.cpp" "6" +"buildgraphloader.h" "6" +"buildgraphnode.cpp" "6" +"buildgraphnode.h" "6" +"buildgraphvisitor.h" "6" +"cycledetector.cpp" "6" +"cycledetector.h" "6" +"dependencyparametersscriptvalue.cpp" "6" +"dependencyparametersscriptvalue.h" "6" +"depscanner.cpp" "6" +"depscanner.h" "6" +"emptydirectoriesremover.cpp" "6" +"emptydirectoriesremover.h" "6" +"environmentscriptrunner.cpp" "6" +"environmentscriptrunner.h" "6" +"executor.cpp" "6" +"executor.h" "6" +"executorjob.cpp" "6" +"executorjob.h" "6" +"filedependency.cpp" "6" +"filedependency.h" "6" +"inputartifactscanner.cpp" "6" +"inputartifactscanner.h" "6" +"jscommandexecutor.cpp" "6" +"jscommandexecutor.h" "6" +"nodeset.cpp" "6" +"nodeset.h" "6" +"nodetreedumper.cpp" "6" +"nodetreedumper.h" "6" +"processcommandexecutor.cpp" "6" +"processcommandexecutor.h" "6" +"productbuilddata.cpp" "6" +"productbuilddata.h" "6" +"productinstaller.cpp" "6" +"productinstaller.h" "6" +"projectbuilddata.cpp" "6" +"projectbuilddata.h" "6" +"qtmocscanner.cpp" "6" +"qtmocscanner.h" "6" +"rawscanneddependency.cpp" "6" +"rawscanneddependency.h" "6" +"rawscanresults.cpp" "6" +"rawscanresults.h" "6" +"requestedartifacts.cpp" "6" +"requestedartifacts.h" "6" +"requesteddependencies.cpp" "6" +"requesteddependencies.h" "6" +"rescuableartifactdata.h" "6" +"rulecommands.cpp" "6" +"rulecommands.h" "6" +"rulegraph.cpp" "6" +"rulegraph.h" "6" +"rulenode.cpp" "6" +"rulenode.h" "6" +"rulesapplicator.cpp" "6" +"rulesapplicator.h" "6" +"rulesevaluationcontext.cpp" "6" +"rulesevaluationcontext.h" "6" +"scriptclasspropertyiterator.h" "6" +"timestampsupdater.cpp" "6" +"timestampsupdater.h" "6" +"transformer.cpp" "6" +"transformer.h" "6" +"transformerchangetracking.cpp" "6" +"transformerchangetracking.h" "6" +"generators" "4" +"corelib.qbs:193" "5" +"generators" "5" +"generatableprojectiterator.cpp" "6" +"generatableprojectiterator.h" "6" +"generator.cpp" "6" +"generatordata.cpp" "6" +"igeneratableprojectvisitor.h" "6" +"jsextensions" "4" +"corelib.qbs:214" "5" +"jsextensions" "5" +"binaryfile.cpp" "6" +"domxml.cpp" "6" +"environmentextension.cpp" "6" +"file.cpp" "6" +"fileinfoextension.cpp" "6" +"jsextensions.cpp" "6" +"jsextensions.h" "6" +"moduleproperties.cpp" "6" +"moduleproperties.h" "6" +"process.cpp" "6" +"temporarydir.cpp" "6" +"textfile.cpp" "6" +"utilitiesextension.cpp" "6" +"jsextensions (Darwin-specific)" "4" +"corelib.qbs:241" "5" +"jsextensions" "5" +"propertylist.mm" "6" +"propertylistutils.h" "6" +"propertylistutils.mm" "6" +"jsextensions (Non-Darwin-specific)" "4" +"corelib.qbs:233" "5" +"jsextensions" "5" +"propertylist.cpp" "6" +"language" "4" +"corelib.qbs:251" "5" +"language" "5" +"artifactproperties.cpp" "6" +"artifactproperties.h" "6" +"astimportshandler.cpp" "6" +"astimportshandler.h" "6" +"astpropertiesitemhandler.cpp" "6" +"astpropertiesitemhandler.h" "6" +"asttools.cpp" "6" +"asttools.h" "6" +"builtindeclarations.cpp" "6" +"builtindeclarations.h" "6" +"deprecationinfo.h" "6" +"evaluationdata.h" "6" +"evaluator.cpp" "6" +"evaluator.h" "6" +"evaluatorscriptclass.cpp" "6" +"evaluatorscriptclass.h" "6" +"filecontext.cpp" "6" +"filecontext.h" "6" +"filecontextbase.cpp" "6" +"filecontextbase.h" "6" +"filetags.cpp" "6" +"filetags.h" "6" +"identifiersearch.cpp" "6" +"identifiersearch.h" "6" +"item.cpp" "6" +"item.h" "6" +"itemdeclaration.cpp" "6" +"itemdeclaration.h" "6" +"itemobserver.h" "6" +"itempool.cpp" "6" +"itempool.h" "6" +"itemreader.cpp" "6" +"itemreader.h" "6" +"itemreaderastvisitor.cpp" "6" +"itemreaderastvisitor.h" "6" +"itemreadervisitorstate.cpp" "6" +"itemreadervisitorstate.h" "6" +"itemtype.h" "6" +"jsimports.h" "6" +"language.cpp" "6" +"language.h" "6" +"loader.cpp" "6" +"loader.h" "6" +"moduleloader.cpp" "6" +"moduleloader.h" "6" +"modulemerger.cpp" "6" +"modulemerger.h" "6" +"preparescriptobserver.cpp" "6" +"preparescriptobserver.h" "6" +"projectresolver.cpp" "6" +"projectresolver.h" "6" +"property.cpp" "6" +"property.h" "6" +"propertydeclaration.cpp" "6" +"propertydeclaration.h" "6" +"propertymapinternal.cpp" "6" +"propertymapinternal.h" "6" +"qualifiedid.cpp" "6" +"qualifiedid.h" "6" +"resolvedfilecontext.cpp" "6" +"resolvedfilecontext.h" "6" +"scriptengine.cpp" "6" +"scriptengine.h" "6" +"scriptimporter.cpp" "6" +"scriptimporter.h" "6" +"scriptpropertyobserver.cpp" "6" +"scriptpropertyobserver.h" "6" +"value.cpp" "6" +"value.h" "6" +"logging" "4" +"corelib.qbs:332" "5" +"logging" "5" +"categories.cpp" "6" +"categories.h" "6" +"ilogsink.cpp" "6" +"logger.cpp" "6" +"logger.h" "6" +"translator.h" "6" +"parser" "4" +"corelib.qbs:350" "5" +"parser" "5" +"qmlerror.cpp" "6" +"qmlerror.h" "6" +"qmljsast.cpp" "6" +"qmljsast_p.h" "6" +"qmljsastfwd_p.h" "6" +"qmljsastvisitor.cpp" "6" +"qmljsastvisitor_p.h" "6" +"qmljsengine_p.cpp" "6" +"qmljsengine_p.h" "6" +"qmljsglobal_p.h" "6" +"qmljsgrammar.cpp" "6" +"qmljsgrammar_p.h" "6" +"qmljskeywords_p.h" "6" +"qmljslexer.cpp" "6" +"qmljslexer_p.h" "6" +"qmljsmemorypool_p.h" "6" +"qmljsparser.cpp" "6" +"qmljsparser_p.h" "6" +"project file updating" "4" +"corelib.qbs:55" "5" +"api" "5" +"changeset.cpp" "6" +"changeset.h" "6" +"projectfileupdater.cpp" "6" +"projectfileupdater.h" "6" +"qmljsrewriter.cpp" "6" +"qmljsrewriter.h" "6" +"public api headers" "4" +"corelib.qbs:89" "5" +"api" "5" +"jobs.h" "6" +"languageinfo.h" "6" +"project.h" "6" +"projectdata.h" "6" +"rulecommand.h" "6" +"runenvironment.h" "6" +"transformerdata.h" "6" +"public buildgraph headers" "4" +"corelib.qbs:187" "5" +"buildgraph" "5" +"forward_decls.h" "6" +"public generator headers" "4" +"corelib.qbs:204" "5" +"generators" "5" +"generator.h" "6" +"generatordata.h" "6" +"public language headers" "4" +"corelib.qbs:326" "5" +"language" "5" +"forward_decls.h" "6" +"public logging headers" "4" +"corelib.qbs:344" "5" +"logging" "5" +"ilogsink.h" "6" +"public tools headers" "4" +"corelib.qbs:459" "5" +"tools" "5" +"architectures.h" "6" +"buildoptions.h" "6" +"cleanoptions.h" "6" +"codelocation.h" "6" +"commandechomode.h" "6" +"error.h" "6" +"generateoptions.h" "6" +"installoptions.h" "6" +"preferences.h" "6" +"processresult.h" "6" +"profile.h" "6" +"projectgeneratormanager.h" "6" +"qbs_export.h" "6" +"settings.h" "6" +"settingsmodel.h" "6" +"setupprojectparameters.h" "6" +"toolchains.h" "6" +"version.h" "6" +"qbscore" "4" +"corelib.qbs:49" "5" +"qbs.h" "5" +"tools" "4" +"corelib.qbs:374" "5" +"tools" "5" +"architectures.cpp" "6" +"buildgraphlocker.cpp" "6" +"buildgraphlocker.h" "6" +"buildoptions.cpp" "6" +"cleanoptions.cpp" "6" +"codelocation.cpp" "6" +"commandechomode.cpp" "6" +"dynamictypecheck.h" "6" +"error.cpp" "6" +"executablefinder.cpp" "6" +"executablefinder.h" "6" +"fileinfo.cpp" "6" +"fileinfo.h" "6" +"filesaver.cpp" "6" +"filesaver.h" "6" +"filetime.cpp" "6" +"filetime.h" "6" +"generateoptions.cpp" "6" +"hostosinfo.h" "6" +"id.cpp" "6" +"id.h" "6" +"installoptions.cpp" "6" +"iosutils.h" "6" +"jsliterals.cpp" "6" +"jsliterals.h" "6" +"launcherinterface.cpp" "6" +"launcherinterface.h" "6" +"launcherpackets.cpp" "6" +"launcherpackets.h" "6" +"launchersocket.cpp" "6" +"launchersocket.h" "6" +"msvcinfo.cpp" "6" +"msvcinfo.h" "6" +"pathutils.h" "6" +"persistence.cpp" "6" +"persistence.h" "6" +"preferences.cpp" "6" +"processresult.cpp" "6" +"processresult_p.h" "6" +"processutils.cpp" "6" +"processutils.h" "6" +"profile.cpp" "6" +"profiling.cpp" "6" +"profiling.h" "6" +"progressobserver.cpp" "6" +"progressobserver.h" "6" +"projectgeneratormanager.cpp" "6" +"qbsassert.cpp" "6" +"qbsassert.h" "6" +"qbspluginmanager.cpp" "6" +"qbspluginmanager.h" "6" +"qbsprocess.cpp" "6" +"qbsprocess.h" "6" +"qttools.cpp" "6" +"qttools.h" "6" +"scannerpluginmanager.cpp" "6" +"scannerpluginmanager.h" "6" +"scripttools.cpp" "6" +"scripttools.h" "6" +"set.h" "6" +"settings.cpp" "6" +"settingscreator.cpp" "6" +"settingscreator.h" "6" +"settingsmodel.cpp" "6" +"settingsrepresentation.cpp" "6" +"settingsrepresentation.h" "6" +"setupprojectparameters.cpp" "6" +"shellutils.cpp" "6" +"shellutils.h" "6" +"stlutils.h" "6" +"stringconstants.h" "6" +"stringutils.h" "6" +"toolchains.cpp" "6" +"version.cpp" "6" +"visualstudioversioninfo.cpp" "6" +"visualstudioversioninfo.h" "6" +"vsenvironmentdetector.cpp" "6" +"vsenvironmentdetector.h" "6" +"weakpointer.h" "6" +"tools (macOS)" "4" +"corelib.qbs:485" "5" +"tools" "5" +"applecodesignutils.cpp" "6" +"applecodesignutils.h" "6" +"use_installed.pri" "4" +"corelib.qbs:494" "5" +"qbs_version.pri" "6" +"use_installed_corelib.pri" "5" "qbsqtprofilesetup" "3" "qtprofilesetup.qbs:3" "4" +"Public API headers" "4" +"qtprofilesetup.qbs:7" "5" +"qtenvironment.h" "5" +"qtmsvctools.h" "5" +"qtprofilesetup.h" "5" +"use_installed_qtprofilesetup.pri" "5" +"templates" "4" +"core.qbs" "5" +"dbus.js" "5" +"dbus.qbs" "5" +"gui.qbs" "5" +"moc.js" "5" +"module.qbs" "5" +"plugin.qbs" "5" +"qdoc.js" "5" +"qml.js" "5" +"qml.qbs" "5" +"qmlcache.qbs" "5" +"QtModule.qbs" "5" +"QtPlugin.qbs" "5" +"quick.js" "5" +"quick.qbs" "5" +"scxml.qbs" "5" +"qtmoduleinfo.cpp" "4" +"qtmoduleinfo.h" "4" +"qtmsvctools.cpp" "4" +"qtprofilesetup.cpp" "4" +"templates.qrc" "4" +"/" "5" +"templates" "6" +"core.qbs" "7" +"dbus.js" "7" +"dbus.qbs" "7" +"gui.qbs" "7" +"moc.js" "7" +"module.qbs" "7" +"plugin.qbs" "7" +"qdoc.js" "7" +"qml.js" "7" +"qml.qbs" "7" +"qmlcache.qbs" "7" +"QtModule.qbs" "7" +"QtPlugin.qbs" "7" +"quick.js" "7" +"quick.qbs" "7" +"scxml.qbs" "7" +"scriptengine" "3" +"scriptengine.qbs:6" "4" +"qbsscriptengine" "4" +"scriptengine.qbs:7" "5" +"api" "5" +"scriptengine.qbs:282" "6" +"bridge" "5" +"scriptengine.qbs:321" "6" +"JavaScriptCore" "5" +"scriptengine.qbs:141" "6" +"parser" "5" +"scriptengine.qbs:343" "6" +"pcre" "5" +"scriptengine.qbs:120" "6" +"system malloc replacement" "5" +"scriptengine.qbs:132" "6" +"QtScriptFwdHeaders" "4" +"scriptengine.qbs:376" "5" +"Group 1" "5" +"scriptengine.qbs:380" "6" "qbs plugins" "2" "plugins.qbs:3" "3" "clangcompilationdbgenerator" "3" "clangcompilationdb.qbs:4" "4" +"clangcompilationdbgenerator.cpp" "4" +"clangcompilationdbgenerator.h" "4" +"clangcompilationdbgeneratorplugin.cpp" "4" +"makefilegenerator" "3" +"makefilegenerator.qbs:4" "4" +"makefilegenerator.cpp" "4" +"makefilegenerator.h" "4" +"makefilegeneratorplugin.cpp" "4" "qbs_cpp_scanner" "3" "cpp.qbs:4" "4" +"scanner.h" "5" +"CPlusPlusForwardDeclarations.h" "4" +"cpp_global.h" "4" +"cppscanner.cpp" "4" +"Lexer.cpp" "4" +"Lexer.h" "4" +"Token.cpp" "4" +"Token.h" "4" "qbs_qt_scanner" "3" "qt.qbs:4" "4" +"scanner.h" "5" +"qtscanner.cpp" "4" "visualstudiogenerator" "3" "visualstudio.qbs:4" "4" +"MSBuild Object Model" "4" +"visualstudio.qbs:49" "5" +"msbuild" "5" +"imsbuildgroup.cpp" "6" +"imsbuildgroup.h" "6" +"imsbuildnode.cpp" "6" +"imsbuildnode.h" "6" +"imsbuildnodevisitor.h" "6" +"imsbuildproperty.cpp" "6" +"imsbuildproperty.h" "6" +"msbuildimport.cpp" "6" +"msbuildimport.h" "6" +"msbuildimportgroup.cpp" "6" +"msbuildimportgroup.h" "6" +"msbuilditem.cpp" "6" +"msbuilditem.h" "6" +"msbuilditemdefinitiongroup.cpp" "6" +"msbuilditemdefinitiongroup.h" "6" +"msbuilditemgroup.cpp" "6" +"msbuilditemgroup.h" "6" +"msbuilditemmetadata.cpp" "6" +"msbuilditemmetadata.h" "6" +"msbuildproject.cpp" "6" +"msbuildproject.h" "6" +"msbuildproperty.cpp" "6" +"msbuildproperty.h" "6" +"msbuildpropertygroup.cpp" "6" +"msbuildpropertygroup.h" "6" +"MSBuild Object Model Items" "4" +"visualstudio.qbs:80" "5" +"msbuildclcompile.cpp" "6" +"msbuildclcompile.h" "6" +"msbuildclinclude.cpp" "6" +"msbuildclinclude.h" "6" +"msbuildfileitem.cpp" "6" +"msbuildfileitem.h" "6" +"msbuildfilter.cpp" "6" +"msbuildfilter.h" "6" +"msbuildlink.cpp" "6" +"msbuildlink.h" "6" +"msbuildnone.cpp" "6" +"msbuildnone.h" "6" +"Solution Object Model" "4" +"visualstudio.qbs:33" "5" +"solution" "5" +"ivisualstudiosolutionproject.cpp" "6" +"ivisualstudiosolutionproject.h" "6" +"visualstudiosolution.cpp" "6" +"visualstudiosolution.h" "6" +"visualstudiosolutionfileproject.cpp" "6" +"visualstudiosolutionfileproject.h" "6" +"visualstudiosolutionfolderproject.cpp" "6" +"visualstudiosolutionfolderproject.h" "6" +"visualstudiosolutionglobalsection.cpp" "6" +"visualstudiosolutionglobalsection.h" "6" +"Visual Studio generator" "4" +"visualstudio.qbs:11" "5" +"msbuildfiltersproject.cpp" "5" +"msbuildfiltersproject.h" "5" +"msbuildqbsgenerateproject.cpp" "5" +"msbuildqbsgenerateproject.h" "5" +"msbuildqbsproductproject.cpp" "5" +"msbuildqbsproductproject.h" "5" +"msbuildsharedsolutionpropertiesproject.cpp" "5" +"msbuildsharedsolutionpropertiesproject.h" "5" +"msbuildsolutionpropertiesproject.cpp" "5" +"msbuildsolutionpropertiesproject.h" "5" +"msbuildtargetproject.cpp" "5" +"msbuildtargetproject.h" "5" +"msbuildutils.h" "5" +"visualstudiogenerator.cpp" "5" +"visualstudiogenerator.h" "5" +"visualstudioguidpool.cpp" "5" +"visualstudioguidpool.h" "5" +"Visual Studio Object Model I/O" "4" +"visualstudio.qbs:98" "5" +"io" "5" +"msbuildprojectwriter.cpp" "6" +"msbuildprojectwriter.h" "6" +"visualstudiosolutionwriter.cpp" "6" +"visualstudiosolutionwriter.h" "6" +"visualstudiogeneratorplugin.cpp" "4" "qbs resources" "2" -"share.qbs:5" "3" +"share.qbs:7" "3" "Examples as resources" "3" -"share.qbs:47" "4" +"share.qbs:58" "4" "app-and-lib" "5" "app" "6" "app.qbs" "7" @@ -11555,6 +13319,13 @@ "mice.qrc" "6" "mouse.cpp" "6" "mouse.h" "6" +"compiled-qml" "5" +"cheese.jpg" "6" +"main.cpp" "6" +"main.qml" "6" +"MainForm.ui.qml" "6" +"myapp.qbs" "6" +"qml.qrc" "6" "helloworld-complex" "5" "src" "6" "foo.cpp" "7" @@ -11586,157 +13357,174 @@ "MainMenu.xib" "6" "Storyboard.storyboard" "6" "examples.qbs" "5" +"Imports" "3" +"share.qbs:40" "4" +"base" "5" +"AndroidApk.qbs" "6" +"AppleApplicationDiskImage.qbs" "6" +"AppleDiskImage.qbs" "6" +"Application.qbs" "6" +"ApplicationExtension.qbs" "6" +"AutotestRunner.qbs" "6" +"CppApplication.qbs" "6" +"DynamicLibrary.qbs" "6" +"InnoSetup.qbs" "6" +"InstallPackage.qbs" "6" +"JavaClassCollection.qbs" "6" +"JavaJarFile.qbs" "6" +"Library.qbs" "6" +"LoadableModule.qbs" "6" +"NativeBinary.qbs" "6" +"NetModule.qbs" "6" +"NodeJSApplication.qbs" "6" +"NSISSetup.qbs" "6" +"QtApplication.qbs" "6" +"QtGuiApplication.qbs" "6" +"StaticLibrary.qbs" "6" +"WindowsInstallerPackage.qbs" "6" +"WindowsSetupPackage.qbs" "6" +"XPCService.qbs" "6" +"BundleTools" "5" +"bundle-tools.js" "6" +"DarwinTools" "5" +"darwin-tools.js" "6" +"ModUtils" "5" +"utils.js" "6" +"PathTools" "5" +"path-tools.js" "6" +"Probes" "5" +"AndroidNdkProbe.qbs" "6" +"AndroidSdkProbe.qbs" "6" +"BinaryProbe.qbs" "6" +"FrameworkProbe.qbs" "6" +"GccBinaryProbe.qbs" "6" +"GccProbe.qbs" "6" +"GccVersionProbe.qbs" "6" +"IcoUtilsVersionProbe.qbs" "6" +"IncludeProbe.qbs" "6" +"InnoSetupProbe.qbs" "6" +"JdkProbe.qbs" "6" +"JdkVersionProbe.qbs" "6" +"MsvcProbe.qbs" "6" +"NodeJsProbe.qbs" "6" +"NpmProbe.qbs" "6" +"path-probe.js" "6" +"PathProbe.qbs" "6" +"PkgConfigProbe.qbs" "6" +"TypeScriptProbe.qbs" "6" +"WiXProbe.qbs" "6" +"XcodeProbe.qbs" "6" +"UnixUtils" "5" +"unix-utils.js" "6" +"WindowsUtils" "5" +"windows-utils.js" "6" "Incredibuild" "3" -"share.qbs:10" "4" +"share.qbs:12" "4" "ibmsvc.xml" "5" "ibqbs.bat" "5" -"Modules and imports" "3" -"share.qbs:38" "4" -"qbs" "4" -"base" "6" -"AndroidApk.qbs" "7" -"AppleApplicationDiskImage.qbs" "7" -"AppleDiskImage.qbs" "7" -"Application.qbs" "7" -"ApplicationExtension.qbs" "7" -"AutotestRunner.qbs" "7" -"CppApplication.qbs" "7" -"DynamicLibrary.qbs" "7" -"InnoSetup.qbs" "7" -"InstallPackage.qbs" "7" -"JavaClassCollection.qbs" "7" -"JavaJarFile.qbs" "7" -"Library.qbs" "7" -"LoadableModule.qbs" "7" -"NativeBinary.qbs" "7" -"NetModule.qbs" "7" -"NodeJSApplication.qbs" "7" -"NSISSetup.qbs" "7" -"QtApplication.qbs" "7" -"QtGuiApplication.qbs" "7" -"StaticLibrary.qbs" "7" -"WindowsInstallerPackage.qbs" "7" -"WindowsSetupPackage.qbs" "7" -"XPCService.qbs" "7" -"BundleTools" "6" -"bundle-tools.js" "7" -"DarwinTools" "6" -"darwin-tools.js" "7" -"ModUtils" "6" +"Modules" "3" +"share.qbs:49" "4" +"Android" "5" +"ndk" "6" +"ndk.qbs" "7" "utils.js" "7" -"PathTools" "6" -"path-tools.js" "7" -"Probes" "6" -"AndroidNdkProbe.qbs" "7" -"AndroidSdkProbe.qbs" "7" -"BinaryProbe.qbs" "7" -"FrameworkProbe.qbs" "7" -"GccProbe.qbs" "7" -"GccVersionProbe.qbs" "7" -"IncludeProbe.qbs" "7" -"InnoSetupProbe.qbs" "7" -"JdkProbe.qbs" "7" -"MsvcProbe.qbs" "7" -"NodeJsProbe.qbs" "7" -"NpmProbe.qbs" "7" -"path-probe.js" "7" -"PathProbe.qbs" "7" -"PkgConfigProbe.qbs" "7" -"TypeScriptProbe.qbs" "7" -"WiXProbe.qbs" "7" -"XcodeProbe.qbs" "7" -"UnixUtils" "6" -"unix-utils.js" "7" -"WindowsUtils" "6" -"windows-utils.js" "7" -"modules" "5" -"Android" "6" -"ndk" "7" -"ndk.qbs" "8" -"utils.js" "8" -"sdk" "7" -"sdk.qbs" "8" -"utils.js" "8" -"archiver" "6" -"archiver.qbs" "7" -"bundle" "6" -"bundle.js" "7" -"BundleModule.qbs" "7" -"MacOSX-Package-Types.xcspec" "7" -"MacOSX-Product-Types.xcspec" "7" -"update-specs.sh" "7" -"cli" "6" -"cli.js" "7" -"CLIModule.qbs" "7" -"mono.qbs" "7" -"windows-dotnet.qbs" "7" -"cpp" "6" -"android-gcc.qbs" "7" -"CppModule.qbs" "7" -"darwin.js" "7" -"DarwinGCC.qbs" "7" -"freebsd-gcc.qbs" "7" -"freebsd.js" "7" -"gcc.js" "7" -"GenericGCC.qbs" "7" -"genericunix-gcc.qbs" "7" -"ios-gcc.qbs" "7" -"LinuxGCC.qbs" "7" -"macos-gcc.qbs" "7" -"msvc.js" "7" -"qnx-qcc.qbs" "7" -"tvos-gcc.qbs" "7" -"UnixGCC.qbs" "7" -"watchos-gcc.qbs" "7" -"windows-mingw.qbs" "7" -"windows-msvc.qbs" "7" -"dmg" "6" -"dmg.js" "7" -"DMGModule.qbs" "7" -"ib" "6" -"ib.js" "7" -"IBModule.qbs" "7" -"innosetup" "6" -"InnoSetupModule.qbs" "7" -"java" "6" -"tools" "8" -"utils" "9" -"JavaCompilerOptions.java" "10" -"JavaCompilerScanner.java" "10" -"NullFileObject.java" "10" -"JavaCompilerScannerTool.java" "9" -"Artifact.java" "8" -"ArtifactListJsonWriter.java" "8" -"ArtifactListWriter.java" "8" -"JavaModule.qbs" "7" +"sdk" "6" +"sdk.qbs" "7" "utils.js" "7" -"lex_yacc" "6" -"lexyacc.js" "7" -"lexyacc.qbs" "7" -"nodejs" "6" -"nodejs.js" "7" -"NodeJS.qbs" "7" -"nsis" "6" -"NSISModule.qbs" "7" +"archiver" "5" +"archiver.qbs" "6" +"bundle" "5" +"bundle.js" "6" +"BundleModule.qbs" "6" +"MacOSX-Package-Types.xcspec" "6" +"MacOSX-Product-Types.xcspec" "6" +"cli" "5" +"cli.js" "6" +"CLIModule.qbs" "6" +"mono.qbs" "6" +"windows-dotnet.qbs" "6" +"cpp" "5" +"android-gcc.qbs" "6" +"cpp.js" "6" +"CppModule.qbs" "6" +"darwin.js" "6" +"DarwinGCC.qbs" "6" +"freebsd-gcc.qbs" "6" +"freebsd.js" "6" +"gcc.js" "6" +"GenericGCC.qbs" "6" +"ios-gcc.qbs" "6" +"LinuxGCC.qbs" "6" +"macos-gcc.qbs" "6" +"msvc.js" "6" +"qnx-qcc.qbs" "6" +"setuprunenv.js" "6" +"tvos-gcc.qbs" "6" +"UnixGCC.qbs" "6" +"watchos-gcc.qbs" "6" +"windows-mingw.qbs" "6" +"windows-msvc.qbs" "6" +"cpufeatures" "5" +"cpufeatures.qbs" "6" +"dmg" "5" +"dmg.js" "6" +"DMGModule.qbs" "6" +"Exporter" "5" +"pkgconfig" "6" +"pkgconfig.js" "7" +"pkgconfig.qbs" "7" "qbs" "6" -"common.qbs" "7" -"qnx" "6" -"qnx.qbs" "7" -"typescript" "6" -"qbs-tsc-scan" "7" -"qbs-tsc-scan.ts" "8" -"typescript.js" "7" -"TypeScriptModule.qbs" "7" -"wix" "6" -"WiXModule.qbs" "7" -"xcode" "6" -"xcode.js" "7" -"xcode.qbs" "7" +"qbsexporter.js" "7" +"qbsexporter.qbs" "7" +"ib" "5" +"ib.js" "6" +"IBModule.qbs" "6" +"ico" "5" +"ico.js" "6" +"IcoModule.qbs" "6" +"innosetup" "5" +"InnoSetupModule.qbs" "6" +"java" "5" +"tools" "7" +"utils" "8" +"JavaCompilerOptions.java" "9" +"JavaCompilerScanner.java" "9" +"NullFileObject.java" "9" +"JavaCompilerScannerTool.java" "8" +"Artifact.java" "7" +"ArtifactListJsonWriter.java" "7" +"ArtifactListWriter.java" "7" +"JavaModule.qbs" "6" +"utils.js" "6" +"lex_yacc" "5" +"lexyacc.js" "6" +"lexyacc.qbs" "6" +"nodejs" "5" +"nodejs.js" "6" +"NodeJS.qbs" "6" +"nsis" "5" +"NSISModule.qbs" "6" +"qbs" "5" +"common.qbs" "6" +"qnx" "5" +"qnx.qbs" "6" +"typescript" "5" +"qbs-tsc-scan" "6" +"qbs-tsc-scan.ts" "7" +"typescript.js" "6" +"TypeScriptModule.qbs" "6" +"vcs" "5" +"vcs-module.qbs" "6" +"wix" "5" +"WiXModule.qbs" "6" +"xcode" "5" +"xcode.js" "6" +"xcode.qbs" "6" "Python executables" "3" -"share.qbs:19" "4" +"share.qbs:21" "4" "dmgbuild" "5" "Python packages" "3" -"share.qbs:28" "4" +"share.qbs:30" "4" "biplist" "5" "__init__.py" "6" "dmgbuild" "5" @@ -11756,6 +13544,10 @@ "bookmark.py" "6" "osx.py" "6" "utils.py" "6" +"qbsjson" "2" +"json.qbs:3" "3" +"json.cpp" "3" +"json.h" "3" "qtcjson" "1" "json.qbs:3" "2" "json.cpp" "2" @@ -11763,22 +13555,22 @@ "qtcreator" "1" "app.qbs:3" "2" "Group 3" "2" -"app.qbs:54" "3" +"app.qbs:58" "3" "qtcreator.rc" "3" "qtcreator.sh" "2" -"app.qbs:66" "3" +"app.qbs:70" "3" "qtcreator.sh" "4" "QtLockedFile_unix" "2" -"app.qbs:74" "3" +"app.qbs:78" "3" "qtlockedfile_unix.cpp" "4" "QtLockedFile_win" "2" -"app.qbs:82" "3" +"app.qbs:86" "3" "qtlockedfile_win.cpp" "4" "standard pch file (gui)" "2" -"QtcProduct.qbs:58" "3" +"QtcProduct.qbs:65" "3" "qtcreator_gui_pch.h" "4" "standard pch file (non-gui)" "2" -"QtcProduct.qbs:50" "3" +"QtcProduct.qbs:57" "3" "qtcreator_pch.h" "4" "shared" "3" "qtlockedfile" "4" @@ -11790,7 +13582,7 @@ "qtsingleapplication.h" "5" "crashhandlersetup.cpp" "4" "crashhandlersetup.h" "4" -"Info.plist" "2" +"app-Info.plist" "2" "main.cpp" "2" "qtcreator.xcassets" "2" "Tools" "1" @@ -11798,23 +13590,254 @@ "buildoutputparser" "2" "buildoutputparser.qbs:3" "3" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" "main.cpp" "3" "outputprocessor.cpp" "3" "outputprocessor.h" "3" "clangbackend" "2" "clangbackend.qbs:3" "3" +"Group 3" "3" +"clangbackend.qbs:9" "4" +"source" "4" +"clangasyncjob.h" "5" +"clangbackend_global.h" "5" +"clangclock.h" "5" +"clangcodecompleteresults.cpp" "5" +"clangcodecompleteresults.h" "5" +"clangcodemodelserver.cpp" "5" +"clangcodemodelserver.h" "5" +"clangcompletecodejob.cpp" "5" +"clangcompletecodejob.h" "5" +"clangdocument.cpp" "5" +"clangdocument.h" "5" +"clangdocumentjob.h" "5" +"clangdocumentprocessor.cpp" "5" +"clangdocumentprocessor.h" "5" +"clangdocumentprocessors.cpp" "5" +"clangdocumentprocessors.h" "5" +"clangdocuments.cpp" "5" +"clangdocuments.h" "5" +"clangdocumentsuspenderresumer.cpp" "5" +"clangdocumentsuspenderresumer.h" "5" +"clangexceptions.cpp" "5" +"clangexceptions.h" "5" +"clangfilepath.cpp" "5" +"clangfilepath.h" "5" +"clangfilesystemwatcher.cpp" "5" +"clangfilesystemwatcher.h" "5" +"clangfollowsymbol.cpp" "5" +"clangfollowsymbol.h" "5" +"clangfollowsymboljob.cpp" "5" +"clangfollowsymboljob.h" "5" +"clangiasyncjob.cpp" "5" +"clangiasyncjob.h" "5" +"clangjobcontext.cpp" "5" +"clangjobcontext.h" "5" +"clangjobqueue.cpp" "5" +"clangjobqueue.h" "5" +"clangjobrequest.cpp" "5" +"clangjobrequest.h" "5" +"clangjobs.cpp" "5" +"clangjobs.h" "5" +"clangparsesupportivetranslationunitjob.cpp" "5" +"clangparsesupportivetranslationunitjob.h" "5" +"clangreferencescollector.cpp" "5" +"clangreferencescollector.h" "5" +"clangrequestannotationsjob.cpp" "5" +"clangrequestannotationsjob.h" "5" +"clangrequestreferencesjob.cpp" "5" +"clangrequestreferencesjob.h" "5" +"clangrequesttooltipjob.cpp" "5" +"clangrequesttooltipjob.h" "5" +"clangresumedocumentjob.cpp" "5" +"clangresumedocumentjob.h" "5" +"clangstring.h" "5" +"clangsupportivetranslationunitinitializer.cpp" "5" +"clangsupportivetranslationunitinitializer.h" "5" +"clangsuspenddocumentjob.cpp" "5" +"clangsuspenddocumentjob.h" "5" +"clangtooltipinfocollector.cpp" "5" +"clangtooltipinfocollector.h" "5" +"clangtranslationunit.cpp" "5" +"clangtranslationunit.h" "5" +"clangtranslationunits.cpp" "5" +"clangtranslationunits.h" "5" +"clangtranslationunitupdater.cpp" "5" +"clangtranslationunitupdater.h" "5" +"clangtype.cpp" "5" +"clangtype.h" "5" +"clangunsavedfilesshallowarguments.cpp" "5" +"clangunsavedfilesshallowarguments.h" "5" +"clangupdateannotationsjob.cpp" "5" +"clangupdateannotationsjob.h" "5" +"clangupdateextraannotationsjob.cpp" "5" +"clangupdateextraannotationsjob.h" "5" +"codecompleter.cpp" "5" +"codecompleter.h" "5" +"codecompletionchunkconverter.cpp" "5" +"codecompletionchunkconverter.h" "5" +"codecompletionsextractor.cpp" "5" +"codecompletionsextractor.h" "5" +"commandlinearguments.cpp" "5" +"commandlinearguments.h" "5" +"cursor.cpp" "5" +"cursor.h" "5" +"diagnostic.cpp" "5" +"diagnostic.h" "5" +"diagnosticset.cpp" "5" +"diagnosticset.h" "5" +"diagnosticsetiterator.h" "5" +"fixit.cpp" "5" +"fixit.h" "5" +"fulltokeninfo.cpp" "5" +"fulltokeninfo.h" "5" +"projectpart.cpp" "5" +"projectpart.h" "5" +"projects.cpp" "5" +"projects.h" "5" +"skippedsourceranges.cpp" "5" +"skippedsourceranges.h" "5" +"sourcelocation.cpp" "5" +"sourcelocation.h" "5" +"sourcerange.cpp" "5" +"sourcerange.h" "5" +"tokeninfo.cpp" "5" +"tokeninfo.h" "5" +"tokenprocessor.h" "5" +"tokenprocessoriterator.h" "5" +"unsavedfile.cpp" "5" +"unsavedfile.h" "5" +"unsavedfiles.cpp" "5" +"unsavedfiles.h" "5" +"utf8positionfromlinecolumn.cpp" "5" +"utf8positionfromlinecolumn.h" "5" +"Group 4" "3" +"clangbackend.qbs:17" "4" +"crashhandlersetup.cpp" "5" +"crashhandlersetup.h" "5" +"standard pch file (gui)" "3" +"QtcProduct.qbs:65" "4" +"qtcreator_gui_pch.h" "5" +"standard pch file (non-gui)" "3" +"QtcProduct.qbs:57" "4" +"qtcreator_pch.h" "5" +"clangbackendmain.cpp" "3" +"clangpchmanagerbackend" "2" +"clangpchmanagerbackend.qbs:4" "3" +"Group 3" "3" +"clangpchmanagerbackend.qbs:36" "4" +"source" "4" +"clangpchmanagerbackend_global.h" "5" +"collectincludesaction.h" "5" +"collectincludespreprocessorcallbacks.h" "5" +"collectincludestoolaction.h" "5" +"environment.h" "5" +"includecollector.cpp" "5" +"includecollector.h" "5" +"pchcreator.cpp" "5" +"pchcreator.h" "5" +"pchcreatorinterface.h" "5" +"pchgenerator.h" "5" +"pchgeneratorinterface.h" "5" +"pchgeneratornotifierinterface.h" "5" +"pchmanagerserver.cpp" "5" +"pchmanagerserver.h" "5" +"pchnotcreatederror.h" "5" +"projectparts.cpp" "5" +"projectparts.h" "5" +"projectpartsinterface.h" "5" +"sources from clangrefactoring" "3" +"clangpchmanagerbackend.qbs:61" "4" +"clangtool.cpp" "5" +"refactoringcompilationdatabase.cpp" "5" +"standard pch file (gui)" "3" +"QtcProduct.qbs:65" "4" +"qtcreator_gui_pch.h" "5" +"standard pch file (non-gui)" "3" +"QtcProduct.qbs:57" "4" +"qtcreator_pch.h" "5" +"clangpchmanagerbackendmain.cpp" "3" +"clangrefactoringbackend" "2" +"clangrefactoringbackend.qbs:4" "3" +"Group 3" "3" +"clangrefactoringbackend.qbs:31" "4" +"source" "4" +"clangquery.cpp" "5" +"clangquery.h" "5" +"clangquerygatherer.cpp" "5" +"clangquerygatherer.h" "5" +"clangrefactoringbackend_global.h" "5" +"clangtool.cpp" "5" +"clangtool.h" "5" +"collectmacrospreprocessorcallbacks.h" "5" +"collectmacrossourcefilecallbacks.cpp" "5" +"collectmacrossourcefilecallbacks.h" "5" +"collectsymbolsaction.cpp" "5" +"collectsymbolsaction.h" "5" +"filestatus.h" "5" +"filestatuscache.cpp" "5" +"filestatuscache.h" "5" +"findcursorusr.h" "5" +"findlocationsofusrs.h" "5" +"findusrforcursoraction.cpp" "5" +"findusrforcursoraction.h" "5" +"indexdataconsumer.cpp" "5" +"indexdataconsumer.h" "5" +"locationsourcefilecallbacks.cpp" "5" +"locationsourcefilecallbacks.h" "5" +"macropreprocessorcallbacks.cpp" "5" +"macropreprocessorcallbacks.h" "5" +"projectpartartefact.cpp" "5" +"projectpartartefact.h" "5" +"projectpartartefactexception.h" "5" +"projectpartentry.h" "5" +"refactoringcompilationdatabase.cpp" "5" +"refactoringcompilationdatabase.h" "5" +"refactoringserver.cpp" "5" +"refactoringserver.h" "5" +"sourcedependency.h" "5" +"sourcelocationentry.h" "5" +"sourcelocationsutils.h" "5" +"sourcerangeextractor.cpp" "5" +"sourcerangeextractor.h" "5" +"sourcerangefilter.cpp" "5" +"sourcerangefilter.h" "5" +"storagesqlitestatementfactory.h" "5" +"symbolentry.h" "5" +"symbolfinder.cpp" "5" +"symbolfinder.h" "5" +"symbolindexer.cpp" "5" +"symbolindexer.h" "5" +"symbolindexing.cpp" "5" +"symbolindexing.h" "5" +"symbolindexinginterface.h" "5" +"symbollocationfinderaction.cpp" "5" +"symbollocationfinderaction.h" "5" +"symbolscollector.cpp" "5" +"symbolscollector.h" "5" +"symbolscollectorinterface.h" "5" +"symbolstorage.h" "5" +"symbolstorageinterface.h" "5" +"symbolsvisitorbase.h" "5" +"usedmacro.h" "5" +"standard pch file (gui)" "3" +"QtcProduct.qbs:65" "4" +"qtcreator_gui_pch.h" "5" +"standard pch file (non-gui)" "3" +"QtcProduct.qbs:57" "4" +"qtcreator_pch.h" "5" +"clangrefactoringbackendmain.cpp" "3" "iostool" "2" "iostool.qbs:3" "3" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" "Info.plist" "3" "iosdevicemanager.cpp" "3" @@ -11990,18 +14013,18 @@ "qml2puppet.qbs:129" "4" "sharedmemory_unix.cpp" "5" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" "qtcdebugger" "2" "qtcdebugger.qbs:3" "3" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" "registryaccess.cpp" "4" "registryaccess.h" "4" @@ -12021,27 +14044,27 @@ "utils.cpp" "4" "utils.h" "4" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" "qtpromaker" "2" "qtpromaker.qbs:3" "3" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" "main.cpp" "3" "sdktool" "2" "sdktool.qbs:3" "3" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" "Utils" "3" "sdktool.qbs:64" "4" @@ -12100,16 +14123,22 @@ "settings.h" "3" "valgrind-fake" "2" "valgrindfake.qbs:4" "3" +"standard pch file (gui)" "3" +"QtcProduct.qbs:65" "4" +"qtcreator_gui_pch.h" "5" +"standard pch file (non-gui)" "3" +"QtcProduct.qbs:57" "4" +"qtcreator_pch.h" "5" "main.cpp" "3" "outputgenerator.cpp" "3" "outputgenerator.h" "3" "winrtdebughelper" "2" "winrtdebughelper.qbs:3" "3" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" "winrtdebughelper.cpp" "3" "Tests" "0" @@ -12119,60 +14148,30 @@ "Aggregation autotest" "2" "aggregation.qbs:3" "3" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" "tst_aggregate.cpp" "3" "Algorithm autotest" "2" "algorithm.qbs:3" "3" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" "tst_algorithm.cpp" "3" "ChangeSet autotest" "2" "changeset.qbs:3" "3" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" "tst_changeset.cpp" "3" -"ClangStaticAnalyzer autotests" "2" -"clangstaticanalyzer.qbs:3" "3" -"ClangStaticAnalyzerLogFileReader Autotest" "3" -"clangstaticanalyzerlogfilereader.qbs:4" "4" -"sources from plugin" "4" -"clangstaticanalyzerlogfilereader.qbs:8" "5" -"clangstaticanalyzerdiagnostic.cpp" "6" -"clangstaticanalyzerdiagnostic.h" "6" -"clangstaticanalyzerlogfilereader.cpp" "6" -"clangstaticanalyzerlogfilereader.h" "6" -"standard pch file (gui)" "4" -"QtcProduct.qbs:58" "5" -"qtcreator_gui_pch.h" "6" -"standard pch file (non-gui)" "4" -"QtcProduct.qbs:50" "5" -"qtcreator_pch.h" "6" -"tst_clangstaticanalyzerlogfilereader.cpp" "4" -"ClangStaticAnalyzerRunner Autotest" "3" -"clangstaticanalyzerrunner.qbs:4" "4" -"sources from plugin" "4" -"clangstaticanalyzerrunner.qbs:7" "5" -"clangstaticanalyzerrunner.cpp" "6" -"clangstaticanalyzerrunner.h" "6" -"standard pch file (gui)" "4" -"QtcProduct.qbs:58" "5" -"qtcreator_gui_pch.h" "6" -"standard pch file (non-gui)" "4" -"QtcProduct.qbs:50" "5" -"qtcreator_pch.h" "6" -"tst_clangstaticanalyzerrunner.cpp" "4" "CPlusPlus autotests" "2" "cplusplus.qbs:3" "3" "C99 autotest" "3" @@ -12185,84 +14184,84 @@ "c99.qbs:6" "5" "tst_c99.cpp" "5" "standard pch file (gui)" "4" -"QtcProduct.qbs:58" "5" +"QtcProduct.qbs:65" "5" "qtcreator_gui_pch.h" "6" "standard pch file (non-gui)" "4" -"QtcProduct.qbs:50" "5" +"QtcProduct.qbs:57" "5" "qtcreator_pch.h" "6" "CPlusPlus AST autotest" "3" "ast.qbs:4" "4" "standard pch file (gui)" "4" -"QtcProduct.qbs:58" "5" +"QtcProduct.qbs:65" "5" "qtcreator_gui_pch.h" "6" "standard pch file (non-gui)" "4" -"QtcProduct.qbs:50" "5" +"QtcProduct.qbs:57" "5" "qtcreator_pch.h" "6" "tst_ast.cpp" "4" "CPlusPlus check symbols autotest" "3" "checksymbols.qbs:4" "4" "standard pch file (gui)" "4" -"QtcProduct.qbs:58" "5" +"QtcProduct.qbs:65" "5" "qtcreator_gui_pch.h" "6" "standard pch file (non-gui)" "4" -"QtcProduct.qbs:50" "5" +"QtcProduct.qbs:57" "5" "qtcreator_pch.h" "6" "cplusplus_global.h" "5" "tst_checksymbols.cpp" "4" "CPlusPlus code formatter autotest" "3" "codeformatter.qbs:4" "4" "standard pch file (gui)" "4" -"QtcProduct.qbs:58" "5" +"QtcProduct.qbs:65" "5" "qtcreator_gui_pch.h" "6" "standard pch file (non-gui)" "4" -"QtcProduct.qbs:50" "5" +"QtcProduct.qbs:57" "5" "qtcreator_pch.h" "6" "tst_codeformatter.cpp" "4" "CPlusPlus fileiterationorder autotest" "3" "fileiterationorder.qbs:4" "4" "standard pch file (gui)" "4" -"QtcProduct.qbs:58" "5" +"QtcProduct.qbs:65" "5" "qtcreator_gui_pch.h" "6" "standard pch file (non-gui)" "4" -"QtcProduct.qbs:50" "5" +"QtcProduct.qbs:57" "5" "qtcreator_pch.h" "6" "tst_fileiterationorder.cpp" "4" "CPlusPlus find usages autotest" "3" "findusages.qbs:4" "4" "standard pch file (gui)" "4" -"QtcProduct.qbs:58" "5" +"QtcProduct.qbs:65" "5" "qtcreator_gui_pch.h" "6" "standard pch file (non-gui)" "4" -"QtcProduct.qbs:50" "5" +"QtcProduct.qbs:57" "5" "qtcreator_pch.h" "6" "cplusplus_global.h" "5" "tst_findusages.cpp" "4" "CPlusPlus lexer autotest" "3" "lexer.qbs:4" "4" "standard pch file (gui)" "4" -"QtcProduct.qbs:58" "5" +"QtcProduct.qbs:65" "5" "qtcreator_gui_pch.h" "6" "standard pch file (non-gui)" "4" -"QtcProduct.qbs:50" "5" +"QtcProduct.qbs:57" "5" "qtcreator_pch.h" "6" "cplusplus_global.h" "5" "tst_lexer.cpp" "4" "CPlusPlus lookup autotest" "3" "lookup.qbs:4" "4" "standard pch file (gui)" "4" -"QtcProduct.qbs:58" "5" +"QtcProduct.qbs:65" "5" "qtcreator_gui_pch.h" "6" "standard pch file (non-gui)" "4" -"QtcProduct.qbs:50" "5" +"QtcProduct.qbs:57" "5" "qtcreator_pch.h" "6" "tst_lookup.cpp" "4" "CPlusPlus miscellaneous autotest" "3" "misc.qbs:4" "4" "standard pch file (gui)" "4" -"QtcProduct.qbs:58" "5" +"QtcProduct.qbs:65" "5" "qtcreator_gui_pch.h" "6" "standard pch file (non-gui)" "4" -"QtcProduct.qbs:50" "5" +"QtcProduct.qbs:57" "5" "qtcreator_pch.h" "6" "tst_misc.cpp" "4" "CPlusPlus preprocessor autotest" "3" @@ -12303,18 +14302,18 @@ "preprocessor.qbs:6" "5" "tst_preprocessor.cpp" "5" "standard pch file (gui)" "4" -"QtcProduct.qbs:58" "5" +"QtcProduct.qbs:65" "5" "qtcreator_gui_pch.h" "6" "standard pch file (non-gui)" "4" -"QtcProduct.qbs:50" "5" +"QtcProduct.qbs:57" "5" "qtcreator_pch.h" "6" "CPlusPlus pretty printer autotest" "3" "typeprettyprinter.qbs:4" "4" "standard pch file (gui)" "4" -"QtcProduct.qbs:58" "5" +"QtcProduct.qbs:65" "5" "qtcreator_gui_pch.h" "6" "standard pch file (non-gui)" "4" -"QtcProduct.qbs:50" "5" +"QtcProduct.qbs:57" "5" "qtcreator_pch.h" "6" "tst_typeprettyprinter.cpp" "4" "CPlusPlus selection changer autotest" "3" @@ -12326,27 +14325,27 @@ "cppselectionchanger.qbs:7" "5" "tst_cppselectionchangertest.cpp" "5" "standard pch file (gui)" "4" -"QtcProduct.qbs:58" "5" +"QtcProduct.qbs:65" "5" "qtcreator_gui_pch.h" "6" "standard pch file (non-gui)" "4" -"QtcProduct.qbs:50" "5" +"QtcProduct.qbs:57" "5" "qtcreator_pch.h" "6" "CPlusPlus semantic autotest" "3" "semantic.qbs:4" "4" "standard pch file (gui)" "4" -"QtcProduct.qbs:58" "5" +"QtcProduct.qbs:65" "5" "qtcreator_gui_pch.h" "6" "standard pch file (non-gui)" "4" -"QtcProduct.qbs:50" "5" +"QtcProduct.qbs:57" "5" "qtcreator_pch.h" "6" "tst_semantic.cpp" "4" "CPlusPlus translation unit autotest" "3" "translationunit.qbs:4" "4" "standard pch file (gui)" "4" -"QtcProduct.qbs:58" "5" +"QtcProduct.qbs:65" "5" "qtcreator_gui_pch.h" "6" "standard pch file (non-gui)" "4" -"QtcProduct.qbs:50" "5" +"QtcProduct.qbs:57" "5" "qtcreator_pch.h" "6" "cplusplus_global.h" "5" "tst_translationunit.cpp" "4" @@ -12365,10 +14364,10 @@ "cxx11.qbs:6" "5" "tst_cxx11.cpp" "5" "standard pch file (gui)" "4" -"QtcProduct.qbs:58" "5" +"QtcProduct.qbs:65" "5" "qtcreator_gui_pch.h" "6" "standard pch file (non-gui)" "4" -"QtcProduct.qbs:50" "5" +"QtcProduct.qbs:57" "5" "qtcreator_pch.h" "6" "Debugger autotests" "2" "debugger.qbs:3" "3" @@ -12385,10 +14384,10 @@ "watchutils.cpp" "6" "watchutils.h" "6" "standard pch file (gui)" "4" -"QtcProduct.qbs:58" "5" +"QtcProduct.qbs:65" "5" "qtcreator_gui_pch.h" "6" "standard pch file (non-gui)" "4" -"QtcProduct.qbs:50" "5" +"QtcProduct.qbs:57" "5" "qtcreator_pch.h" "6" "Test sources" "4" "dumpers.qbs:19" "5" @@ -12399,10 +14398,10 @@ "disassembler.qbs:5" "5" "disassemblerlines.cpp" "6" "standard pch file (gui)" "4" -"QtcProduct.qbs:58" "5" +"QtcProduct.qbs:65" "5" "qtcreator_gui_pch.h" "6" "standard pch file (non-gui)" "4" -"QtcProduct.qbs:50" "5" +"QtcProduct.qbs:57" "5" "qtcreator_pch.h" "6" "Test sources" "4" "disassembler.qbs:10" "5" @@ -12413,10 +14412,10 @@ "gdb.qbs:7" "5" "debuggerprotocol.cpp" "6" "standard pch file (gui)" "4" -"QtcProduct.qbs:58" "5" +"QtcProduct.qbs:65" "5" "qtcreator_gui_pch.h" "6" "standard pch file (non-gui)" "4" -"QtcProduct.qbs:50" "5" +"QtcProduct.qbs:57" "5" "qtcreator_pch.h" "6" "Test sources" "4" "gdb.qbs:12" "5" @@ -12433,10 +14432,10 @@ "parsetreenodes.cpp" "6" "parsetreenodes.h" "6" "standard pch file (gui)" "4" -"QtcProduct.qbs:58" "5" +"QtcProduct.qbs:65" "5" "qtcreator_gui_pch.h" "6" "standard pch file (non-gui)" "4" -"QtcProduct.qbs:50" "5" +"QtcProduct.qbs:57" "5" "qtcreator_pch.h" "6" "Test sources" "4" "namedemangler.qbs:13" "5" @@ -12444,10 +14443,10 @@ "offsets autotest" "3" "offsets.qbs:3" "4" "standard pch file (gui)" "4" -"QtcProduct.qbs:58" "5" +"QtcProduct.qbs:65" "5" "qtcreator_gui_pch.h" "6" "standard pch file (non-gui)" "4" -"QtcProduct.qbs:50" "5" +"QtcProduct.qbs:57" "5" "qtcreator_pch.h" "6" "Test sources" "4" "offsets.qbs:6" "5" @@ -12458,10 +14457,10 @@ "simplifytypes.qbs:6" "5" "simplifytype.cpp" "6" "standard pch file (gui)" "4" -"QtcProduct.qbs:58" "5" +"QtcProduct.qbs:65" "5" "qtcreator_gui_pch.h" "6" "standard pch file (non-gui)" "4" -"QtcProduct.qbs:50" "5" +"QtcProduct.qbs:57" "5" "qtcreator_pch.h" "6" "Test sources" "4" "simplifytypes.qbs:11" "5" @@ -12471,19 +14470,19 @@ "Differ autotest" "3" "differ.qbs:3" "4" "standard pch file (gui)" "4" -"QtcProduct.qbs:58" "5" +"QtcProduct.qbs:65" "5" "qtcreator_gui_pch.h" "6" "standard pch file (non-gui)" "4" -"QtcProduct.qbs:50" "5" +"QtcProduct.qbs:57" "5" "qtcreator_pch.h" "6" "tst_differ.cpp" "4" "Environment autotest" "2" "environment.qbs:3" "3" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" "tst_environment.cpp" "3" "ExtensionSystem autotests" "2" @@ -12500,10 +14499,10 @@ "testdir" "6" "spec.json" "7" "standard pch file (gui)" "5" -"QtcProduct.qbs:58" "6" +"QtcProduct.qbs:65" "6" "qtcreator_gui_pch.h" "7" "standard pch file (non-gui)" "5" -"QtcProduct.qbs:50" "6" +"QtcProduct.qbs:57" "6" "qtcreator_pch.h" "7" "test dependencies" "5" "test.qbs:30" "6" @@ -12562,10 +14561,10 @@ "PluginManager autotest" "4" "test.qbs:3" "5" "standard pch file (gui)" "5" -"QtcProduct.qbs:58" "6" +"QtcProduct.qbs:65" "6" "qtcreator_gui_pch.h" "7" "standard pch file (non-gui)" "5" -"QtcProduct.qbs:50" "6" +"QtcProduct.qbs:57" "6" "qtcreator_pch.h" "7" "tst_pluginmanager.cpp" "5" "ExternalTool autotest" "2" @@ -12575,10 +14574,10 @@ "externaltool.cpp" "5" "externaltool.h" "5" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" "Test sources" "3" "externaltool.qbs:17" "4" @@ -12586,25 +14585,16 @@ "File search autotest" "2" "filesearch.qbs:3" "3" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" "testfile.txt" "3" "tst_filesearch.cpp" "3" "tst_filesearch.qrc" "3" "/tst_filesearch" "4" "testfile.txt" "5" -"FlameGraph autotest" "2" -"flamegraph.qbs:3" "3" -"standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" -"qtcreator_gui_pch.h" "5" -"standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" -"qtcreator_pch.h" "5" -"tst_flamegraph.cpp" "3" "Generic highlighter autotests" "2" "generichighlighter.qbs:3" "3" "Generic highlighter specific rules autotest" "3" @@ -12620,10 +14610,10 @@ "rule.cpp" "6" "specificrules.cpp" "6" "standard pch file (gui)" "4" -"QtcProduct.qbs:58" "5" +"QtcProduct.qbs:65" "5" "qtcreator_gui_pch.h" "6" "standard pch file (non-gui)" "4" -"QtcProduct.qbs:50" "5" +"QtcProduct.qbs:57" "5" "qtcreator_pch.h" "6" "Test sources" "4" "specificrules.qbs:20" "5" @@ -12658,10 +14648,10 @@ "specificrules.cpp" "6" "specificrules.h" "6" "standard pch file (gui)" "4" -"QtcProduct.qbs:58" "5" +"QtcProduct.qbs:65" "5" "qtcreator_gui_pch.h" "6" "standard pch file (non-gui)" "4" -"QtcProduct.qbs:50" "5" +"QtcProduct.qbs:57" "5" "qtcreator_pch.h" "6" "Test sources" "4" "highlighterengine.qbs:23" "5" @@ -12673,13 +14663,13 @@ "json autotest" "2" "json.qbs:3" "3" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" "test data" "3" -"json.qbs:10" "4" +"json.qbs:15" "4" "bom.json" "4" "test.bjson" "4" "test.json" "4" @@ -12710,10 +14700,10 @@ "qmakevfs.cpp" "5" "qmakevfs.h" "5" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" "Test sources" "3" "profilewriter.qbs:23" "4" @@ -12725,28 +14715,28 @@ "QML code model check autotest" "4" "check.qbs:3" "5" "standard pch file (gui)" "5" -"QtcProduct.qbs:58" "6" +"QtcProduct.qbs:65" "6" "qtcreator_gui_pch.h" "7" "standard pch file (non-gui)" "5" -"QtcProduct.qbs:50" "6" +"QtcProduct.qbs:57" "6" "qtcreator_pch.h" "7" "tst_check.cpp" "5" "QML code model dependencies autotest" "4" "dependencies.qbs:3" "5" "standard pch file (gui)" "5" -"QtcProduct.qbs:58" "6" +"QtcProduct.qbs:65" "6" "qtcreator_gui_pch.h" "7" "standard pch file (non-gui)" "5" -"QtcProduct.qbs:50" "6" +"QtcProduct.qbs:57" "6" "qtcreator_pch.h" "7" "tst_dependencies.cpp" "5" "QML code model imports check autotest" "4" "importscheck.qbs:3" "5" "standard pch file (gui)" "5" -"QtcProduct.qbs:58" "6" +"QtcProduct.qbs:65" "6" "qtcreator_gui_pch.h" "7" "standard pch file (non-gui)" "5" -"QtcProduct.qbs:50" "6" +"QtcProduct.qbs:57" "6" "qtcreator_pch.h" "7" "tst_importscheck.cpp" "5" "QML editor autotests" "3" @@ -12754,47 +14744,47 @@ "QML code formatter autotest" "4" "qmlcodeformatter.qbs:3" "5" "standard pch file (gui)" "5" -"QtcProduct.qbs:58" "6" +"QtcProduct.qbs:65" "6" "qtcreator_gui_pch.h" "7" "standard pch file (non-gui)" "5" -"QtcProduct.qbs:50" "6" +"QtcProduct.qbs:57" "6" "qtcreator_pch.h" "7" "tst_qmlcodeformatter.cpp" "5" "QML persistenttrie autotest" "3" "persistenttrie.qbs:3" "4" "standard pch file (gui)" "4" -"QtcProduct.qbs:58" "5" +"QtcProduct.qbs:65" "5" "qtcreator_gui_pch.h" "6" "standard pch file (non-gui)" "4" -"QtcProduct.qbs:50" "5" +"QtcProduct.qbs:57" "5" "qtcreator_pch.h" "6" "tst_testtrie.cpp" "4" "tst_testtrie.h" "4" "QML qrc parser autotest" "3" "qrcparser.qbs:3" "4" "standard pch file (gui)" "4" -"QtcProduct.qbs:58" "5" +"QtcProduct.qbs:65" "5" "qtcreator_gui_pch.h" "6" "standard pch file (non-gui)" "4" -"QtcProduct.qbs:50" "5" +"QtcProduct.qbs:57" "5" "qtcreator_pch.h" "6" "tst_qrcparser.cpp" "4" "QML reformatter autotest" "3" "reformatter.qbs:3" "4" "standard pch file (gui)" "4" -"QtcProduct.qbs:58" "5" +"QtcProduct.qbs:65" "5" "qtcreator_gui_pch.h" "6" "standard pch file (non-gui)" "4" -"QtcProduct.qbs:50" "5" +"QtcProduct.qbs:57" "5" "qtcreator_pch.h" "6" "tst_reformatter.cpp" "4" "QMLJS simple reader autotest" "3" "qmljssimplereader.qbs:3" "4" "standard pch file (gui)" "4" -"QtcProduct.qbs:58" "5" +"QtcProduct.qbs:65" "5" "qtcreator_gui_pch.h" "6" "standard pch file (non-gui)" "4" -"QtcProduct.qbs:50" "5" +"QtcProduct.qbs:57" "5" "qtcreator_pch.h" "6" "tst_qmljssimplereader.cpp" "4" "QmlProjectManager autotests" "3" @@ -12810,50 +14800,72 @@ "qmlprojectitem.cpp" "7" "qmlprojectitem.h" "7" "standard pch file (gui)" "5" -"QtcProduct.qbs:58" "6" +"QtcProduct.qbs:65" "6" "qtcreator_gui_pch.h" "7" "standard pch file (non-gui)" "5" -"QtcProduct.qbs:50" "6" +"QtcProduct.qbs:57" "6" "qtcreator_pch.h" "7" "tst_fileformat.cpp" "5" "QtcProcess autotest" "2" "qtcprocess.qbs:3" "3" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" "tst_qtcprocess.cpp" "3" "Run extensions autotest" "2" "runextensions.qbs:3" "3" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" "tst_runextensions.cpp" "3" "sdktool autotest" "2" "sdktool.qbs:3" "3" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" "Test sources" "3" "sdktool.qbs:6" "4" "tst_sdktool.cpp" "4" -"Timeline autotests" "2" -"timeline.qbs:3" "3" +"ToolChainCache autotest" "2" +"toolchaincache.qbs:3" "3" +"standard pch file (gui)" "3" +"QtcProduct.qbs:65" "4" +"qtcreator_gui_pch.h" "5" +"standard pch file (non-gui)" "3" +"QtcProduct.qbs:57" "4" +"qtcreator_pch.h" "5" +"Test sources" "3" +"toolchaincache.qbs:6" "4" +"tst_toolchaincache.cpp" "4" +"Tracing autotests" "2" +"tracing.qbs:3" "3" +"FlameGraph autotest" "3" +"flamegraph.qbs:4" "4" +"standard pch file (gui)" "4" +"QtcProduct.qbs:65" "5" +"qtcreator_gui_pch.h" "6" +"standard pch file (non-gui)" "4" +"QtcProduct.qbs:57" "5" +"qtcreator_pch.h" "6" +"Test sources" "4" +"flamegraph.qbs:6" "5" +"tst_flamegraph.cpp" "5" "TimelineAbstractRenderer autotest" "3" "timelineabstractrenderer.qbs:4" "4" "standard pch file (gui)" "4" -"QtcProduct.qbs:58" "5" +"QtcProduct.qbs:65" "5" "qtcreator_gui_pch.h" "6" "standard pch file (non-gui)" "4" -"QtcProduct.qbs:50" "5" +"QtcProduct.qbs:57" "5" "qtcreator_pch.h" "6" "Test sources" "4" "timelineabstractrenderer.qbs:6" "5" @@ -12861,10 +14873,10 @@ "TimelineItemsRenderPass autotest" "3" "timelineitemsrenderpass.qbs:5" "4" "standard pch file (gui)" "4" -"QtcProduct.qbs:58" "5" +"QtcProduct.qbs:65" "5" "qtcreator_gui_pch.h" "6" "standard pch file (non-gui)" "4" -"QtcProduct.qbs:50" "5" +"QtcProduct.qbs:57" "5" "qtcreator_pch.h" "6" "Test sources" "4" "timelineitemsrenderpass.qbs:7" "5" @@ -12872,10 +14884,10 @@ "TimelineModel autotest" "3" "timelinemodel.qbs:4" "4" "standard pch file (gui)" "4" -"QtcProduct.qbs:58" "5" +"QtcProduct.qbs:65" "5" "qtcreator_gui_pch.h" "6" "standard pch file (non-gui)" "4" -"QtcProduct.qbs:50" "5" +"QtcProduct.qbs:57" "5" "qtcreator_pch.h" "6" "Test sources" "4" "timelinemodel.qbs:6" "5" @@ -12883,10 +14895,10 @@ "TimelineModelAggregator autotest" "3" "timelinemodelaggregator.qbs:4" "4" "standard pch file (gui)" "4" -"QtcProduct.qbs:58" "5" +"QtcProduct.qbs:65" "5" "qtcreator_gui_pch.h" "6" "standard pch file (non-gui)" "4" -"QtcProduct.qbs:50" "5" +"QtcProduct.qbs:57" "5" "qtcreator_pch.h" "6" "Test sources" "4" "timelinemodelaggregator.qbs:6" "5" @@ -12894,10 +14906,10 @@ "TimelineNotesModel autotest" "3" "timelinenotesmodel.qbs:4" "4" "standard pch file (gui)" "4" -"QtcProduct.qbs:58" "5" +"QtcProduct.qbs:65" "5" "qtcreator_gui_pch.h" "6" "standard pch file (non-gui)" "4" -"QtcProduct.qbs:50" "5" +"QtcProduct.qbs:57" "5" "qtcreator_pch.h" "6" "Test sources" "4" "timelinenotesmodel.qbs:6" "5" @@ -12905,10 +14917,10 @@ "TimelineNotesRenderPass autotest" "3" "timelinenotesrenderpass.qbs:5" "4" "standard pch file (gui)" "4" -"QtcProduct.qbs:58" "5" +"QtcProduct.qbs:65" "5" "qtcreator_gui_pch.h" "6" "standard pch file (non-gui)" "4" -"QtcProduct.qbs:50" "5" +"QtcProduct.qbs:57" "5" "qtcreator_pch.h" "6" "Test sources" "4" "timelinenotesrenderpass.qbs:7" "5" @@ -12916,10 +14928,10 @@ "TimelineOverviewRenderer autotest" "3" "timelineoverviewrenderer.qbs:4" "4" "standard pch file (gui)" "4" -"QtcProduct.qbs:58" "5" +"QtcProduct.qbs:65" "5" "qtcreator_gui_pch.h" "6" "standard pch file (non-gui)" "4" -"QtcProduct.qbs:50" "5" +"QtcProduct.qbs:57" "5" "qtcreator_pch.h" "6" "Test sources" "4" "timelineoverviewrenderer.qbs:6" "5" @@ -12927,10 +14939,10 @@ "TimelineRenderer autotest" "3" "timelinerenderer.qbs:4" "4" "standard pch file (gui)" "4" -"QtcProduct.qbs:58" "5" +"QtcProduct.qbs:65" "5" "qtcreator_gui_pch.h" "6" "standard pch file (non-gui)" "4" -"QtcProduct.qbs:50" "5" +"QtcProduct.qbs:57" "5" "qtcreator_pch.h" "6" "Test sources" "4" "timelinerenderer.qbs:6" "5" @@ -12938,10 +14950,10 @@ "TimelineRenderPass autotest" "3" "timelinerenderpass.qbs:5" "4" "standard pch file (gui)" "4" -"QtcProduct.qbs:58" "5" +"QtcProduct.qbs:65" "5" "qtcreator_gui_pch.h" "6" "standard pch file (non-gui)" "4" -"QtcProduct.qbs:50" "5" +"QtcProduct.qbs:57" "5" "qtcreator_pch.h" "6" "Test sources" "4" "timelinerenderpass.qbs:7" "5" @@ -12949,10 +14961,10 @@ "TimelineRenderState autotest" "3" "timelinerenderstate.qbs:5" "4" "standard pch file (gui)" "4" -"QtcProduct.qbs:58" "5" +"QtcProduct.qbs:65" "5" "qtcreator_gui_pch.h" "6" "standard pch file (non-gui)" "4" -"QtcProduct.qbs:50" "5" +"QtcProduct.qbs:57" "5" "qtcreator_pch.h" "6" "Test sources" "4" "timelinerenderstate.qbs:7" "5" @@ -12960,10 +14972,10 @@ "TimelineSelectionRenderPass autotest" "3" "timelineselectionrenderpass.qbs:5" "4" "standard pch file (gui)" "4" -"QtcProduct.qbs:58" "5" +"QtcProduct.qbs:65" "5" "qtcreator_gui_pch.h" "6" "standard pch file (non-gui)" "4" -"QtcProduct.qbs:50" "5" +"QtcProduct.qbs:57" "5" "qtcreator_pch.h" "6" "Test sources" "4" "timelineselectionrenderpass.qbs:7" "5" @@ -12971,10 +14983,10 @@ "TimelineZoomcontrol autotest" "3" "timelinezoomcontrol.qbs:4" "4" "standard pch file (gui)" "4" -"QtcProduct.qbs:58" "5" +"QtcProduct.qbs:65" "5" "qtcreator_gui_pch.h" "6" "standard pch file (non-gui)" "4" -"QtcProduct.qbs:50" "5" +"QtcProduct.qbs:57" "5" "qtcreator_pch.h" "6" "Test sources" "4" "timelinezoomcontrol.qbs:6" "5" @@ -12982,10 +14994,10 @@ "TreeViewFind autotest" "2" "treeviewfind.qbs:3" "3" "standard pch file (gui)" "3" -"QtcProduct.qbs:58" "4" +"QtcProduct.qbs:65" "4" "qtcreator_gui_pch.h" "5" "standard pch file (non-gui)" "3" -"QtcProduct.qbs:50" "4" +"QtcProduct.qbs:57" "4" "qtcreator_pch.h" "5" "tst_treeviewfind.cpp" "3" "Utils autotests" "2" @@ -12993,55 +15005,64 @@ "ANSI autotest" "3" "ansiescapecodehandler.qbs:3" "4" "standard pch file (gui)" "4" -"QtcProduct.qbs:58" "5" +"QtcProduct.qbs:65" "5" "qtcreator_gui_pch.h" "6" "standard pch file (non-gui)" "4" -"QtcProduct.qbs:50" "5" +"QtcProduct.qbs:57" "5" "qtcreator_pch.h" "6" "tst_ansiescapecodehandler.cpp" "4" "FileUtils autotest" "3" "fileutils.qbs:3" "4" "standard pch file (gui)" "4" -"QtcProduct.qbs:58" "5" +"QtcProduct.qbs:65" "5" "qtcreator_gui_pch.h" "6" "standard pch file (non-gui)" "4" -"QtcProduct.qbs:50" "5" +"QtcProduct.qbs:57" "5" "qtcreator_pch.h" "6" "tst_fileutils.cpp" "4" -"ObjectPool autotest" "3" -"objectpool.qbs:3" "4" +"FuzzyMatcher autotest" "3" +"fuzzymatcher.qbs:3" "4" +"standard pch file (gui)" "4" +"QtcProduct.qbs:65" "5" +"qtcreator_gui_pch.h" "6" +"standard pch file (non-gui)" "4" +"QtcProduct.qbs:57" "5" +"qtcreator_pch.h" "6" +"tst_fuzzymatcher.cpp" "4" +"Settings autotest" "3" +"settings.qbs:3" "4" "standard pch file (gui)" "4" -"QtcProduct.qbs:58" "5" +"QtcProduct.qbs:65" "5" "qtcreator_gui_pch.h" "6" "standard pch file (non-gui)" "4" -"QtcProduct.qbs:50" "5" +"QtcProduct.qbs:57" "5" "qtcreator_pch.h" "6" -"tst_objectpool.cpp" "4" +"tst_settings.cpp" "4" "StringUtils autotest" "3" "stringutils.qbs:3" "4" "standard pch file (gui)" "4" -"QtcProduct.qbs:58" "5" +"QtcProduct.qbs:65" "5" "qtcreator_gui_pch.h" "6" "standard pch file (non-gui)" "4" -"QtcProduct.qbs:50" "5" +"QtcProduct.qbs:57" "5" "qtcreator_pch.h" "6" "tst_stringutils.cpp" "4" "TemplateEngine autotest" "3" "templateengine.qbs:3" "4" "standard pch file (gui)" "4" -"QtcProduct.qbs:58" "5" +"QtcProduct.qbs:65" "5" "qtcreator_gui_pch.h" "6" "standard pch file (non-gui)" "4" -"QtcProduct.qbs:50" "5" +"QtcProduct.qbs:57" "5" "qtcreator_pch.h" "6" "tst_templateengine.cpp" "4" "TreeModel autotest" "3" "treemodel.qbs:3" "4" "standard pch file (gui)" "4" -"QtcProduct.qbs:58" "5" +"QtcProduct.qbs:65" "5" "qtcreator_gui_pch.h" "6" "standard pch file (non-gui)" "4" -"QtcProduct.qbs:50" "5" +"QtcProduct.qbs:57" "5" "qtcreator_pch.h" "6" "tst_treemodel.cpp" "4" "Translations" "0" @@ -13093,11 +15114,9 @@ "qbsplugin.qbs" "4" "tools" "2" "cplusplustools.qbs" "3" -"clangstaticanalyzer" "2" -"clangstaticanalyzerautotest.qbs" "3" "cplusplus" "2" "cplusplusautotest.qbs" "3" "extensionsystem" "2" "plugin.qbs" "3" -"timeline" "2" -"timelineautotest.qbs" "3" +"tracing" "2" +"tracingautotest.qbs" "3" diff --git a/tests/system/suite_general/tst_openqt_creator/test.py b/tests/system/suite_general/tst_openqt_creator/test.py index 1c20800fe5..5f7b0f3b01 100644 --- a/tests/system/suite_general/tst_openqt_creator/test.py +++ b/tests/system/suite_general/tst_openqt_creator/test.py @@ -66,7 +66,7 @@ def main(): generalMessages = str(waitForObject(":Qt Creator_Core::OutputWindow").plainText) test.compare(generalMessages.count("Project MESSAGE: Cannot build Qt Creator with Qt version 5.6.1."), 1, "Warning about outdated Qt shown?") - test.compare(generalMessages.count("Project ERROR: Use at least Qt 5.6.2."), 1, + test.compare(generalMessages.count("Project ERROR: Use at least Qt 5.9.0."), 1, "Minimum Qt version shown (once when parsing with default kit, once with selected)?") # Verify that qmljs.g is in the project even when we don't know where (QTCREATORBUG-17609) diff --git a/tests/system/suite_general/tst_openqt_creator/testdata/projecttree_creator.tsv b/tests/system/suite_general/tst_openqt_creator/testdata/projecttree_creator.tsv index 9ca1262ddb..550fda20b6 100644 --- a/tests/system/suite_general/tst_openqt_creator/testdata/projecttree_creator.tsv +++ b/tests/system/suite_general/tst_openqt_creator/testdata/projecttree_creator.tsv @@ -29,7 +29,13 @@ "qtcreatordata" "2" "qtcreatordata.pri" "3" "Sources" "2" -"qobjectdefs.h" "4" +"cplusplus" "3" +"examples" "4" +"clazy_example.cpp" "5" +"examples.pro" "5" +"tidy_example.cpp" "5" +"tidy_example.h" "5" +"qobjectdefs.h" "5" "debugger" "3" "boosttypes.py" "4" "cdbbridge.py" "4" @@ -56,6 +62,7 @@ "standard.def" "4" "qml-type-descriptions" "3" "builtins.qmltypes" "4" +"qbs-base.qmltypes" "4" "qbs-bundle.json" "4" "qbs.qmltypes" "4" "qmlproject-bundle.json" "4" @@ -65,8 +72,6 @@ "qt-labs-folderlistmodel.qmltypes" "4" "qt-labs-gestures.qmltypes" "4" "qt-labs-particles.qmltypes" "4" -"qt4QtQuick1-bundle.json" "4" -"qt5QtQuick1-bundle.json" "4" "qt5QtQuick2-bundle.json" "4" "qtmobility-connectivity.qmltypes" "4" "qtmobility-contacts.qmltypes" "4" @@ -264,7 +269,6 @@ "ItemDelegate.qml" "5" "ItemsView.qml" "5" "propertyEditorQmlSources" "4" -"HelperWidgets" "5" "images" "6" "checkers.png" "7" "down-arrow.png" "7" @@ -433,6 +437,8 @@ "schemes" "3" "MS_Visual_C++.kms" "4" "Xcode.kms" "4" +"scripts" "3" +"openTerminal.command" "4" "snippets" "3" "cpp.xml" "4" "qml.xml" "4" @@ -476,6 +482,7 @@ "tst.qbs" "7" "tst.txt" "7" "tst_main.cpp" "7" +"tst_qml.tmpl" "7" "tst_src.cpp" "7" "tst_src.h" "7" "autotest.png" "6" @@ -537,8 +544,12 @@ "file.js" "7" "wizard.json" "7" "modeling" "6" -"file.qmodel" "7" -"wizard.json" "7" +"model" "7" +"file.qmodel" "8" +"wizard.json" "8" +"scratch" "7" +"file.qmodel" "8" +"wizard.json" "8" "nim" "6" "file.nim" "7" "wizard.json" "7" @@ -595,62 +606,74 @@ "wizard.json" "7" "file.pro" "7" "wizard.json" "7" -"qtcanvas3dapplication" "6" -"plaincanvas3d" "7" -"glcode.js" "8" -"threejs" "7" -"3rdparty" "8" -"three.js" "9" -"glcode.js" "8" -"3dapplication.png" "7" -"3dapplication@2x.png" "7" -"app.pro" "7" -"CMakeLists.txt" "7" -"file.qbs" "7" -"main.cpp" "7" -"main.qml.tpl" "7" -"qml.qrc" "7" -"/" "8" -"glcode.js" "9" -"main.qml" "9" -"three.js" "9" -"wizard.json" "7" "qtquickapplication" "6" +"canvas3d" "7" +"plaincanvas3d" "8" +"glcode.js" "9" +"threejs" "8" +"3rdparty" "9" +"three.js" "10" +"glcode.js" "9" +"icon.png" "8" +"icon@2x.png" "8" +"main.qml.tpl" "8" +"qml.qrc" "8" +"/" "9" +"glcode.js" "10" +"main.qml" "10" +"three.js" "10" +"wizard.json" "8" +"empty" "7" +"icon.png" "8" +"icon@2x.png" "8" +"main.qml.tpl" "8" +"qml.qrc" "8" +"/" "9" +"main.qml" "10" +"wizard.json" "8" +"scroll" "7" +"icon.png" "8" +"icon@2x.png" "8" +"main.qml.tpl" "8" +"qml.qrc" "8" +"/" "9" +"main.qml" "10" +"qtquickcontrols2.conf" "10" +"wizard.json" "8" +"stack" "7" +"HomeForm.ui.qml.tpl" "8" +"icon.png" "8" +"icon@2x.png" "8" +"main.qml.tpl" "8" +"Page1Form.ui.qml.tpl" "8" +"Page2Form.ui.qml.tpl" "8" +"qml.qrc" "8" +"/" "9" +"HomeForm.ui.qml" "10" +"main.qml" "10" +"Page1Form.ui.qml" "10" +"Page2Form.ui.qml" "10" +"qtquickcontrols2.conf" "10" +"wizard.json" "8" +"swipe" "7" +"icon.png" "8" +"icon@2x.png" "8" +"main.qml.tpl" "8" +"Page1Form.ui.qml.tpl" "8" +"Page2Form.ui.qml.tpl" "8" +"qml.qrc" "8" +"/" "9" +"main.qml" "10" +"Page1Form.ui.qml" "10" +"Page2Form.ui.qml" "10" +"qtquickcontrols2.conf" "10" +"wizard.json" "8" "app.pro" "7" -"CMakeLists.txt" "7" -"file.qbs" "7" -"icon-empty.png" "7" -"icon-empty@2x.png" "7" -"icon-scroll.png" "7" -"icon-scroll@2x.png" "7" -"icon-stack.png" "7" -"icon-stack@2x.png" "7" -"icon-swipe.png" "7" -"icon-swipe@2x.png" "7" -"main.cpp" "7" -"main.qml.tpl" "7" -"MainForm.ui.qml.tpl" "7" -"qml.qrc" "7" -"/" "8" -"main.qml" "9" -"MainForm.ui.qml" "9" -"wizard.json" "7" -"qtquickcontrols2application" "6" -"app.pro" "7" +"app.qbs" "7" "CMakeLists.txt" "7" "file.qbs" "7" "main.cpp" "7" -"main.qml.tpl" "7" -"Page1.qml.tpl" "7" -"Page1Form.ui.qml.tpl" "7" -"qml.qrc" "7" -"/" "8" -"main.qml" "9" -"Page1.qml" "9" -"Page1Form.ui.qml" "9" -"qtquickcontrols2.conf" "9" "qtquickcontrols2.conf" "7" -"wizard.json" "7" "qtquickuiprototype" "6" "app.qmlproject" "7" "qtquickuiprototype.png" "7" @@ -717,7 +740,13 @@ "flat-light.creatortheme" "4" "flat.creatortheme" "4" "Other files" "2" -"qobjectdefs.h" "4" +"cplusplus" "3" +"examples" "4" +"clazy_example.cpp" "5" +"examples.pro" "5" +"tidy_example.cpp" "5" +"tidy_example.h" "5" +"qobjectdefs.h" "5" "debugger" "3" "boosttypes.py" "4" "cdbbridge.py" "4" @@ -744,6 +773,7 @@ "standard.def" "4" "qml-type-descriptions" "3" "builtins.qmltypes" "4" +"qbs-base.qmltypes" "4" "qbs-bundle.json" "4" "qbs.qmltypes" "4" "qmlproject-bundle.json" "4" @@ -753,8 +783,6 @@ "qt-labs-folderlistmodel.qmltypes" "4" "qt-labs-gestures.qmltypes" "4" "qt-labs-particles.qmltypes" "4" -"qt4QtQuick1-bundle.json" "4" -"qt5QtQuick1-bundle.json" "4" "qt5QtQuick2-bundle.json" "4" "qtmobility-connectivity.qmltypes" "4" "qtmobility-contacts.qmltypes" "4" @@ -941,7 +969,6 @@ "SwipeView.qml" "7" "Window.qml" "7" "qmlpuppet_utilities.pri" "4" -"HelperWidgets" "4" "images" "5" "checkers.png" "6" "down-arrow.png" "6" @@ -1068,6 +1095,7 @@ "tst.qbs" "7" "tst.txt" "7" "tst_main.cpp" "7" +"tst_qml.tmpl" "7" "tst_src.cpp" "7" "tst_src.h" "7" "autotest.png" "6" @@ -1129,8 +1157,12 @@ "file.js" "7" "wizard.json" "7" "modeling" "6" -"file.qmodel" "7" -"wizard.json" "7" +"model" "7" +"file.qmodel" "8" +"wizard.json" "8" +"scratch" "7" +"file.qmodel" "8" +"wizard.json" "8" "nim" "6" "file.nim" "7" "wizard.json" "7" @@ -1187,62 +1219,74 @@ "wizard.json" "7" "file.pro" "7" "wizard.json" "7" -"qtcanvas3dapplication" "6" -"plaincanvas3d" "7" -"glcode.js" "8" -"threejs" "7" -"3rdparty" "8" -"three.js" "9" -"glcode.js" "8" -"3dapplication.png" "7" -"3dapplication@2x.png" "7" -"app.pro" "7" -"CMakeLists.txt" "7" -"file.qbs" "7" -"main.cpp" "7" -"main.qml.tpl" "7" -"qml.qrc" "7" -"/" "8" -"glcode.js" "9" -"main.qml" "9" -"three.js" "9" -"wizard.json" "7" "qtquickapplication" "6" +"canvas3d" "7" +"plaincanvas3d" "8" +"glcode.js" "9" +"threejs" "8" +"3rdparty" "9" +"three.js" "10" +"glcode.js" "9" +"icon.png" "8" +"icon@2x.png" "8" +"main.qml.tpl" "8" +"qml.qrc" "8" +"/" "9" +"glcode.js" "10" +"main.qml" "10" +"three.js" "10" +"wizard.json" "8" +"empty" "7" +"icon.png" "8" +"icon@2x.png" "8" +"main.qml.tpl" "8" +"qml.qrc" "8" +"/" "9" +"main.qml" "10" +"wizard.json" "8" +"scroll" "7" +"icon.png" "8" +"icon@2x.png" "8" +"main.qml.tpl" "8" +"qml.qrc" "8" +"/" "9" +"main.qml" "10" +"qtquickcontrols2.conf" "10" +"wizard.json" "8" +"stack" "7" +"HomeForm.ui.qml.tpl" "8" +"icon.png" "8" +"icon@2x.png" "8" +"main.qml.tpl" "8" +"Page1Form.ui.qml.tpl" "8" +"Page2Form.ui.qml.tpl" "8" +"qml.qrc" "8" +"/" "9" +"HomeForm.ui.qml" "10" +"main.qml" "10" +"Page1Form.ui.qml" "10" +"Page2Form.ui.qml" "10" +"qtquickcontrols2.conf" "10" +"wizard.json" "8" +"swipe" "7" +"icon.png" "8" +"icon@2x.png" "8" +"main.qml.tpl" "8" +"Page1Form.ui.qml.tpl" "8" +"Page2Form.ui.qml.tpl" "8" +"qml.qrc" "8" +"/" "9" +"main.qml" "10" +"Page1Form.ui.qml" "10" +"Page2Form.ui.qml" "10" +"qtquickcontrols2.conf" "10" +"wizard.json" "8" "app.pro" "7" -"CMakeLists.txt" "7" -"file.qbs" "7" -"icon-empty.png" "7" -"icon-empty@2x.png" "7" -"icon-scroll.png" "7" -"icon-scroll@2x.png" "7" -"icon-stack.png" "7" -"icon-stack@2x.png" "7" -"icon-swipe.png" "7" -"icon-swipe@2x.png" "7" -"main.cpp" "7" -"main.qml.tpl" "7" -"MainForm.ui.qml.tpl" "7" -"qml.qrc" "7" -"/" "8" -"main.qml" "9" -"MainForm.ui.qml" "9" -"wizard.json" "7" -"qtquickcontrols2application" "6" -"app.pro" "7" +"app.qbs" "7" "CMakeLists.txt" "7" "file.qbs" "7" "main.cpp" "7" -"main.qml.tpl" "7" -"Page1.qml.tpl" "7" -"Page1Form.ui.qml.tpl" "7" -"qml.qrc" "7" -"/" "8" -"main.qml" "9" -"Page1.qml" "9" -"Page1Form.ui.qml" "9" -"qtquickcontrols2.conf" "9" "qtquickcontrols2.conf" "7" -"wizard.json" "7" "qtquickuiprototype" "6" "app.qmlproject" "7" "qtquickuiprototype.png" "7" @@ -1332,6 +1376,8 @@ "src.pro" "1" "app" "1" "app.pro" "2" +"qtbreakpad" "2" +"qtbreakpad.pri" "3" "qtcreator" "2" "qtcreator.pri" "3" "qtsingleapplication" "2" @@ -1342,6 +1388,8 @@ "qtlockedfile.h" "5" "Sources" "4" "qtlockedfile.cpp" "5" +"qtlockedfile_unix.cpp" "5" +"qtlockedfile_win.cpp" "5" "Headers" "3" "qtlocalpeer.h" "4" "qtsingleapplication.h" "4" @@ -1358,7 +1406,6 @@ "Other files" "2" "app.qbs" "3" "app_version.h.in" "3" -"Info.plist" "3" "qtcreator.rc" "3" "app" "1" "app.pro" "2" @@ -1500,28 +1547,6 @@ "Sources" "3" "create-project-main.cpp" "4" "createproject.cpp" "4" -"qbs-qmltypes" "2" -"qbs-qmltypes.pro" "3" -"app" "3" -"app.pri" "4" -"install_prefix" "4" -"install_prefix.pri" "5" -"logging" "4" -"logging.pri" "5" -"Headers" "5" -"coloredoutput.h" "6" -"consolelogger.h" "6" -"Sources" "5" -"coloredoutput.cpp" "6" -"consolelogger.cpp" "6" -"use_corelib" "4" -"use_corelib.pri" "5" -"library_dirname" "5" -"library_dirname.pri" "6" -"qbs_version" "5" -"qbs_version.pri" "6" -"Sources" "3" -"main.cpp" "4" "qbs-setup-android" "2" "qbs-setup-android.pro" "3" "app" "3" @@ -1620,6 +1645,7 @@ "install_prefix" "3" "install_prefix.pri" "4" "Headers" "3" +"changeset.h" "4" "internaljobs.h" "4" "jobs.h" "4" "languageinfo.h" "4" @@ -1627,18 +1653,26 @@ "project_p.h" "4" "projectdata.h" "4" "projectdata_p.h" "4" +"projectfileupdater.h" "4" "propertymap_p.h" "4" +"qmljsrewriter.h" "4" "rulecommand.h" "4" "rulecommand_p.h" "4" "runenvironment.h" "4" +"transformerdata.h" "4" +"transformerdata_p.h" "4" "Sources" "3" +"changeset.cpp" "4" "internaljobs.cpp" "4" "jobs.cpp" "4" "languageinfo.cpp" "4" "project.cpp" "4" "projectdata.cpp" "4" +"projectfileupdater.cpp" "4" +"qmljsrewriter.cpp" "4" "rulecommand.cpp" "4" "runenvironment.cpp" "4" +"transformerdata.cpp" "4" "buildgraph" "2" "buildgraph.pri" "3" "install_prefix" "3" @@ -1647,14 +1681,17 @@ "abstractcommandexecutor.h" "4" "artifact.h" "4" "artifactcleaner.h" "4" +"artifactsscriptvalue.h" "4" "artifactvisitor.h" "4" "buildgraph.h" "4" "buildgraphloader.h" "4" "buildgraphnode.h" "4" "buildgraphvisitor.h" "4" "cycledetector.h" "4" +"dependencyparametersscriptvalue.h" "4" "depscanner.h" "4" "emptydirectoriesremover.h" "4" +"environmentscriptrunner.h" "4" "executor.h" "4" "executorjob.h" "4" "filedependency.h" "4" @@ -1670,25 +1707,32 @@ "qtmocscanner.h" "4" "rawscanneddependency.h" "4" "rawscanresults.h" "4" +"requestedartifacts.h" "4" +"requesteddependencies.h" "4" "rescuableartifactdata.h" "4" "rulecommands.h" "4" "rulegraph.h" "4" "rulenode.h" "4" "rulesapplicator.h" "4" "rulesevaluationcontext.h" "4" +"scriptclasspropertyiterator.h" "4" "timestampsupdater.h" "4" "transformer.h" "4" +"transformerchangetracking.h" "4" "Sources" "3" "abstractcommandexecutor.cpp" "4" "artifact.cpp" "4" "artifactcleaner.cpp" "4" +"artifactsscriptvalue.cpp" "4" "artifactvisitor.cpp" "4" "buildgraph.cpp" "4" "buildgraphloader.cpp" "4" "buildgraphnode.cpp" "4" "cycledetector.cpp" "4" +"dependencyparametersscriptvalue.cpp" "4" "depscanner.cpp" "4" "emptydirectoriesremover.cpp" "4" +"environmentscriptrunner.cpp" "4" "executor.cpp" "4" "executorjob.cpp" "4" "filedependency.cpp" "4" @@ -1703,7 +1747,8 @@ "qtmocscanner.cpp" "4" "rawscanneddependency.cpp" "4" "rawscanresults.cpp" "4" -"rescuableartifactdata.cpp" "4" +"requestedartifacts.cpp" "4" +"requesteddependencies.cpp" "4" "rulecommands.cpp" "4" "rulegraph.cpp" "4" "rulenode.cpp" "4" @@ -1711,8 +1756,13 @@ "rulesevaluationcontext.cpp" "4" "timestampsupdater.cpp" "4" "transformer.cpp" "4" +"transformerchangetracking.cpp" "4" +"bundledlibs" "2" +"bundledlibs.pri" "3" "generators" "2" "generators.pri" "3" +"install_prefix" "3" +"install_prefix.pri" "4" "Headers" "3" "generatableprojectiterator.h" "4" "generator.h" "4" @@ -1726,9 +1776,10 @@ "jsextensions.pri" "3" "Headers" "3" "jsextensions.h" "4" -"jsextensions_p.h" "4" "moduleproperties.h" "4" +"propertylistutils.h" "4" "Sources" "3" +"binaryfile.cpp" "4" "domxml.cpp" "4" "environmentextension.cpp" "4" "file.cpp" "4" @@ -1736,6 +1787,9 @@ "jsextensions.cpp" "4" "moduleproperties.cpp" "4" "process.cpp" "4" +"propertylist.cpp" "4" +"propertylist.mm" "4" +"propertylistutils.mm" "4" "temporarydir.cpp" "4" "textfile.cpp" "4" "utilitiesextension.cpp" "4" @@ -1813,6 +1867,7 @@ "resolvedfilecontext.cpp" "4" "scriptengine.cpp" "4" "scriptimporter.cpp" "4" +"scriptpropertyobserver.cpp" "4" "value.cpp" "4" "library" "2" "library.pri" "3" @@ -1827,10 +1882,12 @@ "install_prefix" "3" "install_prefix.pri" "4" "Headers" "3" +"categories.h" "4" "ilogsink.h" "4" "logger.h" "4" "translator.h" "4" "Sources" "3" +"categories.cpp" "4" "ilogsink.cpp" "4" "logger.cpp" "4" "parser" "2" @@ -1860,12 +1917,14 @@ "install_prefix" "3" "install_prefix.pri" "4" "Headers" "3" +"applecodesignutils.h" "4" "architectures.h" "4" "buildgraphlocker.h" "4" "buildoptions.h" "4" "cleanoptions.h" "4" "codelocation.h" "4" "commandechomode.h" "4" +"dynamictypecheck.h" "4" "error.h" "4" "executablefinder.h" "4" "fileinfo.h" "4" @@ -1875,6 +1934,7 @@ "hostosinfo.h" "4" "id.h" "4" "installoptions.h" "4" +"iosutils.h" "4" "jsliterals.h" "4" "launcherinterface.h" "4" "launcherpackets.h" "4" @@ -1882,7 +1942,6 @@ "msvcinfo.h" "4" "pathutils.h" "4" "persistence.h" "4" -"persistentobject.h" "4" "preferences.h" "4" "processresult.h" "4" "processresult_p.h" "4" @@ -1902,15 +1961,19 @@ "settings.h" "4" "settingscreator.h" "4" "settingsmodel.h" "4" +"settingsrepresentation.h" "4" "setupprojectparameters.h" "4" "shellutils.h" "4" "stlutils.h" "4" +"stringconstants.h" "4" +"stringutils.h" "4" "toolchains.h" "4" "version.h" "4" "visualstudioversioninfo.h" "4" "vsenvironmentdetector.h" "4" "weakpointer.h" "4" "Sources" "3" +"applecodesignutils.cpp" "4" "architectures.cpp" "4" "buildgraphlocker.cpp" "4" "buildoptions.cpp" "4" @@ -1947,12 +2010,17 @@ "settings.cpp" "4" "settingscreator.cpp" "4" "settingsmodel.cpp" "4" +"settingsrepresentation.cpp" "4" "setupprojectparameters.cpp" "4" "shellutils.cpp" "4" "toolchains.cpp" "4" "version.cpp" "4" "visualstudioversioninfo.cpp" "4" "vsenvironmentdetector.cpp" "4" +"use_scriptengine" "2" +"use_scriptengine.pri" "3" +"library_dirname" "3" +"library_dirname.pri" "4" "Headers" "2" "qbs.h" "3" "data" "1" @@ -2021,16 +2089,17 @@ "externaltools" "3" "lrelease.xml" "4" "lupdate.xml" "4" +"notepad_win.xml" "4" "qmlscene.xml" "4" "qmlviewer.xml" "4" -"sort.xml" "4" +"vi.xml" "4" +"vi_mac.xml" "4" "Other files" "2" "externaltools" "3" "lrelease.xml" "4" "lupdate.xml" "4" "qmlscene.xml" "4" "qmlviewer.xml" "4" -"sort.xml" "4" "libexec" "1" "libexec.pro" "2" "qbs_processlauncher" "2" @@ -2072,14 +2141,17 @@ "aggregation.qbs" "4" "aggregation_dependencies" "2" "aggregation_dependencies.pri" "3" -"clangbackendipc" "2" -"clangbackendipc.pro" "3" -"clangbackendipc-lib" "3" -"clangbackendipc-lib.pri" "4" +"cdb_detect" "2" +"cdb_detect.pri" "3" +"clangsupport" "2" +"clangsupport.pro" "3" +"clangsupport-lib" "3" +"clangsupport-lib.pri" "4" "Headers" "4" +"alivemessage.h" "5" +"annotationsmessage.h" "5" +"baseserverproxy.h" "5" "cancelmessage.h" "5" -"clangbackendipc_global.h" "5" -"clangbackendipcdebugutils.h" "5" "clangcodemodelclientinterface.h" "5" "clangcodemodelclientmessages.h" "5" "clangcodemodelclientproxy.h" "5" @@ -2087,61 +2159,86 @@ "clangcodemodelserverinterface.h" "5" "clangcodemodelservermessages.h" "5" "clangcodemodelserverproxy.h" "5" +"clangpathwatcher.h" "5" +"clangpathwatcherinterface.h" "5" +"clangpathwatchernotifier.h" "5" "clangrefactoringclientmessages.h" "5" "clangrefactoringmessages.h" "5" "clangrefactoringservermessages.h" "5" -"cmbalivemessage.h" "5" -"cmbcodecompletedmessage.h" "5" -"cmbcompletecodemessage.h" "5" -"cmbechomessage.h" "5" -"cmbendmessage.h" "5" -"cmbregisterprojectsforeditormessage.h" "5" -"cmbregistertranslationunitsforeditormessage.h" "5" -"cmbunregisterprojectsforeditormessage.h" "5" -"cmbunregistertranslationunitsforeditormessage.h" "5" +"clangsupport_global.h" "5" +"clangsupportdebugutils.h" "5" "codecompletion.h" "5" "codecompletionchunk.h" "5" +"compilermacro.h" "5" +"completionsmessage.h" "5" "connectionclient.h" "5" "connectionserver.h" "5" "diagnosticcontainer.h" "5" -"documentannotationschangedmessage.h" "5" +"documentschangedmessage.h" "5" +"documentsclosedmessage.h" "5" +"documentsopenedmessage.h" "5" +"documentvisibilitychangedmessage.h" "5" "dynamicastmatcherdiagnosticcontainer.h" "5" "dynamicastmatcherdiagnosticcontextcontainer.h" "5" "dynamicastmatcherdiagnosticmessagecontainer.h" "5" "dynamicmatcherdiagnostics.h" "5" +"echomessage.h" "5" +"endmessage.h" "5" "filecontainer.h" "5" "filecontainerv2.h" "5" "filepath.h" "5" +"filepathcache.h" "5" +"filepathcaching.h" "5" +"filepathcachingfwd.h" "5" +"filepathcachinginterface.h" "5" +"filepathexceptions.h" "5" +"filepathid.h" "5" +"filepathstorage.h" "5" +"filepathstoragesources.h" "5" +"filepathstoragesqlitestatementfactory.h" "5" +"filepathview.h" "5" "fixitcontainer.h" "5" -"highlightingmarkcontainer.h" "5" +"followsymbolmessage.h" "5" +"idpaths.h" "5" "ipcclientinterface.h" "5" +"ipcclientprovider.h" "5" "ipcinterface.h" "5" "ipcserverinterface.h" "5" "lineprefixer.h" "5" "messageenvelop.h" "5" +"nativefilepath.h" "5" "pchmanagerclientinterface.h" "5" "pchmanagerclientproxy.h" "5" "pchmanagerserverinterface.h" "5" "pchmanagerserverproxy.h" "5" "precompiledheadersupdatedmessage.h" "5" +"processcreator.h" "5" +"processexception.h" "5" +"processhandle.h" "5" +"processstartedevent.h" "5" +"projectmanagementserverinterface.h" "5" "projectpartcontainer.h" "5" "projectpartcontainerv2.h" "5" "projectpartpch.h" "5" -"projectpartsdonotexistmessage.h" "5" +"projectpartpchproviderinterface.h" "5" +"projectpartsremovedmessage.h" "5" +"projectpartsupdatedmessage.h" "5" "readmessageblock.h" "5" "refactoringclientinterface.h" "5" "refactoringclientproxy.h" "5" +"refactoringdatabaseinitializer.h" "5" "refactoringserverinterface.h" "5" "refactoringserverproxy.h" "5" "referencesmessage.h" "5" -"registerunsavedfilesforeditormessage.h" "5" -"removepchprojectpartsmessage.h" "5" -"requestdocumentannotations.h" "5" +"removeprojectpartsmessage.h" "5" +"requestannotationsmessage.h" "5" +"requestcompletionsmessage.h" "5" +"requestfollowsymbolmessage.h" "5" "requestreferencesmessage.h" "5" "requestsourcelocationforrenamingmessage.h" "5" "requestsourcerangesanddiagnosticsforquerymessage.h" "5" "requestsourcerangesforquerymessage.h" "5" -"sourcefilepathcontainerbase.h" "5" +"requesttooltipmessage.h" "5" "sourcelocationcontainer.h" "5" "sourcelocationcontainerv2.h" "5" "sourcelocationscontainer.h" "5" @@ -2153,46 +2250,48 @@ "sourcerangesforquerymessage.h" "5" "sourcerangewithtextcontainer.h" "5" "stringcache.h" "5" -"translationunitdoesnotexistmessage.h" "5" -"unregisterunsavedfilesforeditormessage.h" "5" -"updatepchprojectpartsmessage.h" "5" -"updatetranslationunitsforeditormessage.h" "5" -"updatevisibletranslationunitsmessage.h" "5" +"stringcachealgorithms.h" "5" +"stringcachefwd.h" "5" +"tokeninfocontainer.h" "5" +"tooltipinfo.h" "5" +"tooltipmessage.h" "5" +"unsavedfilesremovedmessage.h" "5" +"unsavedfilesupdatedmessage.h" "5" +"updateprojectpartsmessage.h" "5" "writemessageblock.h" "5" "Sources" "4" +"alivemessage.cpp" "5" +"annotationsmessage.cpp" "5" +"baseserverproxy.cpp" "5" "cancelmessage.cpp" "5" -"clangbackendipcdebugutils.cpp" "5" "clangcodemodelclientinterface.cpp" "5" "clangcodemodelclientproxy.cpp" "5" "clangcodemodelconnectionclient.cpp" "5" "clangcodemodelserverinterface.cpp" "5" "clangcodemodelserverproxy.cpp" "5" -"cmbalivemessage.cpp" "5" -"cmbcodecompletedmessage.cpp" "5" -"cmbcompletecodemessage.cpp" "5" -"cmbechomessage.cpp" "5" -"cmbendmessage.cpp" "5" -"cmbregisterprojectsforeditormessage.cpp" "5" -"cmbregistertranslationunitsforeditormessage.cpp" "5" -"cmbunregisterprojectsforeditormessage.cpp" "5" -"cmbunregistertranslationunitsforeditormessage.cpp" "5" +"clangsupportdebugutils.cpp" "5" "codecompletion.cpp" "5" "codecompletionchunk.cpp" "5" +"completionsmessage.cpp" "5" "connectionclient.cpp" "5" "connectionserver.cpp" "5" "diagnosticcontainer.cpp" "5" -"documentannotationschangedmessage.cpp" "5" +"documentschangedmessage.cpp" "5" +"documentsclosedmessage.cpp" "5" +"documentsopenedmessage.cpp" "5" +"documentvisibilitychangedmessage.cpp" "5" "dynamicastmatcherdiagnosticcontainer.cpp" "5" "dynamicastmatcherdiagnosticcontextcontainer.cpp" "5" "dynamicastmatcherdiagnosticmessagecontainer.cpp" "5" +"echomessage.cpp" "5" +"endmessage.cpp" "5" "filecontainer.cpp" "5" "filecontainerv2.cpp" "5" "filepath.cpp" "5" +"filepathcaching.cpp" "5" +"filepathid.cpp" "5" "fixitcontainer.cpp" "5" -"highlightingmarkcontainer.cpp" "5" -"ipcclientinterface.cpp" "5" -"ipcinterface.cpp" "5" -"ipcserverinterface.cpp" "5" +"followsymbolmessage.cpp" "5" "lineprefixer.cpp" "5" "messageenvelop.cpp" "5" "pchmanagerclientinterface.cpp" "5" @@ -2200,24 +2299,29 @@ "pchmanagerserverinterface.cpp" "5" "pchmanagerserverproxy.cpp" "5" "precompiledheadersupdatedmessage.cpp" "5" +"processcreator.cpp" "5" +"processexception.cpp" "5" +"processstartedevent.cpp" "5" "projectpartcontainer.cpp" "5" "projectpartcontainerv2.cpp" "5" "projectpartpch.cpp" "5" -"projectpartsdonotexistmessage.cpp" "5" +"projectpartsremovedmessage.cpp" "5" +"projectpartsupdatedmessage.cpp" "5" "readmessageblock.cpp" "5" "refactoringclientinterface.cpp" "5" "refactoringclientproxy.cpp" "5" "refactoringserverinterface.cpp" "5" "refactoringserverproxy.cpp" "5" "referencesmessage.cpp" "5" -"registerunsavedfilesforeditormessage.cpp" "5" -"removepchprojectpartsmessage.cpp" "5" -"requestdocumentannotations.cpp" "5" +"removeprojectpartsmessage.cpp" "5" +"requestannotationsmessage.cpp" "5" +"requestcompletionsmessage.cpp" "5" +"requestfollowsymbolmessage.cpp" "5" "requestreferencesmessage.cpp" "5" "requestsourcelocationforrenamingmessage.cpp" "5" "requestsourcerangesanddiagnosticsforquerymessage.cpp" "5" "requestsourcerangesforquerymessage.cpp" "5" -"sourcefilepathcontainerbase.cpp" "5" +"requesttooltipmessage.cpp" "5" "sourcelocationcontainer.cpp" "5" "sourcelocationcontainerv2.cpp" "5" "sourcelocationscontainer.cpp" "5" @@ -2228,16 +2332,17 @@ "sourcerangescontainer.cpp" "5" "sourcerangesforquerymessage.cpp" "5" "sourcerangewithtextcontainer.cpp" "5" -"translationunitdoesnotexistmessage.cpp" "5" -"unregisterunsavedfilesforeditormessage.cpp" "5" -"updatepchprojectpartsmessage.cpp" "5" -"updatetranslationunitsforeditormessage.cpp" "5" -"updatevisibletranslationunitsmessage.cpp" "5" +"tokeninfocontainer.cpp" "5" +"tooltipinfo.cpp" "5" +"tooltipmessage.cpp" "5" +"unsavedfilesremovedmessage.cpp" "5" +"unsavedfilesupdatedmessage.cpp" "5" +"updateprojectpartsmessage.cpp" "5" "writemessageblock.cpp" "5" "qtcreatorlibrary" "3" "qtcreatorlibrary.pri" "4" -"clangbackendipc_dependencies" "4" -"clangbackendipc_dependencies.pri" "5" +"clangsupport_dependencies" "4" +"clangsupport_dependencies.pri" "5" "qtcreator" "4" "qtcreator.pri" "5" "sqlite_dependencies" "5" @@ -2250,9 +2355,9 @@ "shared" "5" "qtcreator_pch.h" "6" "Other files" "3" -"clangbackendipc.qbs" "4" -"clangbackendipc_dependencies" "2" -"clangbackendipc_dependencies.pri" "3" +"clangsupport.qbs" "4" +"clangsupport_dependencies" "2" +"clangsupport_dependencies.pri" "3" "cplusplus" "2" "cplusplus.pro" "3" "cplusplus-lib" "3" @@ -2348,7 +2453,6 @@ "MatchingText.h" "5" "NamePrettyPrinter.h" "5" "Overview.h" "5" -"OverviewModel.h" "5" "pp-cctype.h" "5" "pp-engine.h" "5" "pp-scanner.h" "5" @@ -2382,7 +2486,6 @@ "MatchingText.cpp" "5" "NamePrettyPrinter.cpp" "5" "Overview.cpp" "5" -"OverviewModel.cpp" "5" "pp-engine.cpp" "5" "pp-scanner.cpp" "5" "PPToken.cpp" "5" @@ -2504,34 +2607,6 @@ "extensionsystem.qbs" "4" "extensionsystem_dependencies" "2" "extensionsystem_dependencies.pri" "3" -"flamegraph" "2" -"flamegraph.pro" "3" -"qtcreatorlibrary" "3" -"qtcreatorlibrary.pri" "4" -"flamegraph_dependencies" "4" -"flamegraph_dependencies.pri" "5" -"qtcreator" "4" -"qtcreator.pri" "5" -"rpath" "4" -"rpath.pri" "5" -"Headers" "4" -"shared" "5" -"qtcreator_pch.h" "6" -"Headers" "3" -"flamegraph.h" "4" -"flamegraph_global.h" "4" -"flamegraphattached.h" "4" -"Sources" "3" -"flamegraph.cpp" "4" -"Resources" "3" -"/flamegraph" "5" -"FlameGraphDelegate.qml" "6" -"FlameGraphDetails.qml" "6" -"FlameGraphText.qml" "6" -"Other files" "3" -"flamegraph.qbs" "4" -"flamegraph_dependencies" "2" -"flamegraph_dependencies.pri" "3" "glsl" "2" "glsl.pro" "3" "glsl-lib" "3" @@ -2637,6 +2712,7 @@ "dboundary.h" "6" "dclass.h" "6" "dcomponent.h" "6" +"dconnection.h" "6" "dconstvisitor.h" "6" "ddependency.h" "6" "ddiagram.h" "6" @@ -2646,6 +2722,7 @@ "dobject.h" "6" "dpackage.h" "6" "drelation.h" "6" +"dswimlane.h" "6" "dvisitor.h" "6" "diagram_controller" "5" "dclonevisitor.h" "6" @@ -2674,12 +2751,14 @@ "boundaryitem.h" "7" "classitem.h" "7" "componentitem.h" "7" +"connectionitem.h" "7" "diagramitem.h" "7" "itemitem.h" "7" "objectitem.h" "7" "packageitem.h" "7" "relationitem.h" "7" "stereotypedisplayvisitor.h" "7" +"swimlaneitem.h" "7" "parts" "6" "alignbuttonsitem.h" "7" "alignlineitem.h" "7" @@ -2725,6 +2804,7 @@ "mclass.h" "6" "mclassmember.h" "6" "mcomponent.h" "6" +"mconnection.h" "6" "mconstvisitor.h" "6" "mdependency.h" "6" "mdiagram.h" "6" @@ -2767,6 +2847,7 @@ "modelserializer.h" "6" "projectserializer.h" "6" "stereotype" "5" +"customrelation.h" "6" "iconshape.h" "6" "shape.h" "6" "shapepaintvisitor.h" "6" @@ -2813,6 +2894,7 @@ "dboundary.cpp" "6" "dclass.cpp" "6" "dcomponent.cpp" "6" +"dconnection.cpp" "6" "ddependency.cpp" "6" "ddiagram.cpp" "6" "delement.cpp" "6" @@ -2821,6 +2903,7 @@ "dobject.cpp" "6" "dpackage.cpp" "6" "drelation.cpp" "6" +"dswimlane.cpp" "6" "diagram_controller" "5" "dclonevisitor.cpp" "6" "dfactory.cpp" "6" @@ -2835,12 +2918,14 @@ "boundaryitem.cpp" "7" "classitem.cpp" "7" "componentitem.cpp" "7" +"connectionitem.cpp" "7" "diagramitem.cpp" "7" "itemitem.cpp" "7" "objectitem.cpp" "7" "packageitem.cpp" "7" "relationitem.cpp" "7" "stereotypedisplayvisitor.cpp" "7" +"swimlaneitem.cpp" "7" "parts" "6" "alignbuttonsitem.cpp" "7" "alignlineitem.cpp" "7" @@ -2878,6 +2963,7 @@ "mclass.cpp" "6" "mclassmember.cpp" "6" "mcomponent.cpp" "6" +"mconnection.cpp" "6" "mdependency.cpp" "6" "mdiagram.cpp" "6" "melement.cpp" "6" @@ -2914,6 +3000,7 @@ "modelserializer.cpp" "6" "projectserializer.cpp" "6" "stereotype" "5" +"customrelation.cpp" "6" "iconshape.cpp" "6" "shapepaintvisitor.cpp" "6" "shapes.cpp" "6" @@ -2961,6 +3048,7 @@ "inheritance.png" "8" "item.png" "8" "package.png" "8" +"swimlane.png" "8" "qstringparser" "3" "qstringparser.pri" "4" "Headers" "4" @@ -3012,11 +3100,21 @@ "modelinglib.qbs" "4" "modelinglib_dependencies" "2" "modelinglib_dependencies.pri" "3" +"process_ctrlc_stub" "2" +"process_ctrlc_stub.pro" "3" +"qtcreator" "3" +"qtcreator.pri" "4" +"Sources" "3" +"process_ctrlc_stub.cpp" "4" +"Other files" "3" +"process_ctrlc_stub.qbs" "4" "process_stub" "2" "process_stub.pro" "3" "qtcreator" "3" "qtcreator.pri" "4" "Sources" "3" +"process_stub_unix.c" "4" +"process_stub_win.c" "4" "Other files" "3" "process_stub.qbs" "4" "qmldebug" "2" @@ -3033,6 +3131,8 @@ "qmldebug_global.h" "5" "qmldebugclient.h" "5" "qmldebugcommandlinearguments.h" "5" +"qmldebugconnection.h" "5" +"qmldebugconnectionmanager.h" "5" "qmldebugconstants.h" "5" "qmlenginecontrolclient.h" "5" "qmlenginedebugclient.h" "5" @@ -3046,6 +3146,8 @@ "declarativetoolsclient.cpp" "5" "qdebugmessageclient.cpp" "5" "qmldebugclient.cpp" "5" +"qmldebugconnection.cpp" "5" +"qmldebugconnectionmanager.cpp" "5" "qmlenginecontrolclient.cpp" "5" "qmloutputparser.cpp" "5" "qmltoolsclient.cpp" "5" @@ -3083,10 +3185,8 @@ "easingcontextpane.ui" "6" "Resources" "5" "easingpane.qrc" "6" -"/" "7" -"playicon.png" "8" +"/qmleditorwidgets" "7" "qt_logo.png" "8" -"stopicon.png" "8" "Headers" "4" "colorbox.h" "5" "colorbutton.h" "5" @@ -3162,13 +3262,11 @@ "bold-h-icon.png" "8" "checkbox_indicator.png" "8" "checkbox_indicator@2x.png" "8" -"hole.png" "8" "horizontal-scale-icon.png" "8" "icon_color_gradient.png" "8" "icon_color_none.png" "8" "icon_color_solid.png" "8" "italic-h-icon.png" "8" -"lock.png" "8" "scale-icon.png" "8" "scrollbar-borderimage-horizontal.png" "8" "scrollbar-borderimage-vertical.png" "8" @@ -3181,8 +3279,8 @@ "style_strikeout@2x.png" "8" "style_underline.png" "8" "style_underline@2x.png" "8" -"tile-icon-hor - scale.png" "8" "tile-icon-hor-crop.png" "8" +"tile-icon-hor-scale.png" "8" "tile-icon-vert-crop.png" "8" "tile-icon-vert-scale.png" "8" "tile-icon.png" "8" @@ -3349,6 +3447,49 @@ "qmljs_dependencies.pri" "3" "qtcreator" "2" "qtcreator.pri" "3" +"qtcreatorcdbext" "2" +"qtcreatorcdbext.pro" "3" +"cdb_detect" "3" +"cdb_detect.pri" "4" +"qtcreator" "3" +"qtcreator.pri" "4" +"Headers" "3" +"common.h" "4" +"containers.h" "4" +"eventcallback.h" "4" +"extensioncontext.h" "4" +"gdbmihelpers.h" "4" +"iinterfacepointer.h" "4" +"knowntype.h" "4" +"outputcallback.h" "4" +"pycdbextmodule.h" "4" +"pyfield.h" "4" +"pystdoutredirect.h" "4" +"pytype.h" "4" +"pyvalue.h" "4" +"stringutils.h" "4" +"symbolgroup.h" "4" +"symbolgroupnode.h" "4" +"symbolgroupvalue.h" "4" +"Sources" "3" +"common.cpp" "4" +"containers.cpp" "4" +"eventcallback.cpp" "4" +"extensioncontext.cpp" "4" +"gdbmihelpers.cpp" "4" +"outputcallback.cpp" "4" +"pycdbextmodule.cpp" "4" +"pyfield.cpp" "4" +"pystdoutredirect.cpp" "4" +"pytype.cpp" "4" +"pyvalue.cpp" "4" +"qtcreatorcdbextension.cpp" "4" +"stringutils.cpp" "4" +"symbolgroup.cpp" "4" +"symbolgroupnode.cpp" "4" +"symbolgroupvalue.cpp" "4" +"Other files" "3" +"qtcreatorcdbext.qbs" "4" "sqlite" "2" "sqlite.pro" "3" "qtcreatorlibrary" "3" @@ -3373,51 +3514,37 @@ "Sources" "5" "sqlite3.c" "6" "Headers" "4" -"columndefinition.h" "5" -"createtablecommand.h" "5" "createtablesqlstatementbuilder.h" "5" +"sqlitebasestatement.h" "5" "sqlitecolumn.h" "5" "sqlitedatabase.h" "5" "sqlitedatabasebackend.h" "5" -"sqlitedatabaseconnection.h" "5" -"sqlitedatabaseconnectionproxy.h" "5" "sqliteexception.h" "5" "sqliteglobal.h" "5" +"sqliteindex.h" "5" "sqlitereadstatement.h" "5" "sqlitereadwritestatement.h" "5" -"sqlitestatement.h" "5" "sqlitetable.h" "5" "sqlitetransaction.h" "5" -"sqliteworkerthread.h" "5" "sqlitewritestatement.h" "5" "sqlstatementbuilder.h" "5" "sqlstatementbuilderexception.h" "5" -"tablewriteworker.h" "5" -"tablewriteworkerproxy.h" "5" "utf8string.h" "5" "utf8stringvector.h" "5" "Sources" "4" -"columndefinition.cpp" "5" -"createtablecommand.cpp" "5" "createtablesqlstatementbuilder.cpp" "5" +"sqlitebasestatement.cpp" "5" "sqlitecolumn.cpp" "5" "sqlitedatabase.cpp" "5" "sqlitedatabasebackend.cpp" "5" -"sqlitedatabaseconnection.cpp" "5" -"sqlitedatabaseconnectionproxy.cpp" "5" "sqliteexception.cpp" "5" "sqliteglobal.cpp" "5" "sqlitereadstatement.cpp" "5" "sqlitereadwritestatement.cpp" "5" -"sqlitestatement.cpp" "5" "sqlitetable.cpp" "5" -"sqlitetransaction.cpp" "5" -"sqliteworkerthread.cpp" "5" "sqlitewritestatement.cpp" "5" "sqlstatementbuilder.cpp" "5" "sqlstatementbuilderexception.cpp" "5" -"tablewriteworker.cpp" "5" -"tablewriteworkerproxy.cpp" "5" "utf8string.cpp" "5" "utf8stringvector.cpp" "5" "Other files" "3" @@ -3522,12 +3649,19 @@ "sshtcpiptunnel.cpp" "4" "Forms" "3" "sshkeycreationdialog.ui" "4" +"Resources" "3" +"ssh.qrc" "4" +"/ssh" "5" +"images" "6" +"dir.png" "7" +"help.png" "7" +"unknownfile.png" "7" "Other files" "3" "ssh.qbs" "4" "ssh_dependencies" "2" "ssh_dependencies.pri" "3" -"timeline" "2" -"timeline.pro" "3" +"tracing" "2" +"tracing.pro" "3" "qtcreatorlibrary" "3" "qtcreatorlibrary.pri" "4" "qtcreator" "4" @@ -3536,14 +3670,15 @@ "utils_dependencies.pri" "6" "rpath" "4" "rpath.pri" "5" -"timeline_dependencies" "4" -"timeline_dependencies.pri" "5" +"tracing_dependencies" "4" +"tracing_dependencies.pri" "5" "Headers" "4" "shared" "5" "qtcreator_pch.h" "6" "Headers" "3" +"flamegraph.h" "4" +"flamegraphattached.h" "4" "runscenegraphtest.h" "4" -"timeline_global.h" "4" "timelineabstractrenderer.h" "4" "timelineabstractrenderer_p.h" "4" "timelineformattime.h" "4" @@ -3563,8 +3698,15 @@ "timelinerenderstate_p.h" "4" "timelineselectionrenderpass.h" "4" "timelinetheme.h" "4" +"timelinetracefile.h" "4" +"timelinetracemanager.h" "4" "timelinezoomcontrol.h" "4" +"traceevent.h" "4" +"traceeventtype.h" "4" +"tracestashfile.h" "4" +"tracing_global.h" "4" "Sources" "3" +"flamegraph.cpp" "4" "runscenegraphtest.cpp" "4" "timelineabstractrenderer.cpp" "4" "timelineformattime.cpp" "4" @@ -3579,12 +3721,16 @@ "timelinerenderstate.cpp" "4" "timelineselectionrenderpass.cpp" "4" "timelinetheme.cpp" "4" +"timelinetracefile.cpp" "4" +"timelinetracemanager.cpp" "4" "timelinezoomcontrol.cpp" "4" "Resources" "3" -"/timeline" "5" +"/tracing" "5" "ButtonsBar.qml" "6" "CategoryLabel.qml" "6" "Detail.qml" "6" +"FlameGraphDelegate.qml" "6" +"FlameGraphView.qml" "6" "ico_edit.png" "6" "ico_edit@2x.png" "6" "ico_rangeselected.png" "6" @@ -3604,7 +3750,6 @@ "RowLabel.qml" "6" "SelectionRange.qml" "6" "SelectionRangeDetails.qml" "6" -"SynchronousReloader.qml" "6" "TimeDisplay.qml" "6" "TimelineContent.qml" "6" "timelineitems.frag" "6" @@ -3615,9 +3760,9 @@ "TimeMarks.qml" "6" "Other files" "3" "README" "4" -"timeline.qbs" "4" -"timeline_dependencies" "2" -"timeline_dependencies.pri" "3" +"tracing.qbs" "4" +"tracing_dependencies" "2" +"tracing_dependencies.pri" "3" "utils" "2" "utils.pro" "3" "qtcreatorlibrary" "3" @@ -3654,7 +3799,10 @@ "mimetype.cpp" "6" "mimetypeparser.cpp" "6" "Headers" "4" -"optional.hpp" "6" +"optional" "6" +"optional.hpp" "7" +"variant" "6" +"variant.hpp" "7" "theme" "5" "theme.h" "6" "theme_p.h" "6" @@ -3667,9 +3815,8 @@ "annotateditemdelegate.h" "5" "ansiescapecodehandler.h" "5" "appmainwindow.h" "5" -"asconst.h" "5" "basetreeview.h" "5" -"bracematcher.h" "5" +"benchmarker.h" "5" "buildablehelperlibrary.h" "5" "categorysortfiltermodel.h" "5" "changeset.h" "5" @@ -3696,14 +3843,18 @@ "faketooltip.h" "5" "fancylineedit.h" "5" "fancymainwindow.h" "5" +"filecrumblabel.h" "5" "fileinprojectfinder.h" "5" "filenamevalidatinglineedit.h" "5" "filesearch.h" "5" "filesystemwatcher.h" "5" "fileutils.h" "5" +"fileutils_mac.h" "5" "filewizardpage.h" "5" +"fixedsizeclicklabel.h" "5" "flowlayout.h" "5" "functiontraits.h" "5" +"fuzzymatcher.h" "5" "guard.h" "5" "headerviewstretcher.h" "5" "highlightingitemdelegate.h" "5" @@ -3713,14 +3864,14 @@ "icon.h" "5" "itemviews.h" "5" "json.h" "5" -"linecolumnlabel.h" "5" +"linecolumn.h" "5" +"link.h" "5" "listutils.h" "5" "macroexpander.h" "5" "mapreduce.h" "5" "navigationtreeview.h" "5" "networkaccessmanager.h" "5" "newclasswidget.h" "5" -"objectpool.h" "5" "optional.h" "5" "osspecificaspects.h" "5" "outputformat.h" "5" @@ -3730,23 +3881,26 @@ "pathchooser.h" "5" "pathlisteditor.h" "5" "persistentsettings.h" "5" +"pointeralgorithm.h" "5" "port.h" "5" "portlist.h" "5" +"predicates.h" "5" "processhandle.h" "5" "progressindicator.h" "5" "projectintropage.h" "5" "proxyaction.h" "5" "proxycredentialsdialog.h" "5" "qtcassert.h" "5" -"qtcfallthrough.h" "5" "qtcolorbutton.h" "5" "QtConcurrentTools" "5" "qtcprocess.h" "5" "reloadpromptutils.h" "5" +"removefiledialog.h" "5" "runextensions.h" "5" "savedaction.h" "5" "savefile.h" "5" "scopedswap.h" "5" +"settingsaccessor.h" "5" "settingsselector.h" "5" "shellcommand.h" "5" "shellcommandpage.h" "5" @@ -3770,12 +3924,15 @@ "textfieldcheckbox.h" "5" "textfieldcombobox.h" "5" "textfileformat.h" "5" +"textutils.h" "5" "treemodel.h" "5" "treeviewcombobox.h" "5" "uncommentselection.h" "5" "unixutils.h" "5" +"url.h" "5" "utils_global.h" "5" "utilsicons.h" "5" +"variant.h" "5" "winutils.h" "5" "wizard.h" "5" "wizardpage.h" "5" @@ -3789,7 +3946,7 @@ "ansiescapecodehandler.cpp" "5" "appmainwindow.cpp" "5" "basetreeview.cpp" "5" -"bracematcher.cpp" "5" +"benchmarker.cpp" "5" "buildablehelperlibrary.cpp" "5" "categorysortfiltermodel.cpp" "5" "changeset.cpp" "5" @@ -3799,6 +3956,8 @@ "completinglineedit.cpp" "5" "completingtextedit.cpp" "5" "consoleprocess.cpp" "5" +"consoleprocess_unix.cpp" "5" +"consoleprocess_win.cpp" "5" "crumblepath.cpp" "5" "detailsbutton.cpp" "5" "detailswidget.cpp" "5" @@ -3813,13 +3972,16 @@ "faketooltip.cpp" "5" "fancylineedit.cpp" "5" "fancymainwindow.cpp" "5" +"filecrumblabel.cpp" "5" "fileinprojectfinder.cpp" "5" "filenamevalidatinglineedit.cpp" "5" "filesearch.cpp" "5" "filesystemwatcher.cpp" "5" "fileutils.cpp" "5" "filewizardpage.cpp" "5" +"fixedsizeclicklabel.cpp" "5" "flowlayout.cpp" "5" +"fuzzymatcher.cpp" "5" "guard.cpp" "5" "headerviewstretcher.cpp" "5" "highlightingitemdelegate.cpp" "5" @@ -3829,7 +3991,6 @@ "icon.cpp" "5" "itemviews.cpp" "5" "json.cpp" "5" -"linecolumnlabel.cpp" "5" "macroexpander.cpp" "5" "navigationtreeview.cpp" "5" "networkaccessmanager.cpp" "5" @@ -3851,9 +4012,11 @@ "qtcolorbutton.cpp" "5" "qtcprocess.cpp" "5" "reloadpromptutils.cpp" "5" +"removefiledialog.cpp" "5" "runextensions.cpp" "5" "savedaction.cpp" "5" "savefile.cpp" "5" +"settingsaccessor.cpp" "5" "settingsselector.cpp" "5" "shellcommand.cpp" "5" "shellcommandpage.cpp" "5" @@ -3868,10 +4031,12 @@ "textfieldcheckbox.cpp" "5" "textfieldcombobox.cpp" "5" "textfileformat.cpp" "5" +"textutils.cpp" "5" "treemodel.cpp" "5" "treeviewcombobox.cpp" "5" "uncommentselection.cpp" "5" "unixutils.cpp" "5" +"url.cpp" "5" "utilsicons.cpp" "5" "winutils.cpp" "5" "wizard.cpp" "5" @@ -3881,10 +4046,13 @@ "newclasswidget.ui" "5" "projectintropage.ui" "5" "proxycredentialsdialog.ui" "5" +"removefiledialog.ui" "5" "Resources" "4" "utils.qrc" "5" "/utils" "6" "images" "7" +"app-on-top.png" "8" +"app-on-top@2x.png" "8" "arrow.png" "8" "arrowdown.png" "8" "arrowdown@2x.png" "8" @@ -3900,22 +4068,35 @@ "clean_pane_small@2x.png" "8" "close.png" "8" "close@2x.png" "8" +"codemodelerror.png" "8" +"codemodelerror@2x.png" "8" +"codemodelwarning.png" "8" +"codemodelwarning@2x.png" "8" "collapse.png" "8" "collapse@2x.png" "8" "compile_error_taskbar.png" "8" "compile_error_taskbar@2x.png" "8" -"crumblepath-segment-end.png" "8" -"crumblepath-segment-hover-end.png" "8" -"crumblepath-segment-hover.png" "8" -"crumblepath-segment-selected-end.png" "8" -"crumblepath-segment-selected.png" "8" -"crumblepath-segment.png" "8" +"crumblepath-segment-first-hover.png" "8" +"crumblepath-segment-first-hover@2x.png" "8" +"crumblepath-segment-first.png" "8" +"crumblepath-segment-first@2x.png" "8" +"crumblepath-segment-last-hover.png" "8" +"crumblepath-segment-last-hover@2x.png" "8" +"crumblepath-segment-last.png" "8" +"crumblepath-segment-last@2x.png" "8" +"crumblepath-segment-middle-hover.png" "8" +"crumblepath-segment-middle-hover@2x.png" "8" +"crumblepath-segment-middle.png" "8" +"crumblepath-segment-middle@2x.png" "8" +"crumblepath-segment-single-hover.png" "8" +"crumblepath-segment-single-hover@2x.png" "8" +"crumblepath-segment-single.png" "8" +"crumblepath-segment-single@2x.png" "8" "dark_fileicon.png" "8" "dark_foldericon.png" "8" "Desktop.png" "8" "desktopdevicesmall.png" "8" "desktopdevicesmall@2x.png" "8" -"dir.png" "8" "editclear.png" "8" "editclear@2x.png" "8" "editcopy.png" "8" @@ -3925,6 +4106,7 @@ "editpaste.png" "8" "editpaste@2x.png" "8" "empty14.png" "8" +"empty16.png" "8" "error.png" "8" "error@2x.png" "8" "expand.png" "8" @@ -3935,6 +4117,10 @@ "eye_closed@2x.png" "8" "eye_open.png" "8" "eye_open@2x.png" "8" +"fileexport.png" "8" +"fileexport@2x.png" "8" +"filemultiexport.png" "8" +"filemultiexport@2x.png" "8" "filenew.png" "8" "filenew@2x.png" "8" "fileopen.png" "8" @@ -3947,11 +4133,14 @@ "filtericon@2x.png" "8" "fittoview.png" "8" "fittoview@2x.png" "8" -"help.png" "8" +"home.png" "8" +"home@2x.png" "8" "iconoverlay_add.png" "8" "iconoverlay_add@2x.png" "8" "iconoverlay_add_background.png" "8" "iconoverlay_add_background@2x.png" "8" +"iconoverlay_add_small.png" "8" +"iconoverlay_add_small@2x.png" "8" "iconoverlay_error.png" "8" "iconoverlay_error@2x.png" "8" "iconoverlay_error_background.png" "8" @@ -3972,6 +4161,10 @@ "interrupt_small@2x.png" "8" "leftsidebaricon.png" "8" "leftsidebaricon@2x.png" "8" +"lightbulb.png" "8" +"lightbulb@2x.png" "8" +"lightbulbcap.png" "8" +"lightbulbcap@2x.png" "8" "linkicon.png" "8" "linkicon@2x.png" "8" "locked.png" "8" @@ -4014,6 +4207,8 @@ "progressindicator_medium@2x.png" "8" "progressindicator_small.png" "8" "progressindicator_small@2x.png" "8" +"project.png" "8" +"project@2x.png" "8" "redo.png" "8" "redo@2x.png" "8" "reload_gray.png" "8" @@ -4028,6 +4223,8 @@ "rightsidebaricon@2x.png" "8" "run_small.png" "8" "run_small@2x.png" "8" +"select.png" "8" +"select@2x.png" "8" "snapshot.png" "8" "snapshot@2x.png" "8" "splitbutton_closebottom.png" "8" @@ -4044,10 +4241,10 @@ "splitbutton_vertical@2x.png" "8" "stop_small.png" "8" "stop_small@2x.png" "8" -"triangle_vert.png" "8" +"toolbuttonexpandarrow.png" "8" +"toolbuttonexpandarrow@2x.png" "8" "undo.png" "8" "undo@2x.png" "8" -"unknownfile.png" "8" "unlocked.png" "8" "unlocked@2x.png" "8" "warning.png" "8" @@ -4129,7 +4326,6 @@ "Headers" "3" "adbcommandswidget.h" "4" "android_global.h" "4" -"androidanalyzesupport.h" "4" "androidavdmanager.h" "4" "androidbuildapkstep.h" "4" "androidbuildapkwidget.h" "4" @@ -4151,17 +4347,21 @@ "androidmanifesteditor.h" "4" "androidmanifesteditorfactory.h" "4" "androidmanifesteditorwidget.h" "4" +"androidpackageinstallationstep.h" "4" "androidplugin.h" "4" "androidpotentialkit.h" "4" +"androidqmltoolingsupport.h" "4" "androidqtsupport.h" "4" "androidqtversion.h" "4" "androidqtversionfactory.h" "4" "androidrunconfiguration.h" "4" -"androidrunconfigurationwidget.h" "4" "androidruncontrol.h" "4" -"androidrunnable.h" "4" "androidrunner.h" "4" +"androidrunnerworker.h" "4" "androidsdkmanager.h" "4" +"androidsdkmanagerwidget.h" "4" +"androidsdkmodel.h" "4" +"androidsdkpackage.h" "4" "androidsettingspage.h" "4" "androidsettingswidget.h" "4" "androidsignaloperation.h" "4" @@ -4174,7 +4374,6 @@ "javaparser.h" "4" "Sources" "3" "adbcommandswidget.cpp" "4" -"androidanalyzesupport.cpp" "4" "androidavdmanager.cpp" "4" "androidbuildapkstep.cpp" "4" "androidbuildapkwidget.cpp" "4" @@ -4194,17 +4393,21 @@ "androidmanifesteditor.cpp" "4" "androidmanifesteditorfactory.cpp" "4" "androidmanifesteditorwidget.cpp" "4" +"androidpackageinstallationstep.cpp" "4" "androidplugin.cpp" "4" "androidpotentialkit.cpp" "4" +"androidqmltoolingsupport.cpp" "4" "androidqtsupport.cpp" "4" "androidqtversion.cpp" "4" "androidqtversionfactory.cpp" "4" "androidrunconfiguration.cpp" "4" -"androidrunconfigurationwidget.cpp" "4" "androidruncontrol.cpp" "4" -"androidrunnable.cpp" "4" "androidrunner.cpp" "4" +"androidrunnerworker.cpp" "4" "androidsdkmanager.cpp" "4" +"androidsdkmanagerwidget.cpp" "4" +"androidsdkmodel.cpp" "4" +"androidsdkpackage.cpp" "4" "androidsettingspage.cpp" "4" "androidsettingswidget.cpp" "4" "androidsignaloperation.cpp" "4" @@ -4222,7 +4425,7 @@ "androidcreatekeystorecertificate.ui" "4" "androiddeployqtwidget.ui" "4" "androiddevicedialog.ui" "4" -"androidrunconfigurationwidget.ui" "4" +"androidsdkmanagerwidget.ui" "4" "androidsettingswidget.ui" "4" "Resources" "3" "android.qrc" "4" @@ -4293,6 +4496,8 @@ "qtsupport_dependencies.pri" "5" "rpath" "4" "rpath.pri" "5" +"texteditor_dependencies" "4" +"texteditor_dependencies.pri" "5" "Headers" "4" "shared" "5" "qtcreator_gui_pch.h" "6" @@ -4341,6 +4546,7 @@ "itestsettingspage.h" "4" "testcodeparser.h" "4" "testconfiguration.h" "4" +"testeditormark.h" "4" "testframeworkmanager.h" "4" "testnavigationwidget.h" "4" "testoutputreader.h" "4" @@ -4391,6 +4597,7 @@ "itestparser.cpp" "4" "testcodeparser.cpp" "4" "testconfiguration.cpp" "4" +"testeditormark.cpp" "4" "testframeworkmanager.cpp" "4" "testnavigationwidget.cpp" "4" "testoutputreader.cpp" "4" @@ -4413,17 +4620,21 @@ "testsettingspage.ui" "4" "Resources" "3" "autotest.qrc" "4" -"/" "5" +"/autotest" "5" "images" "6" -"autotest.png" "7" "benchmark.png" "7" +"benchmark@2x.png" "7" "data.png" "7" "leafsort.png" "7" "leafsort@2x.png" "7" +"run_file.png" "7" +"run_file@2x.png" "7" "runselected_boxes.png" "7" "runselected_boxes@2x.png" "7" "runselected_tickmarks.png" "7" "runselected_tickmarks@2x.png" "7" +"settingscategory_autotest.png" "7" +"settingscategory_autotest@2x.png" "7" "sort.png" "7" "sort@2x.png" "7" "text.png" "7" @@ -4647,8 +4858,6 @@ "texteditor_dependencies.pri" "6" "utils_dependencies" "5" "utils_dependencies.pri" "6" -"qtsupport_dependencies" "4" -"qtsupport_dependencies.pri" "5" "rpath" "4" "rpath.pri" "5" "Headers" "4" @@ -4668,8 +4877,6 @@ "baremetalgdbcommandsdeploystep.h" "4" "baremetalplugin.h" "4" "baremetalrunconfiguration.h" "4" -"baremetalrunconfigurationfactory.h" "4" -"baremetalrunconfigurationwidget.h" "4" "defaultgdbserverprovider.h" "4" "gdbserverprovider.h" "4" "gdbserverproviderchooser.h" "4" @@ -4689,8 +4896,6 @@ "baremetalgdbcommandsdeploystep.cpp" "4" "baremetalplugin.cpp" "4" "baremetalrunconfiguration.cpp" "4" -"baremetalrunconfigurationfactory.cpp" "4" -"baremetalrunconfigurationwidget.cpp" "4" "defaultgdbserverprovider.cpp" "4" "gdbserverprovider.cpp" "4" "gdbserverproviderchooser.cpp" "4" @@ -4899,8 +5104,8 @@ "beautifier.qrc" "4" "/beautifier" "5" "images" "6" -"beautifier.png" "7" -"beautifier@2x.png" "7" +"settingscategory_beautifier.png" "7" +"settingscategory_beautifier@2x.png" "7" "Other files" "3" "beautifier.qbs" "4" "beautifier_dependencies" "2" @@ -4986,55 +5191,55 @@ "Bookmarks.json.in" "6" "Headers" "3" "bookmark.h" "4" +"bookmarkfilter.h" "4" "bookmarkmanager.h" "4" "bookmarks_global.h" "4" "bookmarksplugin.h" "4" "Sources" "3" "bookmark.cpp" "4" +"bookmarkfilter.cpp" "4" "bookmarkmanager.cpp" "4" "bookmarksplugin.cpp" "4" "Other files" "3" "bookmarks.qbs" "4" "bookmarks_dependencies" "2" "bookmarks_dependencies.pri" "3" -"clangstaticanalyzer" "2" -"clangstaticanalyzer.pro" "3" +"clangcodemodel" "2" +"clangcodemodel.pro" "3" +"clang_defines" "3" +"clang_defines.pri" "4" +"clang_installation" "3" +"clang_installation.pri" "4" "qtcreatorplugin" "3" "qtcreatorplugin.pri" "4" -"clangstaticanalyzer_dependencies" "4" -"clangstaticanalyzer_dependencies.pri" "5" +"clangcodemodel_dependencies" "4" +"clangcodemodel_dependencies.pri" "5" +"coreplugin_dependencies" "4" +"coreplugin_dependencies.pri" "5" +"cppeditor_dependencies" "4" +"cppeditor_dependencies.pri" "5" "cpptools_dependencies" "4" "cpptools_dependencies.pri" "5" -"debugger_dependencies" "4" -"debugger_dependencies.pri" "5" -"qbsprojectmanager_dependencies" "4" -"qbsprojectmanager_dependencies.pri" "5" "qmakeprojectmanager_dependencies" "4" "qmakeprojectmanager_dependencies.pri" "5" "qtcreator" "4" "qtcreator.pri" "5" "aggregation_dependencies" "5" "aggregation_dependencies.pri" "6" +"clangsupport_dependencies" "5" +"clangsupport_dependencies.pri" "6" "coreplugin_dependencies" "5" "coreplugin_dependencies.pri" "6" "cplusplus_dependencies" "5" "cplusplus_dependencies.pri" "6" "cpptools_dependencies" "5" "cpptools_dependencies.pri" "6" -"debugger_dependencies" "5" -"debugger_dependencies.pri" "6" "extensionsystem_dependencies" "5" "extensionsystem_dependencies.pri" "6" -"languageutils_dependencies" "5" -"languageutils_dependencies.pri" "6" "projectexplorer_dependencies" "5" "projectexplorer_dependencies.pri" "6" -"qmldebug_dependencies" "5" -"qmldebug_dependencies.pri" "6" -"qmljs_dependencies" "5" -"qmljs_dependencies.pri" "6" -"qtsupport_dependencies" "5" -"qtsupport_dependencies.pri" "6" +"sqlite_dependencies" "5" +"sqlite_dependencies.pri" "6" "ssh_dependencies" "5" "ssh_dependencies.pri" "6" "texteditor_dependencies" "5" @@ -5043,99 +5248,213 @@ "utils_dependencies.pri" "6" "rpath" "4" "rpath.pri" "5" +"texteditor_dependencies" "4" +"texteditor_dependencies.pri" "5" "Headers" "4" "shared" "5" "qtcreator_gui_pch.h" "6" "Other files" "4" -"ClangStaticAnalyzer.json.in" "6" +"ClangCodeModel.json.in" "6" "Headers" "3" -"clangstaticanalyzer_global.h" "4" -"clangstaticanalyzerconfigwidget.h" "4" -"clangstaticanalyzerconstants.h" "4" -"clangstaticanalyzerdiagnostic.h" "4" -"clangstaticanalyzerdiagnosticmodel.h" "4" -"clangstaticanalyzerdiagnosticview.h" "4" -"clangstaticanalyzerlogfilereader.h" "4" -"clangstaticanalyzerplugin.h" "4" -"clangstaticanalyzerpreconfiguredsessiontests.h" "4" -"clangstaticanalyzerprojectsettings.h" "4" -"clangstaticanalyzerprojectsettingsmanager.h" "4" -"clangstaticanalyzerprojectsettingswidget.h" "4" -"clangstaticanalyzerruncontrol.h" "4" -"clangstaticanalyzerrunner.h" "4" -"clangstaticanalyzersettings.h" "4" -"clangstaticanalyzertool.h" "4" -"clangstaticanalyzerunittests.h" "4" -"clangstaticanalyzerutils.h" "4" +"test" "4" +"clangautomationutils.h" "5" +"clangbatchfileprocessor.h" "5" +"clangcodecompletion_test.h" "5" +"clangactivationsequencecontextprocessor.h" "4" +"clangactivationsequenceprocessor.h" "4" +"clangassistproposal.h" "4" +"clangassistproposalitem.h" "4" +"clangassistproposalmodel.h" "4" +"clangbackendcommunicator.h" "4" +"clangbackendlogging.h" "4" +"clangbackendreceiver.h" "4" +"clangbackendsender.h" "4" +"clangcodemodelplugin.h" "4" +"clangcompletionassistinterface.h" "4" +"clangcompletionassistprocessor.h" "4" +"clangcompletionassistprovider.h" "4" +"clangcompletionchunkstotextconverter.h" "4" +"clangcompletioncontextanalyzer.h" "4" +"clangconstants.h" "4" +"clangcurrentdocumentfilter.h" "4" +"clangdiagnosticfilter.h" "4" +"clangdiagnosticmanager.h" "4" +"clangdiagnostictooltipwidget.h" "4" +"clangeditordocumentparser.h" "4" +"clangeditordocumentprocessor.h" "4" +"clangfixitoperation.h" "4" +"clangfixitoperationsextractor.h" "4" +"clangfollowsymbol.h" "4" +"clangfunctionhintmodel.h" "4" +"clanghighlightingresultreporter.h" "4" +"clanghoverhandler.h" "4" +"clangisdiagnosticrelatedtolocation.h" "4" +"clangmodelmanagersupport.h" "4" +"clangoverviewmodel.h" "4" +"clangpreprocessorassistproposalitem.h" "4" +"clangprojectsettings.h" "4" +"clangprojectsettingswidget.h" "4" +"clangrefactoringengine.h" "4" +"clangtextmark.h" "4" +"clanguiheaderondiskmanager.h" "4" +"clangutils.h" "4" "Sources" "3" -"clangstaticanalyzerconfigwidget.cpp" "4" -"clangstaticanalyzerdiagnostic.cpp" "4" -"clangstaticanalyzerdiagnosticmodel.cpp" "4" -"clangstaticanalyzerdiagnosticview.cpp" "4" -"clangstaticanalyzerlogfilereader.cpp" "4" -"clangstaticanalyzerplugin.cpp" "4" -"clangstaticanalyzerpreconfiguredsessiontests.cpp" "4" -"clangstaticanalyzerprojectsettings.cpp" "4" -"clangstaticanalyzerprojectsettingsmanager.cpp" "4" -"clangstaticanalyzerprojectsettingswidget.cpp" "4" -"clangstaticanalyzerruncontrol.cpp" "4" -"clangstaticanalyzerrunner.cpp" "4" -"clangstaticanalyzersettings.cpp" "4" -"clangstaticanalyzertool.cpp" "4" -"clangstaticanalyzerunittests.cpp" "4" -"clangstaticanalyzerutils.cpp" "4" +"test" "4" +"clangautomationutils.cpp" "5" +"clangbatchfileprocessor.cpp" "5" +"clangcodecompletion_test.cpp" "5" +"clangactivationsequencecontextprocessor.cpp" "4" +"clangactivationsequenceprocessor.cpp" "4" +"clangassistproposal.cpp" "4" +"clangassistproposalitem.cpp" "4" +"clangassistproposalmodel.cpp" "4" +"clangbackendcommunicator.cpp" "4" +"clangbackendlogging.cpp" "4" +"clangbackendreceiver.cpp" "4" +"clangbackendsender.cpp" "4" +"clangcodemodelplugin.cpp" "4" +"clangcompletionassistinterface.cpp" "4" +"clangcompletionassistprocessor.cpp" "4" +"clangcompletionassistprovider.cpp" "4" +"clangcompletionchunkstotextconverter.cpp" "4" +"clangcompletioncontextanalyzer.cpp" "4" +"clangcurrentdocumentfilter.cpp" "4" +"clangdiagnosticfilter.cpp" "4" +"clangdiagnosticmanager.cpp" "4" +"clangdiagnostictooltipwidget.cpp" "4" +"clangeditordocumentparser.cpp" "4" +"clangeditordocumentprocessor.cpp" "4" +"clangfixitoperation.cpp" "4" +"clangfixitoperationsextractor.cpp" "4" +"clangfollowsymbol.cpp" "4" +"clangfunctionhintmodel.cpp" "4" +"clanghighlightingresultreporter.cpp" "4" +"clanghoverhandler.cpp" "4" +"clangmodelmanagersupport.cpp" "4" +"clangoverviewmodel.cpp" "4" +"clangpreprocessorassistproposalitem.cpp" "4" +"clangprojectsettings.cpp" "4" +"clangprojectsettingswidget.cpp" "4" +"clangrefactoringengine.cpp" "4" +"clangtextmark.cpp" "4" +"clanguiheaderondiskmanager.cpp" "4" +"clangutils.cpp" "4" "Forms" "3" -"clangstaticanalyzerconfigwidget.ui" "4" -"clangstaticanalyzerprojectsettingswidget.ui" "4" +"clangprojectsettingswidget.ui" "4" "Resources" "3" -"clangstaticanalyzerunittests.qrc" "4" -"/" "5" -"unit-tests" "6" -"qt-essential-includes" "7" -"main.cpp" "8" -"qt-essential-includes.pro" "8" -"qt-essential-includes.qbs" "8" +"/unittests/ClangCodeModel" "5" +"exampleIncludeDir" "6" +"mylib" "7" +"mylib.h" "8" +"file.h" "7" +"otherFile.h" "7" +"qt-widgets-app" "6" +"main.cpp" "7" +"mainwindow.cpp" "7" +"mainwindow.h" "7" +"mainwindow.ui" "7" +"qt-widgets-app.pro" "7" +"completionWithProject.cpp" "6" +"constructorCompletion.cpp" "6" +"dotToArrowCorrection.cpp" "6" +"doxygenKeywordsCompletion.cpp" "6" +"functionCompletion.cpp" "6" +"globalCompletion.cpp" "6" +"includeDirectiveCompletion.cpp" "6" +"memberCompletion.cpp" "6" +"myheader.h" "6" +"mysource.cpp" "6" +"noDotToArrowCorrectionForFloats.cpp" "6" +"objc_messages_1.mm" "6" +"objc_messages_2.mm" "6" +"objc_messages_3.mm" "6" +"preprocessorKeywordsCompletion.cpp" "6" +"Other files" "3" +"creator-clang-codemodel.qdoc" "5" +"clangtestdata.qrc" "5" +"/unittests/ClangCodeModel" "6" +"exampleIncludeDir" "7" +"mylib" "8" +"mylib.h" "9" +"file.h" "8" +"otherFile.h" "8" "qt-widgets-app" "7" "main.cpp" "8" "mainwindow.cpp" "8" "mainwindow.h" "8" "mainwindow.ui" "8" "qt-widgets-app.pro" "8" -"qt-widgets-app.qbs" "8" -"simple" "7" -"main.cpp" "8" -"simple.pro" "8" -"simple.qbs" "8" -"simple-library" "7" -"simple-library.cpp" "8" -"simple-library.h" "8" -"simple-library.pro" "8" -"simple-library.qbs" "8" -"stdc++11-includes" "7" -"main.cpp" "8" -"stdc++11-includes.pro" "8" -"stdc++11-includes.qbs" "8" -"Other files" "3" -"creator-clang-static-analyzer.qdoc" "5" -"clangstaticanalyzer.qbs" "4" -"clangstaticanalyzer_dependencies" "2" -"clangstaticanalyzer_dependencies.pri" "3" -"classview" "2" -"classview.pro" "3" +"completionWithProject.cpp" "7" +"constructorCompletion.cpp" "7" +"dotToArrowCorrection.cpp" "7" +"doxygenKeywordsCompletion.cpp" "7" +"functionCompletion.cpp" "7" +"globalCompletion.cpp" "7" +"includeDirectiveCompletion.cpp" "7" +"memberCompletion.cpp" "7" +"myheader.h" "7" +"mysource.cpp" "7" +"noDotToArrowCorrectionForFloats.cpp" "7" +"objc_messages_1.mm" "7" +"objc_messages_2.mm" "7" +"objc_messages_3.mm" "7" +"preprocessorKeywordsCompletion.cpp" "7" +"completionWithProject.cpp" "5" +"constructorCompletion.cpp" "5" +"dotToArrowCorrection.cpp" "5" +"doxygenKeywordsCompletion.cpp" "5" +"functionCompletion.cpp" "5" +"globalCompletion.cpp" "5" +"includeDirectiveCompletion.cpp" "5" +"memberCompletion.cpp" "5" +"myheader.h" "5" +"mysource.cpp" "5" +"noDotToArrowCorrectionForFloats.cpp" "5" +"objc_messages_1.mm" "5" +"objc_messages_2.mm" "5" +"objc_messages_3.mm" "5" +"preprocessorKeywordsCompletion.cpp" "5" +"clangcodemodel.qbs" "4" +"README" "4" +"clangcodemodel_dependencies" "2" +"clangcodemodel_dependencies.pri" "3" +"clangpchmanager" "2" +"clangpchmanager.pro" "3" +"clang_defines" "3" +"clang_defines.pri" "4" +"clang_installation" "3" +"clang_installation.pri" "4" +"clangpchmanager-source" "3" +"clangpchmanager-source.pri" "4" +"Headers" "4" +"clangpchmanager_global.h" "5" +"pchmanagerclient.h" "5" +"pchmanagerconnectionclient.h" "5" +"pchmanagernotifierinterface.h" "5" +"pchmanagerprojectupdater.h" "5" +"precompiledheaderstorage.h" "5" +"precompiledheaderstorageinterface.h" "5" +"projectupdater.h" "5" +"Sources" "4" +"pchmanagerclient.cpp" "5" +"pchmanagerconnectionclient.cpp" "5" +"pchmanagernotifierinterface.cpp" "5" +"pchmanagerprojectupdater.cpp" "5" +"projectupdater.cpp" "5" "qtcreatorplugin" "3" "qtcreatorplugin.pri" "4" -"classview_dependencies" "4" -"classview_dependencies.pri" "5" +"clangpchmanager_dependencies" "4" +"clangpchmanager_dependencies.pri" "5" "coreplugin_dependencies" "4" "coreplugin_dependencies.pri" "5" "cpptools_dependencies" "4" "cpptools_dependencies.pri" "5" -"projectexplorer_dependencies" "4" -"projectexplorer_dependencies.pri" "5" "qtcreator" "4" "qtcreator.pri" "5" "aggregation_dependencies" "5" "aggregation_dependencies.pri" "6" +"clangsupport_dependencies" "5" +"clangsupport_dependencies.pri" "6" "coreplugin_dependencies" "5" "coreplugin_dependencies.pri" "6" "cplusplus_dependencies" "5" @@ -5146,6 +5465,8 @@ "extensionsystem_dependencies.pri" "6" "projectexplorer_dependencies" "5" "projectexplorer_dependencies.pri" "6" +"sqlite_dependencies" "5" +"sqlite_dependencies.pri" "6" "ssh_dependencies" "5" "ssh_dependencies.pri" "6" "texteditor_dependencies" "5" @@ -5154,102 +5475,414 @@ "utils_dependencies.pri" "6" "rpath" "4" "rpath.pri" "5" -"texteditor_dependencies" "4" -"texteditor_dependencies.pri" "5" "Headers" "4" "shared" "5" "qtcreator_gui_pch.h" "6" "Other files" "4" -"ClassView.json.in" "6" +"ClangPchManager.json.in" "6" "Headers" "3" -"classviewconstants.h" "4" -"classviewmanager.h" "4" -"classviewnavigationwidget.h" "4" -"classviewnavigationwidgetfactory.h" "4" -"classviewparser.h" "4" -"classviewparsertreeitem.h" "4" -"classviewplugin.h" "4" -"classviewsymbolinformation.h" "4" -"classviewsymbollocation.h" "4" -"classviewtreeitemmodel.h" "4" -"classviewutils.h" "4" +"clangpchmanagerplugin.h" "4" +"qtcreatorprojectupdater.h" "4" "Sources" "3" -"classviewmanager.cpp" "4" -"classviewnavigationwidget.cpp" "4" -"classviewnavigationwidgetfactory.cpp" "4" -"classviewparser.cpp" "4" -"classviewparsertreeitem.cpp" "4" -"classviewplugin.cpp" "4" -"classviewsymbolinformation.cpp" "4" -"classviewsymbollocation.cpp" "4" -"classviewtreeitemmodel.cpp" "4" -"classviewutils.cpp" "4" +"clangpchmanagerplugin.cpp" "4" +"qtcreatorprojectupdater.cpp" "4" "Other files" "3" -"classview.qbs" "4" -"classview_dependencies" "2" -"classview_dependencies.pri" "3" -"clearcase" "2" -"clearcase.pro" "3" +"clangpchmanager.qbs" "4" +"clangpchmanager_dependencies" "2" +"clangpchmanager_dependencies.pri" "3" +"clangrefactoring" "2" +"clangrefactoring.pro" "3" +"clang_defines" "3" +"clang_defines.pri" "4" +"clang_installation" "3" +"clang_installation.pri" "4" +"clangrefactoring-source" "3" +"clangrefactoring-source.pri" "4" +"Headers" "4" +"clangqueryexamplehighlighter.h" "5" +"clangqueryexamplehighlightmarker.h" "5" +"clangqueryhighlighter.h" "5" +"clangqueryhighlightmarker.h" "5" +"clangqueryprojectsfindfilter.h" "5" +"editormanagerinterface.h" "5" +"locatorfilter.h" "5" +"projectpartproviderinterface.h" "5" +"projectpartutilities.h" "5" +"refactoringclient.h" "5" +"refactoringconnectionclient.h" "5" +"refactoringengine.h" "5" +"refactoringprojectupdater.h" "5" +"searchhandle.h" "5" +"searchinterface.h" "5" +"symbol.h" "5" +"symbolqueryinterface.h" "5" +"symbolsfindfilter.h" "5" +"Sources" "4" +"clangqueryexamplehighlighter.cpp" "5" +"clangqueryhighlighter.cpp" "5" +"clangqueryprojectsfindfilter.cpp" "5" +"locatorfilter.cpp" "5" +"projectpartutilities.cpp" "5" +"refactoringclient.cpp" "5" +"refactoringconnectionclient.cpp" "5" +"refactoringengine.cpp" "5" +"refactoringprojectupdater.cpp" "5" +"searchhandle.cpp" "5" +"symbolsfindfilter.cpp" "5" "qtcreatorplugin" "3" "qtcreatorplugin.pri" "4" -"clearcase_dependencies" "4" -"clearcase_dependencies.pri" "5" +"clangpchmanager_dependencies" "4" +"clangpchmanager_dependencies.pri" "5" +"clangrefactoring_dependencies" "4" +"clangrefactoring_dependencies.pri" "5" "coreplugin_dependencies" "4" "coreplugin_dependencies.pri" "5" -"projectexplorer_dependencies" "4" -"projectexplorer_dependencies.pri" "5" +"cpptools_dependencies" "4" +"cpptools_dependencies.pri" "5" "qtcreator" "4" "qtcreator.pri" "5" "aggregation_dependencies" "5" "aggregation_dependencies.pri" "6" +"clangpchmanager_dependencies" "5" +"clangpchmanager_dependencies.pri" "6" +"clangsupport_dependencies" "5" +"clangsupport_dependencies.pri" "6" "coreplugin_dependencies" "5" "coreplugin_dependencies.pri" "6" "cplusplus_dependencies" "5" "cplusplus_dependencies.pri" "6" "cpptools_dependencies" "5" "cpptools_dependencies.pri" "6" -"diffeditor_dependencies" "5" -"diffeditor_dependencies.pri" "6" "extensionsystem_dependencies" "5" "extensionsystem_dependencies.pri" "6" "projectexplorer_dependencies" "5" "projectexplorer_dependencies.pri" "6" +"sqlite_dependencies" "5" +"sqlite_dependencies.pri" "6" "ssh_dependencies" "5" "ssh_dependencies.pri" "6" "texteditor_dependencies" "5" "texteditor_dependencies.pri" "6" "utils_dependencies" "5" "utils_dependencies.pri" "6" -"vcsbase_dependencies" "5" -"vcsbase_dependencies.pri" "6" "rpath" "4" "rpath.pri" "5" "texteditor_dependencies" "4" "texteditor_dependencies.pri" "5" -"vcsbase_dependencies" "4" -"vcsbase_dependencies.pri" "5" "Headers" "4" "shared" "5" "qtcreator_gui_pch.h" "6" "Other files" "4" -"ClearCase.json.in" "6" +"ClangRefactoring.json.in" "6" "Headers" "3" -"activityselector.h" "4" -"annotationhighlighter.h" "4" -"checkoutdialog.h" "4" -"clearcaseconstants.h" "4" -"clearcasecontrol.h" "4" -"clearcaseeditor.h" "4" -"clearcaseplugin.h" "4" -"clearcasesettings.h" "4" -"clearcasesubmiteditor.h" "4" -"clearcasesubmiteditorwidget.h" "4" -"clearcasesync.h" "4" -"settingspage.h" "4" -"versionselector.h" "4" +"baseclangquerytexteditorwidget.h" "4" +"clangqueryexampletexteditorwidget.h" "4" +"clangqueryhoverhandler.h" "4" +"clangqueryprojectsfindfilterwidget.h" "4" +"clangquerytexteditorwidget.h" "4" +"clangrefactoringplugin.h" "4" +"qtcreatorclangqueryfindfilter.h" "4" +"qtcreatoreditormanager.h" "4" +"qtcreatorsearch.h" "4" +"qtcreatorsearchhandle.h" "4" +"qtcreatorsymbolsfindfilter.h" "4" +"querysqlitestatementfactory.h" "4" +"sourcelocations.h" "4" +"symbolquery.h" "4" +"symbolsfindfilterconfigwidget.h" "4" "Sources" "3" -"activityselector.cpp" "4" -"annotationhighlighter.cpp" "4" +"baseclangquerytexteditorwidget.cpp" "4" +"clangqueryexampletexteditorwidget.cpp" "4" +"clangqueryhoverhandler.cpp" "4" +"clangqueryprojectsfindfilterwidget.cpp" "4" +"clangquerytexteditorwidget.cpp" "4" +"clangrefactoringplugin.cpp" "4" +"qtcreatorclangqueryfindfilter.cpp" "4" +"qtcreatoreditormanager.cpp" "4" +"qtcreatorsearch.cpp" "4" +"qtcreatorsearchhandle.cpp" "4" +"qtcreatorsymbolsfindfilter.cpp" "4" +"symbolsfindfilterconfigwidget.cpp" "4" +"Forms" "3" +"clangqueryprojectsfindfilter.ui" "4" +"Other files" "3" +"clangrefactoring.qbs" "4" +"clangrefactoring_dependencies" "2" +"clangrefactoring_dependencies.pri" "3" +"clangtools" "2" +"clangtools.pro" "3" +"clang_defines" "3" +"clang_defines.pri" "4" +"clang_installation" "3" +"clang_installation.pri" "4" +"qtcreatorplugin" "3" +"qtcreatorplugin.pri" "4" +"clangtools_dependencies" "4" +"clangtools_dependencies.pri" "5" +"cpptools_dependencies" "4" +"cpptools_dependencies.pri" "5" +"debugger_dependencies" "4" +"debugger_dependencies.pri" "5" +"qbsprojectmanager_dependencies" "4" +"qbsprojectmanager_dependencies.pri" "5" +"qmakeprojectmanager_dependencies" "4" +"qmakeprojectmanager_dependencies.pri" "5" +"qtcreator" "4" +"qtcreator.pri" "5" +"aggregation_dependencies" "5" +"aggregation_dependencies.pri" "6" +"coreplugin_dependencies" "5" +"coreplugin_dependencies.pri" "6" +"cplusplus_dependencies" "5" +"cplusplus_dependencies.pri" "6" +"cpptools_dependencies" "5" +"cpptools_dependencies.pri" "6" +"debugger_dependencies" "5" +"debugger_dependencies.pri" "6" +"extensionsystem_dependencies" "5" +"extensionsystem_dependencies.pri" "6" +"languageutils_dependencies" "5" +"languageutils_dependencies.pri" "6" +"projectexplorer_dependencies" "5" +"projectexplorer_dependencies.pri" "6" +"qmldebug_dependencies" "5" +"qmldebug_dependencies.pri" "6" +"qmljs_dependencies" "5" +"qmljs_dependencies.pri" "6" +"qtsupport_dependencies" "5" +"qtsupport_dependencies.pri" "6" +"ssh_dependencies" "5" +"ssh_dependencies.pri" "6" +"texteditor_dependencies" "5" +"texteditor_dependencies.pri" "6" +"utils_dependencies" "5" +"utils_dependencies.pri" "6" +"rpath" "4" +"rpath.pri" "5" +"Headers" "4" +"shared" "5" +"qtcreator_gui_pch.h" "6" +"Other files" "4" +"ClangTools.json.in" "6" +"Headers" "3" +"clangfileinfo.h" "4" +"clangfixitsrefactoringchanges.h" "4" +"clangselectablefilesdialog.h" "4" +"clangtidyclazyruncontrol.h" "4" +"clangtidyclazyrunner.h" "4" +"clangtidyclazytool.h" "4" +"clangtool.h" "4" +"clangtoolruncontrol.h" "4" +"clangtoolrunner.h" "4" +"clangtools_global.h" "4" +"clangtoolsbasicsettings.h" "4" +"clangtoolsconfigwidget.h" "4" +"clangtoolsconstants.h" "4" +"clangtoolsdiagnostic.h" "4" +"clangtoolsdiagnosticmodel.h" "4" +"clangtoolsdiagnosticview.h" "4" +"clangtoolslogfilereader.h" "4" +"clangtoolsplugin.h" "4" +"clangtoolspreconfiguredsessiontests.h" "4" +"clangtoolsprojectsettings.h" "4" +"clangtoolsprojectsettingswidget.h" "4" +"clangtoolssettings.h" "4" +"clangtoolsunittests.h" "4" +"clangtoolsutils.h" "4" +"Sources" "3" +"clangfixitsrefactoringchanges.cpp" "4" +"clangselectablefilesdialog.cpp" "4" +"clangtidyclazyruncontrol.cpp" "4" +"clangtidyclazyrunner.cpp" "4" +"clangtidyclazytool.cpp" "4" +"clangtool.cpp" "4" +"clangtoolruncontrol.cpp" "4" +"clangtoolrunner.cpp" "4" +"clangtoolsbasicsettings.cpp" "4" +"clangtoolsconfigwidget.cpp" "4" +"clangtoolsdiagnostic.cpp" "4" +"clangtoolsdiagnosticmodel.cpp" "4" +"clangtoolsdiagnosticview.cpp" "4" +"clangtoolslogfilereader.cpp" "4" +"clangtoolsplugin.cpp" "4" +"clangtoolspreconfiguredsessiontests.cpp" "4" +"clangtoolsprojectsettings.cpp" "4" +"clangtoolsprojectsettingswidget.cpp" "4" +"clangtoolssettings.cpp" "4" +"clangtoolsunittests.cpp" "4" +"clangtoolsutils.cpp" "4" +"Forms" "3" +"clangselectablefilesdialog.ui" "4" +"clangtoolsbasicsettings.ui" "4" +"clangtoolsconfigwidget.ui" "4" +"clangtoolsprojectsettingswidget.ui" "4" +"Resources" "3" +"clangtoolsunittests.qrc" "4" +"/" "5" +"unit-tests" "6" +"clangtidy_clazy" "7" +"clangtidy_clazy.pro" "8" +"clazy_example.cpp" "8" +"tidy_example.cpp" "8" +"qt-essential-includes" "7" +"main.cpp" "8" +"qt-essential-includes.pro" "8" +"qt-essential-includes.qbs" "8" +"qt-widgets-app" "7" +"main.cpp" "8" +"mainwindow.cpp" "8" +"mainwindow.h" "8" +"mainwindow.ui" "8" +"qt-widgets-app.pro" "8" +"qt-widgets-app.qbs" "8" +"simple" "7" +"main.cpp" "8" +"simple.pro" "8" +"simple.qbs" "8" +"simple-library" "7" +"simple-library.cpp" "8" +"simple-library.h" "8" +"simple-library.pro" "8" +"simple-library.qbs" "8" +"stdc++11-includes" "7" +"main.cpp" "8" +"stdc++11-includes.pro" "8" +"stdc++11-includes.qbs" "8" +"Other files" "3" +"creator-clang-static-analyzer.qdoc" "5" +"clangtools.qbs" "4" +"clangtools_dependencies" "2" +"clangtools_dependencies.pri" "3" +"classview" "2" +"classview.pro" "3" +"qtcreatorplugin" "3" +"qtcreatorplugin.pri" "4" +"classview_dependencies" "4" +"classview_dependencies.pri" "5" +"coreplugin_dependencies" "4" +"coreplugin_dependencies.pri" "5" +"cpptools_dependencies" "4" +"cpptools_dependencies.pri" "5" +"projectexplorer_dependencies" "4" +"projectexplorer_dependencies.pri" "5" +"qtcreator" "4" +"qtcreator.pri" "5" +"aggregation_dependencies" "5" +"aggregation_dependencies.pri" "6" +"coreplugin_dependencies" "5" +"coreplugin_dependencies.pri" "6" +"cplusplus_dependencies" "5" +"cplusplus_dependencies.pri" "6" +"cpptools_dependencies" "5" +"cpptools_dependencies.pri" "6" +"extensionsystem_dependencies" "5" +"extensionsystem_dependencies.pri" "6" +"projectexplorer_dependencies" "5" +"projectexplorer_dependencies.pri" "6" +"ssh_dependencies" "5" +"ssh_dependencies.pri" "6" +"texteditor_dependencies" "5" +"texteditor_dependencies.pri" "6" +"utils_dependencies" "5" +"utils_dependencies.pri" "6" +"rpath" "4" +"rpath.pri" "5" +"texteditor_dependencies" "4" +"texteditor_dependencies.pri" "5" +"Headers" "4" +"shared" "5" +"qtcreator_gui_pch.h" "6" +"Other files" "4" +"ClassView.json.in" "6" +"Headers" "3" +"classviewconstants.h" "4" +"classviewmanager.h" "4" +"classviewnavigationwidget.h" "4" +"classviewnavigationwidgetfactory.h" "4" +"classviewparser.h" "4" +"classviewparsertreeitem.h" "4" +"classviewplugin.h" "4" +"classviewsymbolinformation.h" "4" +"classviewsymbollocation.h" "4" +"classviewtreeitemmodel.h" "4" +"classviewutils.h" "4" +"Sources" "3" +"classviewmanager.cpp" "4" +"classviewnavigationwidget.cpp" "4" +"classviewnavigationwidgetfactory.cpp" "4" +"classviewparser.cpp" "4" +"classviewparsertreeitem.cpp" "4" +"classviewplugin.cpp" "4" +"classviewsymbolinformation.cpp" "4" +"classviewsymbollocation.cpp" "4" +"classviewtreeitemmodel.cpp" "4" +"classviewutils.cpp" "4" +"Other files" "3" +"classview.qbs" "4" +"classview_dependencies" "2" +"classview_dependencies.pri" "3" +"clearcase" "2" +"clearcase.pro" "3" +"qtcreatorplugin" "3" +"qtcreatorplugin.pri" "4" +"clearcase_dependencies" "4" +"clearcase_dependencies.pri" "5" +"coreplugin_dependencies" "4" +"coreplugin_dependencies.pri" "5" +"projectexplorer_dependencies" "4" +"projectexplorer_dependencies.pri" "5" +"qtcreator" "4" +"qtcreator.pri" "5" +"aggregation_dependencies" "5" +"aggregation_dependencies.pri" "6" +"coreplugin_dependencies" "5" +"coreplugin_dependencies.pri" "6" +"cplusplus_dependencies" "5" +"cplusplus_dependencies.pri" "6" +"cpptools_dependencies" "5" +"cpptools_dependencies.pri" "6" +"diffeditor_dependencies" "5" +"diffeditor_dependencies.pri" "6" +"extensionsystem_dependencies" "5" +"extensionsystem_dependencies.pri" "6" +"projectexplorer_dependencies" "5" +"projectexplorer_dependencies.pri" "6" +"ssh_dependencies" "5" +"ssh_dependencies.pri" "6" +"texteditor_dependencies" "5" +"texteditor_dependencies.pri" "6" +"utils_dependencies" "5" +"utils_dependencies.pri" "6" +"vcsbase_dependencies" "5" +"vcsbase_dependencies.pri" "6" +"rpath" "4" +"rpath.pri" "5" +"texteditor_dependencies" "4" +"texteditor_dependencies.pri" "5" +"vcsbase_dependencies" "4" +"vcsbase_dependencies.pri" "5" +"Headers" "4" +"shared" "5" +"qtcreator_gui_pch.h" "6" +"Other files" "4" +"ClearCase.json.in" "6" +"Headers" "3" +"activityselector.h" "4" +"annotationhighlighter.h" "4" +"checkoutdialog.h" "4" +"clearcaseconstants.h" "4" +"clearcasecontrol.h" "4" +"clearcaseeditor.h" "4" +"clearcaseplugin.h" "4" +"clearcasesettings.h" "4" +"clearcasesubmiteditor.h" "4" +"clearcasesubmiteditorwidget.h" "4" +"clearcasesync.h" "4" +"settingspage.h" "4" +"versionselector.h" "4" +"Sources" "3" +"activityselector.cpp" "4" +"annotationhighlighter.cpp" "4" "checkoutdialog.cpp" "4" "clearcasecontrol.cpp" "4" "clearcaseeditor.cpp" "4" @@ -5322,6 +5955,7 @@ "CMakeProjectManager.json.in" "6" "Headers" "3" "builddirmanager.h" "4" +"builddirparameters.h" "4" "builddirreader.h" "4" "cmake_global.h" "4" "cmakeautocompleter.h" "4" @@ -5329,6 +5963,7 @@ "cmakebuildinfo.h" "4" "cmakebuildsettingswidget.h" "4" "cmakebuildstep.h" "4" +"cmakebuildtarget.h" "4" "cmakecbpparser.h" "4" "cmakeconfigitem.h" "4" "cmakeeditor.h" "4" @@ -5346,6 +5981,8 @@ "cmakeprojectplugin.h" "4" "cmakerunconfiguration.h" "4" "cmakesettingspage.h" "4" +"cmakespecificsettings.h" "4" +"cmakespecificsettingspage.h" "4" "cmaketool.h" "4" "cmaketoolmanager.h" "4" "configmodel.h" "4" @@ -5356,11 +5993,13 @@ "treescanner.h" "4" "Sources" "3" "builddirmanager.cpp" "4" +"builddirparameters.cpp" "4" "builddirreader.cpp" "4" "cmakeautocompleter.cpp" "4" "cmakebuildconfiguration.cpp" "4" "cmakebuildsettingswidget.cpp" "4" "cmakebuildstep.cpp" "4" +"cmakebuildtarget.cpp" "4" "cmakecbpparser.cpp" "4" "cmakeconfigitem.cpp" "4" "cmakeeditor.cpp" "4" @@ -5377,6 +6016,8 @@ "cmakeprojectplugin.cpp" "4" "cmakerunconfiguration.cpp" "4" "cmakesettingspage.cpp" "4" +"cmakespecificsettings.cpp" "4" +"cmakespecificsettingspage.cpp" "4" "cmaketool.cpp" "4" "cmaketoolmanager.cpp" "4" "configmodel.cpp" "4" @@ -5385,6 +6026,8 @@ "servermodereader.cpp" "4" "tealeafreader.cpp" "4" "treescanner.cpp" "4" +"Forms" "3" +"cmakespecificsettingspage.ui" "4" "Resources" "3" "cmakeproject.qrc" "4" "/cmakeproject" "5" @@ -5405,7 +6048,7 @@ "findplugin.h" "5" "findtoolbar.h" "5" "findtoolwindow.h" "5" -"highlightscrollbar.h" "5" +"highlightscrollbarcontroller.h" "5" "ifindfilter.h" "5" "ifindsupport.h" "5" "itemviewfind.h" "5" @@ -5425,7 +6068,7 @@ "findplugin.cpp" "5" "findtoolbar.cpp" "5" "findtoolwindow.cpp" "5" -"highlightscrollbar.cpp" "5" +"highlightscrollbarcontroller.cpp" "5" "ifindfilter.cpp" "5" "ifindsupport.cpp" "5" "itemviewfind.cpp" "5" @@ -5464,6 +6107,7 @@ "externaltoolsfilter.h" "5" "filesystemfilter.h" "5" "ilocatorfilter.h" "5" +"javascriptfilter.h" "5" "locator.h" "5" "locatorconstants.h" "5" "locatorfiltersfilter.h" "5" @@ -5473,6 +6117,7 @@ "locatorsettingspage.h" "5" "locatorwidget.h" "5" "opendocumentsfilter.h" "5" +"spotlightlocatorfilter.h" "5" "Sources" "4" "basefilefilter.cpp" "5" "commandlocator.cpp" "5" @@ -5481,6 +6126,7 @@ "externaltoolsfilter.cpp" "5" "filesystemfilter.cpp" "5" "ilocatorfilter.cpp" "5" +"javascriptfilter.cpp" "5" "locator.cpp" "5" "locator_test.cpp" "5" "locatorfiltersfilter.cpp" "5" @@ -5527,6 +6173,7 @@ "dialogs" "4" "addtovcsdialog.h" "5" "externaltoolconfig.h" "5" +"filepropertiesdialog.h" "5" "ioptionspage.h" "5" "newdialog.h" "5" "openwithdialog.h" "5" @@ -5594,6 +6241,7 @@ "jsexpander.h" "4" "mainwindow.h" "4" "manhattanstyle.h" "4" +"menubarfilter.h" "4" "messagebox.h" "4" "messagemanager.h" "4" "messageoutputwindow.h" "4" @@ -5611,14 +6259,12 @@ "plugindialog.h" "4" "reaper.h" "4" "reaper_p.h" "4" -"removefiledialog.h" "4" "rightpane.h" "4" "settingsdatabase.h" "4" "shellcommand.h" "4" "sidebar.h" "4" "sidebarwidget.h" "4" "statusbarmanager.h" "4" -"statusbarwidget.h" "4" "styleanimator.h" "4" "systemsettings.h" "4" "testdatadir.h" "4" @@ -5640,6 +6286,7 @@ "dialogs" "4" "addtovcsdialog.cpp" "5" "externaltoolconfig.cpp" "5" +"filepropertiesdialog.cpp" "5" "ioptionspage.cpp" "5" "newdialog.cpp" "5" "openwithdialog.cpp" "5" @@ -5664,6 +6311,8 @@ "futureprogress.cpp" "5" "progressbar.cpp" "5" "progressmanager.cpp" "5" +"progressmanager_win.cpp" "5" +"progressmanager_x11.cpp" "5" "progressview.cpp" "5" "basefilewizard.cpp" "4" "basefilewizardfactory.cpp" "4" @@ -5671,6 +6320,7 @@ "corejsextensions.cpp" "4" "coreplugin.cpp" "4" "designmode.cpp" "4" +"diffservice.cpp" "4" "documentmanager.cpp" "4" "editmode.cpp" "4" "editortoolbar.cpp" "4" @@ -5700,6 +6350,7 @@ "jsexpander.cpp" "4" "mainwindow.cpp" "4" "manhattanstyle.cpp" "4" +"menubarfilter.cpp" "4" "messagebox.cpp" "4" "messagemanager.cpp" "4" "messageoutputwindow.cpp" "4" @@ -5716,14 +6367,12 @@ "patchtool.cpp" "4" "plugindialog.cpp" "4" "reaper.cpp" "4" -"removefiledialog.cpp" "4" "rightpane.cpp" "4" "settingsdatabase.cpp" "4" "shellcommand.cpp" "4" "sidebar.cpp" "4" "sidebarwidget.cpp" "4" "statusbarmanager.cpp" "4" -"statusbarwidget.cpp" "4" "styleanimator.cpp" "4" "systemsettings.cpp" "4" "testdatadir.cpp" "4" @@ -5738,6 +6387,7 @@ "dialogs" "4" "addtovcsdialog.ui" "5" "externaltoolconfig.ui" "5" +"filepropertiesdialog.ui" "5" "newdialog.ui" "5" "openwithdialog.ui" "5" "readonlyfilesdialog.ui" "5" @@ -5745,18 +6395,17 @@ "generalsettings.ui" "4" "mimetypemagicdialog.ui" "4" "mimetypesettingspage.ui" "4" -"removefiledialog.ui" "4" "systemsettings.ui" "4" "Resources" "3" "core.qrc" "4" "/core" "5" "images" "6" -"category_core.png" "7" -"category_design.png" "7" -"category_locator.png" "7" -"category_texteditor.png" "7" "qtcreatorlogo-big.png" "7" "qtcreatorlogo-big@2x.png" "7" +"settingscategory_core.png" "7" +"settingscategory_core@2x.png" "7" +"settingscategory_design.png" "7" +"settingscategory_design@2x.png" "7" "fancyactionbar.qrc" "4" "/fancyactionbar" "5" "images" "6" @@ -5851,7 +6500,8 @@ "cpaster.qrc" "4" "/cpaster" "5" "images" "6" -"category_cpaster.png" "7" +"settingscategory_cpaster.png" "7" +"settingscategory_cpaster@2x.png" "7" "Other files" "3" "cpaster.qbs" "4" "cpaster_dependencies" "2" @@ -5911,11 +6561,9 @@ "cppeditorenums.h" "4" "cppeditorplugin.h" "4" "cppeditortestcase.h" "4" -"cppelementevaluator.h" "4" -"cppfollowsymbolundercursor.h" "4" +"cppeditorwidget.h" "4" "cppfunctiondecldeflink.h" "4" "cpphighlighter.h" "4" -"cpphoverhandler.h" "4" "cppincludehierarchy.h" "4" "cppinsertvirtualmethods.h" "4" "cpplocalrenaming.h" "4" @@ -5929,8 +6577,6 @@ "cppquickfixes.h" "4" "cpptypehierarchy.h" "4" "cppuseselectionsupdater.h" "4" -"cppvirtualfunctionassistprovider.h" "4" -"cppvirtualfunctionproposalitem.h" "4" "resourcepreviewhoverhandler.h" "4" "Sources" "3" "cppautocompleter.cpp" "4" @@ -5941,11 +6587,9 @@ "cppeditordocument.cpp" "4" "cppeditorplugin.cpp" "4" "cppeditortestcase.cpp" "4" -"cppelementevaluator.cpp" "4" -"cppfollowsymbolundercursor.cpp" "4" +"cppeditorwidget.cpp" "4" "cppfunctiondecldeflink.cpp" "4" "cpphighlighter.cpp" "4" -"cpphoverhandler.cpp" "4" "cppincludehierarchy.cpp" "4" "cppincludehierarchy_test.cpp" "4" "cppinsertvirtualmethods.cpp" "4" @@ -5961,8 +6605,6 @@ "cpptypehierarchy.cpp" "4" "cppuseselections_test.cpp" "4" "cppuseselectionsupdater.cpp" "4" -"cppvirtualfunctionassistprovider.cpp" "4" -"cppvirtualfunctionproposalitem.cpp" "4" "fileandtokenactions_test.cpp" "4" "followsymbol_switchmethoddecldef_test.cpp" "4" "resourcepreviewhoverhandler.cpp" "4" @@ -6026,15 +6668,16 @@ "CppTools.json.in" "6" "Headers" "3" "abstracteditorsupport.h" "4" +"abstractoverviewmodel.h" "4" "baseeditordocumentparser.h" "4" "baseeditordocumentprocessor.h" "4" "builtincursorinfo.h" "4" "builtineditordocumentparser.h" "4" "builtineditordocumentprocessor.h" "4" "builtinindexingsupport.h" "4" -"clangcompileroptionsbuilder.h" "4" "clangdiagnosticconfig.h" "4" "clangdiagnosticconfigsmodel.h" "4" +"clangdiagnosticconfigsselectionwidget.h" "4" "clangdiagnosticconfigswidget.h" "4" "compileroptionsbuilder.h" "4" "cppcanonicalsymbol.h" "4" @@ -6055,10 +6698,14 @@ "cppcursorinfo.h" "4" "cppdoxygen.h" "4" "cppeditoroutline.h" "4" +"cppeditorwidgetinterface.h" "4" +"cppelementevaluator.h" "4" "cppfileiterationorder.h" "4" "cppfilesettingspage.h" "4" "cppfindreferences.h" "4" +"cppfollowsymbolundercursor.h" "4" "cppfunctionsfilter.h" "4" +"cpphoverhandler.h" "4" "cppincludesfilter.h" "4" "cppindexingsupport.h" "4" "cpplocalsymbols.h" "4" @@ -6067,6 +6714,7 @@ "cppmodelmanager.h" "4" "cppmodelmanagersupport.h" "4" "cppmodelmanagersupportinternal.h" "4" +"cppoverviewmodel.h" "4" "cpppointerdeclarationformatter.h" "4" "cppprojectfile.h" "4" "cppprojectfilecategorizer.h" "4" @@ -6076,11 +6724,14 @@ "cppqtstyleindenter.h" "4" "cpprawprojectpart.h" "4" "cpprefactoringchanges.h" "4" +"cpprefactoringengine.h" "4" "cppselectionchanger.h" "4" "cppsemanticinfo.h" "4" "cppsemanticinfoupdater.h" "4" "cppsourceprocessertesthelper.h" "4" "cppsourceprocessor.h" "4" +"cppsymbolinfo.h" "4" +"cpptools_clangtidychecks.h" "4" "cpptools_global.h" "4" "cpptools_utils.h" "4" "cpptoolsbridge.h" "4" @@ -6092,9 +6743,13 @@ "cpptoolsreuse.h" "4" "cpptoolssettings.h" "4" "cpptoolstestcase.h" "4" +"cppvirtualfunctionassistprovider.h" "4" +"cppvirtualfunctionproposalitem.h" "4" "cppworkingcopy.h" "4" +"cursorineditor.h" "4" "doxygengenerator.h" "4" "editordocumenthandle.h" "4" +"followsymbolinterface.h" "4" "functionutils.h" "4" "generatedcodemodelsupport.h" "4" "includeutils.h" "4" @@ -6112,6 +6767,8 @@ "symbolfinder.h" "4" "symbolsfindfilter.h" "4" "typehierarchybuilder.h" "4" +"usages.h" "4" +"wrappablelineedit.h" "4" "Sources" "3" "abstracteditorsupport.cpp" "4" "baseeditordocumentparser.cpp" "4" @@ -6120,9 +6777,9 @@ "builtineditordocumentparser.cpp" "4" "builtineditordocumentprocessor.cpp" "4" "builtinindexingsupport.cpp" "4" -"clangcompileroptionsbuilder.cpp" "4" "clangdiagnosticconfig.cpp" "4" "clangdiagnosticconfigsmodel.cpp" "4" +"clangdiagnosticconfigsselectionwidget.cpp" "4" "clangdiagnosticconfigswidget.cpp" "4" "compileroptionsbuilder.cpp" "4" "cppcanonicalsymbol.cpp" "4" @@ -6144,11 +6801,14 @@ "cppcurrentdocumentfilter.cpp" "4" "cppdoxygen.cpp" "4" "cppeditoroutline.cpp" "4" +"cppelementevaluator.cpp" "4" "cppfileiterationorder.cpp" "4" "cppfilesettingspage.cpp" "4" "cppfindreferences.cpp" "4" +"cppfollowsymbolundercursor.cpp" "4" "cppfunctionsfilter.cpp" "4" "cppheadersource_test.cpp" "4" +"cpphoverhandler.cpp" "4" "cppincludesfilter.cpp" "4" "cppindexingsupport.cpp" "4" "cpplocalsymbols.cpp" "4" @@ -6160,6 +6820,7 @@ "cppmodelmanager_test.cpp" "4" "cppmodelmanagersupport.cpp" "4" "cppmodelmanagersupportinternal.cpp" "4" +"cppoverviewmodel.cpp" "4" "cpppointerdeclarationformatter.cpp" "4" "cpppointerdeclarationformatter_test.cpp" "4" "cppprojectfile.cpp" "4" @@ -6170,6 +6831,7 @@ "cppqtstyleindenter.cpp" "4" "cpprawprojectpart.cpp" "4" "cpprefactoringchanges.cpp" "4" +"cpprefactoringengine.cpp" "4" "cppselectionchanger.cpp" "4" "cppsemanticinfoupdater.cpp" "4" "cppsourceprocessertesthelper.cpp" "4" @@ -6182,6 +6844,8 @@ "cpptoolsreuse.cpp" "4" "cpptoolssettings.cpp" "4" "cpptoolstestcase.cpp" "4" +"cppvirtualfunctionassistprovider.cpp" "4" +"cppvirtualfunctionproposalitem.cpp" "4" "cppworkingcopy.cpp" "4" "doxygengenerator.cpp" "4" "editordocumenthandle.cpp" "4" @@ -6202,16 +6866,21 @@ "symbolsfindfilter.cpp" "4" "typehierarchybuilder.cpp" "4" "typehierarchybuilder_test.cpp" "4" +"wrappablelineedit.cpp" "4" "Forms" "3" +"clangbasechecks.ui" "4" "clangdiagnosticconfigswidget.ui" "4" +"clazychecks.ui" "4" "cppcodemodelsettingspage.ui" "4" "cppcodestylesettingspage.ui" "4" "cppfilesettingspage.ui" "4" +"tidychecks.ui" "4" "Resources" "3" "cpptools.qrc" "4" "/cpptools" "5" "images" "6" -"category_cpp.png" "7" +"settingscategory_cpp.png" "7" +"settingscategory_cpp@2x.png" "7" "Other files" "3" "cpptools.qbs" "4" "cpptools_dependencies" "2" @@ -6291,6 +6960,7 @@ "analyzer.pri" "4" "Headers" "4" "analyzerconstants.h" "5" +"analyzericons.h" "5" "analyzermanager.h" "5" "analyzerrunconfigwidget.h" "5" "analyzerutils.h" "5" @@ -6307,7 +6977,8 @@ "analyzerbase.qrc" "5" "/" "6" "images" "7" -"analyzer_category.png" "8" +"settingscategory_analyzer.png" "8" +"settingscategory_analyzer@2x.png" "8" "cdb" "3" "cdb.pri" "4" "Headers" "4" @@ -6343,28 +7014,22 @@ "gdb" "3" "gdb.pri" "4" "Headers" "4" -"attachgdbadapter.h" "5" -"coregdbadapter.h" "5" "gdbengine.h" "5" -"gdbplainengine.h" "5" -"remotegdbserveradapter.h" "5" -"startgdbserverdialog.h" "5" -"termgdbadapter.h" "5" "Sources" "4" -"attachgdbadapter.cpp" "5" -"coregdbadapter.cpp" "5" "gdbengine.cpp" "5" "gdboptionspage.cpp" "5" -"gdbplainengine.cpp" "5" -"remotegdbserveradapter.cpp" "5" -"startgdbserverdialog.cpp" "5" -"termgdbadapter.cpp" "5" "lldb" "3" "lldb.pri" "4" "Headers" "4" "lldbengine.h" "5" "Sources" "4" "lldbengine.cpp" "5" +"modeltest" "3" +"modeltest.pri" "4" +"Headers" "4" +"modeltest.h" "5" +"Sources" "4" +"modeltest.cpp" "5" "namedemangler" "3" "namedemangler.pri" "4" "Headers" "4" @@ -6452,6 +7117,12 @@ "qtcreator_gui_pch.h" "6" "Other files" "4" "Debugger.json.in" "6" +"registryaccess" "3" +"registryaccess.pri" "4" +"Headers" "4" +"registryaccess.h" "5" +"Sources" "4" +"registryaccess.cpp" "5" "shared" "3" "shared.pri" "4" "Headers" "4" @@ -6490,7 +7161,6 @@ "debuggerrunconfigurationaspect.h" "4" "debuggerruncontrol.h" "4" "debuggersourcepathmappingwidget.h" "4" -"debuggerstartparameters.h" "4" "debuggertooltipmanager.h" "4" "disassembleragent.h" "4" "disassemblerlines.h" "4" @@ -6503,6 +7173,7 @@ "outputcollector.h" "4" "procinterrupt.h" "4" "registerhandler.h" "4" +"registerpostmortemaction.h" "4" "simplifytype.h" "4" "snapshothandler.h" "4" "snapshotwindow.h" "4" @@ -6550,6 +7221,7 @@ "outputcollector.cpp" "4" "procinterrupt.cpp" "4" "registerhandler.cpp" "4" +"registerpostmortemaction.cpp" "4" "simplifytype.cpp" "4" "snapshothandler.cpp" "4" "snapshotwindow.cpp" "4" @@ -6571,16 +7243,10 @@ "debugger.qrc" "4" "/debugger" "5" "images" "6" -"qml" "7" -"app-on-top.png" "8" -"app-on-top@2x.png" "8" -"select.png" "8" -"select@2x.png" "8" "breakpoint_disabled.png" "7" "breakpoint_disabled@2x.png" "7" "breakpoint_pending_overlay.png" "7" "breakpoint_pending_overlay@2x.png" "7" -"category_debug.png" "7" "debugger_breakpoints.png" "7" "debugger_continue.png" "7" "debugger_continue@2x.png" "7" @@ -6620,6 +7286,10 @@ "recordfill@2x.png" "7" "recordoutline.png" "7" "recordoutline@2x.png" "7" +"settingscategory_debugger.png" "7" +"settingscategory_debugger@2x.png" "7" +"tracepointoverlay.png" "7" +"tracepointoverlay@2x.png" "7" "debuggerunittests.qrc" "4" "/" "5" "unit-tests" "6" @@ -6779,6 +7449,7 @@ "Other files" "4" "DiffEditor.json.in" "6" "Headers" "3" +"descriptionwidgetwatcher.h" "4" "diffeditor.h" "4" "diffeditor_global.h" "4" "diffeditorconstants.h" "4" @@ -6795,6 +7466,7 @@ "sidebysidediffeditorwidget.h" "4" "unifieddiffeditorwidget.h" "4" "Sources" "3" +"descriptionwidgetwatcher.cpp" "4" "diffeditor.cpp" "4" "diffeditorcontroller.cpp" "4" "diffeditordocument.cpp" "4" @@ -6910,7 +7582,8 @@ "fakevim.qrc" "4" "/fakevim" "5" "images" "6" -"category_fakevim.png" "7" +"settingscategory_fakevim.png" "7" +"settingscategory_fakevim@2x.png" "7" "Other files" "3" "fakevim.qbs" "4" "fakevim_dependencies" "2" @@ -7071,6 +7744,7 @@ "branchcheckoutdialog.h" "4" "branchdialog.h" "4" "branchmodel.h" "4" +"branchutils.h" "4" "changeselectiondialog.h" "4" "commitdata.h" "4" "gitclient.h" "4" @@ -7096,6 +7770,7 @@ "branchcheckoutdialog.cpp" "4" "branchdialog.cpp" "4" "branchmodel.cpp" "4" +"branchutils.cpp" "4" "changeselectiondialog.cpp" "4" "commitdata.cpp" "4" "gitclient.cpp" "4" @@ -7280,6 +7955,8 @@ "utils_dependencies.pri" "6" "rpath" "4" "rpath.pri" "5" +"texteditor_dependencies" "4" +"texteditor_dependencies.pri" "5" "Headers" "4" "shared" "5" "qtcreator_gui_pch.h" "6" @@ -7298,6 +7975,7 @@ "helpviewer.h" "4" "helpwidget.h" "4" "localhelpmanager.h" "4" +"macwebkithelpviewer.h" "4" "openpagesmanager.h" "4" "openpagesmodel.h" "4" "openpagesswitcher.h" "4" @@ -7306,6 +7984,7 @@ "searchtaskhandler.h" "4" "searchwidget.h" "4" "textbrowserhelpviewer.h" "4" +"webenginehelpviewer.h" "4" "xbelsupport.h" "4" "Sources" "3" "centralwidget.cpp" "4" @@ -7327,6 +8006,7 @@ "searchtaskhandler.cpp" "4" "searchwidget.cpp" "4" "textbrowserhelpviewer.cpp" "4" +"webenginehelpviewer.cpp" "4" "xbelsupport.cpp" "4" "Forms" "3" "docsettingspage.ui" "4" @@ -7337,23 +8017,12 @@ "help.qrc" "4" "/help" "5" "images" "6" -"book.png" "7" -"category_help.png" "7" -"find.png" "7" -"home.png" "7" -"home@2x.png" "7" "mode_help.png" "7" "mode_help@2x.png" "7" "mode_help_mask.png" "7" "mode_help_mask@2x.png" "7" -"/trolltech/assistant" "5" -"images" "6" -"mac" "7" -"addtab.png" "8" -"closetab.png" "8" -"win" "7" -"addtab.png" "8" -"closetab.png" "8" +"settingscategory_help.png" "7" +"settingscategory_help@2x.png" "7" "Other files" "3" "help.qbs" "4" "help_dependencies" "2" @@ -7391,6 +8060,7 @@ "imageviewerfactory.h" "4" "imageviewerfile.h" "4" "imageviewerplugin.h" "4" +"multiexportdialog.h" "4" "Sources" "3" "exportdialog.cpp" "4" "imageview.cpp" "4" @@ -7398,6 +8068,7 @@ "imageviewerfactory.cpp" "4" "imageviewerfile.cpp" "4" "imageviewerplugin.cpp" "4" +"multiexportdialog.cpp" "4" "Forms" "3" "imageviewertoolbar.ui" "4" "Other files" "3" @@ -7473,13 +8144,11 @@ "iosdevice.h" "4" "iosdevicefactory.h" "4" "iosdsymbuildstep.h" "4" -"iosmanager.h" "4" "iosplugin.h" "4" "iosprobe.h" "4" "iosqtversion.h" "4" "iosqtversionfactory.h" "4" "iosrunconfiguration.h" "4" -"iosrunfactories.h" "4" "iosrunner.h" "4" "iossettingspage.h" "4" "iossettingswidget.h" "4" @@ -7502,13 +8171,11 @@ "iosdevice.cpp" "4" "iosdevicefactory.cpp" "4" "iosdsymbuildstep.cpp" "4" -"iosmanager.cpp" "4" "iosplugin.cpp" "4" "iosprobe.cpp" "4" "iosqtversion.cpp" "4" "iosqtversionfactory.cpp" "4" "iosrunconfiguration.cpp" "4" -"iosrunfactories.cpp" "4" "iosrunner.cpp" "4" "iossettingspage.cpp" "4" "iossettingswidget.cpp" "4" @@ -7825,19 +8492,14 @@ "nimindenter.h" "5" "project" "4" "nimbuildconfiguration.h" "5" -"nimbuildconfigurationfactory.h" "5" "nimbuildconfigurationwidget.h" "5" "nimcompilerbuildstep.h" "5" "nimcompilerbuildstepconfigwidget.h" "5" -"nimcompilerbuildstepfactory.h" "5" "nimcompilercleanstep.h" "5" "nimcompilercleanstepconfigwidget.h" "5" -"nimcompilercleanstepfactory.h" "5" "nimproject.h" "5" "nimprojectnode.h" "5" "nimrunconfiguration.h" "5" -"nimrunconfigurationfactory.h" "5" -"nimrunconfigurationwidget.h" "5" "nimtoolchain.h" "5" "nimtoolchainfactory.h" "5" "settings" "4" @@ -7857,19 +8519,14 @@ "nimindenter.cpp" "5" "project" "4" "nimbuildconfiguration.cpp" "5" -"nimbuildconfigurationfactory.cpp" "5" "nimbuildconfigurationwidget.cpp" "5" "nimcompilerbuildstep.cpp" "5" "nimcompilerbuildstepconfigwidget.cpp" "5" -"nimcompilerbuildstepfactory.cpp" "5" "nimcompilercleanstep.cpp" "5" "nimcompilercleanstepconfigwidget.cpp" "5" -"nimcompilercleanstepfactory.cpp" "5" "nimproject.cpp" "5" "nimprojectnode.cpp" "5" "nimrunconfiguration.cpp" "5" -"nimrunconfigurationfactory.cpp" "5" -"nimrunconfigurationwidget.cpp" "5" "nimtoolchain.cpp" "5" "nimtoolchainfactory.cpp" "5" "settings" "4" @@ -7888,9 +8545,10 @@ "nimcodestylepreferenceswidget.ui" "5" "Resources" "3" "nim.qrc" "4" -"/" "5" +"/nim" "5" "images" "6" -"nim.png" "7" +"settingscategory_nim.png" "7" +"settingscategory_nim@2x.png" "7" "Other files" "3" "nim.qbs" "4" "nim_dependencies" "2" @@ -8078,7 +8736,6 @@ "appoutputpane.h" "4" "baseprojectwizarddialog.h" "4" "buildconfiguration.h" "4" -"buildconfigurationmodel.h" "4" "buildenvironmentwidget.h" "4" "buildinfo.h" "4" "buildmanager.h" "4" @@ -8095,7 +8752,6 @@ "copytaskhandler.h" "4" "currentprojectfilter.h" "4" "currentprojectfind.h" "4" -"customexecutableconfigurationwidget.h" "4" "customexecutablerunconfiguration.h" "4" "customparser.h" "4" "customparserconfigdialog.h" "4" @@ -8103,7 +8759,6 @@ "dependenciespanel.h" "4" "deployablefile.h" "4" "deployconfiguration.h" "4" -"deployconfigurationmodel.h" "4" "deploymentdata.h" "4" "deploymentdatamodel.h" "4" "deploymentdataview.h" "4" @@ -8124,6 +8779,7 @@ "ioutputparser.h" "4" "ipotentialkit.h" "4" "itaskhandler.h" "4" +"journaldwatcher.h" "4" "kit.h" "4" "kitchooser.h" "4" "kitconfigwidget.h" "4" @@ -8148,6 +8804,7 @@ "processstep.h" "4" "project.h" "4" "projectconfiguration.h" "4" +"projectconfigurationmodel.h" "4" "projectexplorer.h" "4" "projectexplorer_export.h" "4" "projectexplorer_global.h" "4" @@ -8157,6 +8814,7 @@ "projectexplorersettingspage.h" "4" "projectfilewizardextension.h" "4" "projectimporter.h" "4" +"projectmacro.h" "4" "projectmacroexpander.h" "4" "projectmanager.h" "4" "projectmodels.h" "4" @@ -8170,17 +8828,15 @@ "removetaskhandler.h" "4" "runconfiguration.h" "4" "runconfigurationaspects.h" "4" -"runconfigurationmodel.h" "4" -"runnables.h" "4" "runsettingspropertiespage.h" "4" "selectablefilesmodel.h" "4" "session.h" "4" "sessiondialog.h" "4" "sessionmodel.h" "4" "sessionview.h" "4" -"settingsaccessor.h" "4" "showineditortaskhandler.h" "4" "showoutputtaskhandler.h" "4" +"subscription.h" "4" "target.h" "4" "targetsettingspanel.h" "4" "targetsetuppage.h" "4" @@ -8193,6 +8849,8 @@ "toolchainconfigwidget.h" "4" "toolchainmanager.h" "4" "toolchainoptionspage.h" "4" +"toolchainsettingsaccessor.h" "4" +"userfileaccessor.h" "4" "vcsannotatetaskhandler.h" "4" "waitforstopdialog.h" "4" "windebuginterface.h" "4" @@ -8231,7 +8889,6 @@ "appoutputpane.cpp" "4" "baseprojectwizarddialog.cpp" "4" "buildconfiguration.cpp" "4" -"buildconfigurationmodel.cpp" "4" "buildenvironmentwidget.cpp" "4" "buildinfo.cpp" "4" "buildmanager.cpp" "4" @@ -8247,7 +8904,6 @@ "copytaskhandler.cpp" "4" "currentprojectfilter.cpp" "4" "currentprojectfind.cpp" "4" -"customexecutableconfigurationwidget.cpp" "4" "customexecutablerunconfiguration.cpp" "4" "customparser.cpp" "4" "customparserconfigdialog.cpp" "4" @@ -8255,7 +8911,6 @@ "dependenciespanel.cpp" "4" "deployablefile.cpp" "4" "deployconfiguration.cpp" "4" -"deployconfigurationmodel.cpp" "4" "deploymentdatamodel.cpp" "4" "deploymentdataview.cpp" "4" "editorconfiguration.cpp" "4" @@ -8271,6 +8926,7 @@ "gnumakeparser.cpp" "4" "importwidget.cpp" "4" "ioutputparser.cpp" "4" +"journaldwatcher.cpp" "4" "kit.cpp" "4" "kitchooser.cpp" "4" "kitconfigwidget.cpp" "4" @@ -8294,11 +8950,13 @@ "processstep.cpp" "4" "project.cpp" "4" "projectconfiguration.cpp" "4" +"projectconfigurationmodel.cpp" "4" "projectexplorer.cpp" "4" "projectexplorericons.cpp" "4" "projectexplorersettingspage.cpp" "4" "projectfilewizardextension.cpp" "4" "projectimporter.cpp" "4" +"projectmacro.cpp" "4" "projectmacroexpander.cpp" "4" "projectmodels.cpp" "4" "projectnodes.cpp" "4" @@ -8311,17 +8969,15 @@ "removetaskhandler.cpp" "4" "runconfiguration.cpp" "4" "runconfigurationaspects.cpp" "4" -"runconfigurationmodel.cpp" "4" -"runnables.cpp" "4" "runsettingspropertiespage.cpp" "4" "selectablefilesmodel.cpp" "4" "session.cpp" "4" "sessiondialog.cpp" "4" "sessionmodel.cpp" "4" "sessionview.cpp" "4" -"settingsaccessor.cpp" "4" "showineditortaskhandler.cpp" "4" "showoutputtaskhandler.cpp" "4" +"subscription.cpp" "4" "target.cpp" "4" "targetsettingspanel.cpp" "4" "targetsetuppage.cpp" "4" @@ -8334,6 +8990,8 @@ "toolchainconfigwidget.cpp" "4" "toolchainmanager.cpp" "4" "toolchainoptionspage.cpp" "4" +"toolchainsettingsaccessor.cpp" "4" +"userfileaccessor.cpp" "4" "vcsannotatetaskhandler.cpp" "4" "waitforstopdialog.cpp" "4" "windebuginterface.cpp" "4" @@ -8364,7 +9022,10 @@ "build_hammerhandle_mask@2x.png" "7" "build_hammerhead_mask.png" "7" "build_hammerhead_mask@2x.png" "7" -"build_small.png" "7" +"buildhammerhandle.png" "7" +"buildhammerhandle@2x.png" "7" +"buildhammerhead.png" "7" +"buildhammerhead@2x.png" "7" "BuildSettings.png" "7" "buildstepdisable.png" "7" "buildstepdisable@2x.png" "7" @@ -8374,7 +9035,8 @@ "buildstepmoveup@2x.png" "7" "buildstepremove.png" "7" "buildstepremove@2x.png" "7" -"category_buildrun.png" "7" +"cancelbuild_overlay.png" "7" +"cancelbuild_overlay@2x.png" "7" "closetab.png" "7" "CodeStyleSettings.png" "7" "continue_1_small.png" "7" @@ -8425,6 +9087,12 @@ "run_mask@2x.png" "7" "RunSettings.png" "7" "session.png" "7" +"settingscategory_buildrun.png" "7" +"settingscategory_buildrun@2x.png" "7" +"settingscategory_devices.png" "7" +"settingscategory_devices@2x.png" "7" +"settingscategory_kits.png" "7" +"settingscategory_kits@2x.png" "7" "Simulator.png" "7" "targetpanel_bottom.png" "7" "unconfigured.png" "7" @@ -8433,6 +9101,14 @@ "projectexplorer.qbs" "4" "projectexplorer_dependencies" "2" "projectexplorer_dependencies.pri" "3" +"ptracepreload" "2" +"ptracepreload.pro" "3" +"qtcreator" "3" +"qtcreator.pri" "4" +"Sources" "3" +"ptracepreload.c" "4" +"Other files" "3" +"ptracepreload.qbs" "4" "pythoneditor" "2" "pythoneditor.pro" "3" "qtcreatorplugin" "3" @@ -8697,26 +9373,18 @@ "QmakeAndroidSupport.json.in" "6" "Headers" "3" "androidextralibrarylistmodel.h" "4" -"androidpackageinstallationfactory.h" "4" -"androidpackageinstallationstep.h" "4" "androidqmakebuildconfigurationfactory.h" "4" "createandroidmanifestwizard.h" "4" "qmakeandroidbuildapkstep.h" "4" "qmakeandroidbuildapkwidget.h" "4" -"qmakeandroidrunconfiguration.h" "4" -"qmakeandroidrunfactories.h" "4" "qmakeandroidsupport.h" "4" "qmakeandroidsupportplugin.h" "4" "Sources" "3" "androidextralibrarylistmodel.cpp" "4" -"androidpackageinstallationfactory.cpp" "4" -"androidpackageinstallationstep.cpp" "4" "androidqmakebuildconfigurationfactory.cpp" "4" "createandroidmanifestwizard.cpp" "4" "qmakeandroidbuildapkstep.cpp" "4" "qmakeandroidbuildapkwidget.cpp" "4" -"qmakeandroidrunconfiguration.cpp" "4" -"qmakeandroidrunfactories.cpp" "4" "qmakeandroidsupport.cpp" "4" "qmakeandroidsupportplugin.cpp" "4" "Forms" "3" @@ -8818,9 +9486,6 @@ "simpleprojectwizard.h" "5" "subdirsprojectwizard.h" "5" "subdirsprojectwizarddialog.h" "5" -"testwizard.h" "5" -"testwizarddialog.h" "5" -"testwizardpage.h" "5" "addlibrarywizard.h" "4" "desktopqmakerunconfiguration.h" "4" "externaleditors.h" "4" @@ -8846,7 +9511,6 @@ "qmakeprojectmanager_global.h" "4" "qmakeprojectmanagerconstants.h" "4" "qmakeprojectmanagerplugin.h" "4" -"qmakerunconfigurationfactory.h" "4" "qmakestep.h" "4" "qtmodulesinfo.h" "4" "Sources" "3" @@ -8863,9 +9527,6 @@ "simpleprojectwizard.cpp" "5" "subdirsprojectwizard.cpp" "5" "subdirsprojectwizarddialog.cpp" "5" -"testwizard.cpp" "5" -"testwizarddialog.cpp" "5" -"testwizardpage.cpp" "5" "addlibrarywizard.cpp" "4" "desktopqmakerunconfiguration.cpp" "4" "externaleditors.cpp" "4" @@ -8888,12 +9549,9 @@ "qmakeprojectimporter.cpp" "4" "qmakeprojectmanager.cpp" "4" "qmakeprojectmanagerplugin.cpp" "4" -"qmakerunconfigurationfactory.cpp" "4" "qmakestep.cpp" "4" "qtmodulesinfo.cpp" "4" "Forms" "3" -"wizards" "4" -"testwizardpage.ui" "5" "librarydetailswidget.ui" "4" "makestep.ui" "4" "qmakeprojectconfigwidget.ui" "4" @@ -9013,6 +9671,7 @@ "abstractaction.h" "6" "abstractactiongroup.h" "6" "actioninterface.h" "6" +"addimagesdialog.h" "6" "addsignalhandlerdialog.h" "6" "changestyleaction.h" "6" "componentcore_constants.h" "6" @@ -9027,9 +9686,11 @@ "qmldesignericonprovider.h" "6" "selectioncontext.h" "6" "theme.h" "6" +"zoomaction.h" "6" "Sources" "5" "abstractaction.cpp" "6" "abstractactiongroup.cpp" "6" +"addimagesdialog.cpp" "6" "addsignalhandlerdialog.cpp" "6" "changestyleaction.cpp" "6" "crumblebar.cpp" "6" @@ -9043,6 +9704,7 @@ "qmldesignericonprovider.cpp" "6" "selectioncontext.cpp" "6" "theme.cpp" "6" +"zoomaction.cpp" "6" "Forms" "5" "addsignalhandlerdialog.ui" "6" "Resources" "5" @@ -9152,6 +9814,8 @@ "propertybindingcontainer.cpp" "7" "propertyvaluecontainer.cpp" "7" "reparentcontainer.cpp" "7" +"sharedmemory_qt.cpp" "7" +"sharedmemory_unix.cpp" "7" "filemanager" "5" "filemanager.pri" "6" "Headers" "6" @@ -9264,6 +9928,8 @@ "qmlmodelnodefacade.h" "7" "qmlobjectnode.h" "7" "qmlstate.h" "7" +"qmltimeline.h" "7" +"qmltimelinekeyframegroup.h" "7" "removebasestateexception.h" "7" "rewriterview.h" "7" "rewritingexception.h" "7" @@ -9355,6 +10021,8 @@ "qmlobjectnode.cpp" "7" "qmlstate.cpp" "7" "qmltextgenerator.cpp" "7" +"qmltimeline.cpp" "7" +"qmltimelinekeyframegroup.cpp" "7" "rewriteaction.cpp" "7" "rewriteactioncompressor.cpp" "7" "rewriterview.cpp" "7" @@ -9411,7 +10079,6 @@ "snapper.h" "6" "snappinglinecreator.h" "6" "toolbox.h" "6" -"zoomaction.h" "6" "Sources" "5" "abstractcustomtool.cpp" "6" "abstractformeditortool.cpp" "6" @@ -9451,7 +10118,6 @@ "snapper.cpp" "6" "snappinglinecreator.cpp" "6" "toolbox.cpp" "6" -"zoomaction.cpp" "6" "Resources" "5" "formeditor.qrc" "6" "/icon/layout" "7" @@ -9553,7 +10219,6 @@ "export_checked@2x.png" "8" "export_unchecked.png" "8" "export_unchecked@2x.png" "8" -"warning.png" "8" "propertyeditor" "4" "propertyeditor.pri" "5" "Headers" "5" @@ -9582,18 +10247,6 @@ "qmlanchorbindingproxy.cpp" "6" "qmlmodelnodeproxy.cpp" "6" "quick2propertyeditorview.cpp" "6" -"Resources" "5" -"propertyeditor.qrc" "6" -"/" "7" -"images" "8" -"button2_hovered.png" "9" -"button2_normal.png" "9" -"button2_pressed.png" "9" -"button_hovered.png" "9" -"button_normal.png" "9" -"button_pressed.png" "9" -"frame.png" "9" -"gradient.png" "9" "qmldesignerextension" "4" "qmldesignerextension.pri" "5" "colortool" "5" @@ -9761,9 +10414,6 @@ "spliteditorhorizontally@2x.png" "9" "spliteditorvertically.png" "9" "spliteditorvertically@2x.png" "9" -"templates" "8" -"Standard" "9" -"Form.xml" "10" "centerwidget.css" "8" "formeditorstylesheet.css" "8" "scrollbar.css" "8" @@ -9945,6 +10595,7 @@ "qmljsreuse.h" "4" "qmljssemantichighlighter.h" "4" "qmljssemanticinfoupdater.h" "4" +"qmljstextmark.h" "4" "qmljswrapinloader.h" "4" "qmloutlinemodel.h" "4" "qmltaskmanager.h" "4" @@ -9971,6 +10622,7 @@ "qmljsreuse.cpp" "4" "qmljssemantichighlighter.cpp" "4" "qmljssemanticinfoupdater.cpp" "4" +"qmljstextmark.cpp" "4" "qmljswrapinloader.cpp" "4" "qmloutlinemodel.cpp" "4" "qmltaskmanager.cpp" "4" @@ -10066,7 +10718,8 @@ "qmljstools.qrc" "4" "/qmljstools" "5" "images" "6" -"category_qml.png" "7" +"settingscategory_qml.png" "7" +"settingscategory_qml@2x.png" "7" "Other files" "3" "qmljstools.qbs" "4" "qmljstools_dependencies" "2" @@ -10097,8 +10750,6 @@ "debugger_dependencies.pri" "6" "extensionsystem_dependencies" "5" "extensionsystem_dependencies.pri" "6" -"flamegraph_dependencies" "5" -"flamegraph_dependencies.pri" "6" "languageutils_dependencies" "5" "languageutils_dependencies.pri" "6" "projectexplorer_dependencies" "5" @@ -10113,8 +10764,8 @@ "ssh_dependencies.pri" "6" "texteditor_dependencies" "5" "texteditor_dependencies.pri" "6" -"timeline_dependencies" "5" -"timeline_dependencies.pri" "6" +"tracing_dependencies" "5" +"tracing_dependencies.pri" "6" "utils_dependencies" "5" "utils_dependencies.pri" "6" "qtsupport_dependencies" "4" @@ -10128,7 +10779,11 @@ "qtcreator_gui_pch.h" "6" "Other files" "4" "QmlProfiler.json.in" "6" +"tests" "3" +"tests.pri" "4" +"Headers" "4" "debugmessagesmodel_test.h" "5" +"fakedebugserver.h" "5" "flamegraphmodel_test.h" "5" "flamegraphview_test.h" "5" "inputeventsmodel_test.h" "5" @@ -10144,7 +10799,40 @@ "qmlprofilerbindingloopsrenderpass_test.h" "5" "qmlprofilerclientmanager_test.h" "5" "qmlprofilerconfigwidget_test.h" "5" +"qmlprofilerdetailsrewriter_test.h" "5" +"qmlprofilertool_test.h" "5" +"qmlprofilertraceclient_test.h" "5" "qmlprofilertraceview_test.h" "5" +"Sources" "4" +"debugmessagesmodel_test.cpp" "5" +"fakedebugserver.cpp" "5" +"flamegraphmodel_test.cpp" "5" +"flamegraphview_test.cpp" "5" +"inputeventsmodel_test.cpp" "5" +"localqmlprofilerrunner_test.cpp" "5" +"memoryusagemodel_test.cpp" "5" +"pixmapcachemodel_test.cpp" "5" +"qmlevent_test.cpp" "5" +"qmleventlocation_test.cpp" "5" +"qmleventtype_test.cpp" "5" +"qmlnote_test.cpp" "5" +"qmlprofileranimationsmodel_test.cpp" "5" +"qmlprofilerattachdialog_test.cpp" "5" +"qmlprofilerbindingloopsrenderpass_test.cpp" "5" +"qmlprofilerclientmanager_test.cpp" "5" +"qmlprofilerconfigwidget_test.cpp" "5" +"qmlprofilerdetailsrewriter_test.cpp" "5" +"qmlprofilertool_test.cpp" "5" +"qmlprofilertraceclient_test.cpp" "5" +"qmlprofilertraceview_test.cpp" "5" +"Resources" "4" +"tests.qrc" "5" +"/qmlprofiler/tests" "6" +"check.dat" "7" +"qmlprofilerdetailsrewriter_test.cpp" "7" +"Test.qml" "7" +"traces.dat" "7" +"Headers" "3" "debugmessagesmodel.h" "4" "flamegraphmodel.h" "4" "flamegraphview.h" "4" @@ -10156,6 +10844,7 @@ "qmleventtype.h" "4" "qmlnote.h" "4" "qmlprofiler_global.h" "4" +"qmlprofileractions.h" "4" "qmlprofileranimationsmodel.h" "4" "qmlprofilerattachdialog.h" "4" "qmlprofilerbindingloopsrenderpass.h" "4" @@ -10197,6 +10886,7 @@ "qmleventlocation.cpp" "4" "qmleventtype.cpp" "4" "qmlnote.cpp" "4" +"qmlprofileractions.cpp" "4" "qmlprofileranimationsmodel.cpp" "4" "qmlprofilerattachdialog.cpp" "4" "qmlprofilerbindingloopsrenderpass.cpp" "4" @@ -10299,7 +10989,6 @@ "qmlprojectnodes.h" "4" "qmlprojectplugin.h" "4" "qmlprojectrunconfiguration.h" "4" -"qmlprojectrunconfigurationfactory.h" "4" "qmlprojectrunconfigurationwidget.h" "4" "Sources" "3" "qmlproject.cpp" "4" @@ -10307,13 +10996,11 @@ "qmlprojectnodes.cpp" "4" "qmlprojectplugin.cpp" "4" "qmlprojectrunconfiguration.cpp" "4" -"qmlprojectrunconfigurationfactory.cpp" "4" "qmlprojectrunconfigurationwidget.cpp" "4" "Resources" "3" "qmlproject.qrc" "4" "/qmlproject" "5" "images" "6" -"qmlfolder.png" "7" "qmlproject.png" "7" "Other files" "3" "qmlprojectmanager.qbs" "4" @@ -10329,8 +11016,6 @@ "debugger_dependencies.pri" "5" "projectexplorer_dependencies" "4" "projectexplorer_dependencies.pri" "5" -"qmakeprojectmanager_dependencies" "4" -"qmakeprojectmanager_dependencies.pri" "5" "qnx_dependencies" "4" "qnx_dependencies.pri" "5" "qtcreator" "4" @@ -10351,8 +11036,6 @@ "languageutils_dependencies.pri" "6" "projectexplorer_dependencies" "5" "projectexplorer_dependencies.pri" "6" -"qmakeprojectmanager_dependencies" "5" -"qmakeprojectmanager_dependencies.pri" "6" "qmldebug_dependencies" "5" "qmldebug_dependencies.pri" "6" "qmljs_dependencies" "5" @@ -10361,8 +11044,6 @@ "qtsupport_dependencies.pri" "6" "remotelinux_dependencies" "5" "remotelinux_dependencies.pri" "6" -"resourceeditor_dependencies" "5" -"resourceeditor_dependencies.pri" "6" "ssh_dependencies" "5" "ssh_dependencies.pri" "6" "texteditor_dependencies" "5" @@ -10384,17 +11065,13 @@ "pathchooserdelegate.h" "4" "qnx_export.h" "4" "qnxanalyzesupport.h" "4" -"qnxattachdebugdialog.h" "4" -"qnxattachdebugsupport.h" "4" "qnxbaseqtconfigwidget.h" "4" "qnxconfiguration.h" "4" "qnxconfigurationmanager.h" "4" "qnxconstants.h" "4" "qnxdebugsupport.h" "4" "qnxdeployconfiguration.h" "4" -"qnxdeployconfigurationfactory.h" "4" "qnxdeployqtlibrariesdialog.h" "4" -"qnxdeploystepfactory.h" "4" "qnxdevice.h" "4" "qnxdevicefactory.h" "4" "qnxdeviceprocess.h" "4" @@ -10406,7 +11083,6 @@ "qnxqtversion.h" "4" "qnxqtversionfactory.h" "4" "qnxrunconfiguration.h" "4" -"qnxrunconfigurationfactory.h" "4" "qnxsettingspage.h" "4" "qnxsettingswidget.h" "4" "qnxtoolchain.h" "4" @@ -10416,16 +11092,12 @@ "Sources" "3" "pathchooserdelegate.cpp" "4" "qnxanalyzesupport.cpp" "4" -"qnxattachdebugdialog.cpp" "4" -"qnxattachdebugsupport.cpp" "4" "qnxbaseqtconfigwidget.cpp" "4" "qnxconfiguration.cpp" "4" "qnxconfigurationmanager.cpp" "4" "qnxdebugsupport.cpp" "4" "qnxdeployconfiguration.cpp" "4" -"qnxdeployconfigurationfactory.cpp" "4" "qnxdeployqtlibrariesdialog.cpp" "4" -"qnxdeploystepfactory.cpp" "4" "qnxdevice.cpp" "4" "qnxdevicefactory.cpp" "4" "qnxdeviceprocess.cpp" "4" @@ -10437,7 +11109,6 @@ "qnxqtversion.cpp" "4" "qnxqtversionfactory.cpp" "4" "qnxrunconfiguration.cpp" "4" -"qnxrunconfigurationfactory.cpp" "4" "qnxsettingspage.cpp" "4" "qnxsettingswidget.cpp" "4" "qnxtoolchain.cpp" "4" @@ -10451,7 +11122,10 @@ "qnx.qrc" "4" "/qnx" "5" "images" "6" -"qnx-target.png" "7" +"qnxdevice.png" "7" +"qnxdevice@2x.png" "7" +"qnxdevicesmall.png" "7" +"qnxdevicesmall@2x.png" "7" "Other files" "3" "qnx.qbs" "4" "qnx_dependencies" "2" @@ -10587,16 +11261,12 @@ "/qtsupport" "5" "images" "6" "icons" "7" -"androidapp.png" "8" -"buildrun.png" "8" -"ddays13.png" "8" -"ddays14.png" "8" -"qtquick.png" "8" -"qwidget.png" "8" +"qteventicon.png" "8" +"qteventicon@2x.png" "8" "tutorialicon.png" "8" +"tutorialicon@2x.png" "8" "videotutorialicon.png" "8" -"worldsummit15.png" "8" -"worldsummit16.png" "8" +"videotutorialicon@2x.png" "8" "dark_forms.png" "7" "dark_qml.png" "7" "dark_qt_project.png" "7" @@ -10662,7 +11332,6 @@ "abstractpackagingstep.h" "4" "abstractremotelinuxdeployservice.h" "4" "abstractremotelinuxdeploystep.h" "4" -"abstractremotelinuxrunsupport.h" "4" "abstractuploadandinstallpackageservice.h" "4" "deploymenttimeinfo.h" "4" "embeddedlinuxqtversion.h" "4" @@ -10673,7 +11342,6 @@ "genericlinuxdeviceconfigurationwidget.h" "4" "genericlinuxdeviceconfigurationwizard.h" "4" "genericlinuxdeviceconfigurationwizardpages.h" "4" -"genericremotelinuxdeploystepfactory.h" "4" "linuxdevice.h" "4" "linuxdeviceprocess.h" "4" "linuxdevicetester.h" "4" @@ -10681,7 +11349,6 @@ "publickeydeploymentdialog.h" "4" "remotelinux_constants.h" "4" "remotelinux_export.h" "4" -"remotelinuxanalyzesupport.h" "4" "remotelinuxcheckforfreediskspaceservice.h" "4" "remotelinuxcheckforfreediskspacestep.h" "4" "remotelinuxcustomcommanddeploymentstep.h" "4" @@ -10689,15 +11356,15 @@ "remotelinuxcustomrunconfiguration.h" "4" "remotelinuxdebugsupport.h" "4" "remotelinuxdeployconfiguration.h" "4" -"remotelinuxdeployconfigurationfactory.h" "4" "remotelinuxenvironmentaspect.h" "4" "remotelinuxenvironmentaspectwidget.h" "4" "remotelinuxenvironmentreader.h" "4" +"remotelinuxkillappservice.h" "4" +"remotelinuxkillappstep.h" "4" "remotelinuxpackageinstaller.h" "4" "remotelinuxplugin.h" "4" +"remotelinuxqmltoolingsupport.h" "4" "remotelinuxrunconfiguration.h" "4" -"remotelinuxrunconfigurationfactory.h" "4" -"remotelinuxrunconfigurationwidget.h" "4" "remotelinuxsignaloperation.h" "4" "remotelinuxutils.h" "4" "sshkeydeployer.h" "4" @@ -10708,7 +11375,6 @@ "abstractpackagingstep.cpp" "4" "abstractremotelinuxdeployservice.cpp" "4" "abstractremotelinuxdeploystep.cpp" "4" -"abstractremotelinuxrunsupport.cpp" "4" "abstractuploadandinstallpackageservice.cpp" "4" "deploymenttimeinfo.cpp" "4" "embeddedlinuxqtversion.cpp" "4" @@ -10719,13 +11385,11 @@ "genericlinuxdeviceconfigurationwidget.cpp" "4" "genericlinuxdeviceconfigurationwizard.cpp" "4" "genericlinuxdeviceconfigurationwizardpages.cpp" "4" -"genericremotelinuxdeploystepfactory.cpp" "4" "linuxdevice.cpp" "4" "linuxdeviceprocess.cpp" "4" "linuxdevicetester.cpp" "4" "packageuploader.cpp" "4" "publickeydeploymentdialog.cpp" "4" -"remotelinuxanalyzesupport.cpp" "4" "remotelinuxcheckforfreediskspaceservice.cpp" "4" "remotelinuxcheckforfreediskspacestep.cpp" "4" "remotelinuxcustomcommanddeploymentstep.cpp" "4" @@ -10733,15 +11397,15 @@ "remotelinuxcustomrunconfiguration.cpp" "4" "remotelinuxdebugsupport.cpp" "4" "remotelinuxdeployconfiguration.cpp" "4" -"remotelinuxdeployconfigurationfactory.cpp" "4" "remotelinuxenvironmentaspect.cpp" "4" "remotelinuxenvironmentaspectwidget.cpp" "4" "remotelinuxenvironmentreader.cpp" "4" +"remotelinuxkillappservice.cpp" "4" +"remotelinuxkillappstep.cpp" "4" "remotelinuxpackageinstaller.cpp" "4" "remotelinuxplugin.cpp" "4" +"remotelinuxqmltoolingsupport.cpp" "4" "remotelinuxrunconfiguration.cpp" "4" -"remotelinuxrunconfigurationfactory.cpp" "4" -"remotelinuxrunconfigurationwidget.cpp" "4" "remotelinuxsignaloperation.cpp" "4" "remotelinuxutils.cpp" "4" "sshkeydeployer.cpp" "4" @@ -10752,7 +11416,6 @@ "genericlinuxdeviceconfigurationwidget.ui" "4" "genericlinuxdeviceconfigurationwizardsetuppage.ui" "4" "remotelinuxcheckforfreediskspacestepwidget.ui" "4" -"remotelinuxcustomrunconfigurationwidget.ui" "4" "Resources" "3" "remotelinux.qrc" "4" "/remotelinux" "5" @@ -11100,6 +11763,50 @@ "scxmleditor.qbs" "4" "scxmleditor_dependencies" "2" "scxmleditor_dependencies.pri" "3" +"serialterminal" "2" +"serialterminal.pro" "3" +"qtcreatorplugin" "3" +"qtcreatorplugin.pri" "4" +"coreplugin_dependencies" "4" +"coreplugin_dependencies.pri" "5" +"qtcreator" "4" +"qtcreator.pri" "5" +"aggregation_dependencies" "5" +"aggregation_dependencies.pri" "6" +"coreplugin_dependencies" "5" +"coreplugin_dependencies.pri" "6" +"extensionsystem_dependencies" "5" +"extensionsystem_dependencies.pri" "6" +"utils_dependencies" "5" +"utils_dependencies.pri" "6" +"rpath" "4" +"rpath.pri" "5" +"serialterminal_dependencies" "4" +"serialterminal_dependencies.pri" "5" +"Headers" "4" +"shared" "5" +"qtcreator_gui_pch.h" "6" +"Other files" "4" +"SerialTerminal.json.in" "6" +"Headers" "3" +"consolelineedit.h" "4" +"serialcontrol.h" "4" +"serialdevicemodel.h" "4" +"serialoutputpane.h" "4" +"serialterminalconstants.h" "4" +"serialterminalplugin.h" "4" +"serialterminalsettings.h" "4" +"Sources" "3" +"consolelineedit.cpp" "4" +"serialcontrol.cpp" "4" +"serialdevicemodel.cpp" "4" +"serialoutputpane.cpp" "4" +"serialterminalplugin.cpp" "4" +"serialterminalsettings.cpp" "4" +"Other files" "3" +"serialterminal.qbs" "4" +"serialterminal_dependencies" "2" +"serialterminal_dependencies.pri" "3" "silversearcher" "2" "silversearcher.pro" "3" "qtcreatorplugin" "3" @@ -11292,6 +11999,7 @@ "assistproposaliteminterface.h" "5" "codeassistant.h" "5" "completionassistprovider.h" "5" +"documentcontentcompletion.h" "5" "functionhintproposal.h" "5" "functionhintproposalwidget.h" "5" "genericproposal.h" "5" @@ -11304,8 +12012,6 @@ "iassistprovider.h" "5" "ifunctionhintproposalmodel.h" "5" "keywordscompletionassist.h" "5" -"quickfixassistprocessor.h" "5" -"quickfixassistprovider.h" "5" "runner.h" "5" "textdocumentmanipulator.h" "5" "textdocumentmanipulatorinterface.h" "5" @@ -11357,7 +12063,6 @@ "commentssettings.h" "4" "completionsettings.h" "4" "completionsettingspage.h" "4" -"convenience.h" "4" "displaysettings.h" "4" "displaysettingspage.h" "4" "extraencodingsettings.h" "4" @@ -11407,6 +12112,7 @@ "assistproposalitem.cpp" "5" "codeassistant.cpp" "5" "completionassistprovider.cpp" "5" +"documentcontentcompletion.cpp" "5" "functionhintproposal.cpp" "5" "functionhintproposalwidget.cpp" "5" "genericproposal.cpp" "5" @@ -11419,8 +12125,6 @@ "iassistprovider.cpp" "5" "ifunctionhintproposalmodel.cpp" "5" "keywordscompletionassist.cpp" "5" -"quickfixassistprocessor.cpp" "5" -"quickfixassistprovider.cpp" "5" "runner.cpp" "5" "textdocumentmanipulator.cpp" "5" "generichighlighter" "4" @@ -11466,7 +12170,6 @@ "commentssettings.cpp" "4" "completionsettings.cpp" "4" "completionsettingspage.cpp" "4" -"convenience.cpp" "4" "displaysettings.cpp" "4" "displaysettingspage.cpp" "4" "extraencodingsettings.cpp" "4" @@ -11525,12 +12228,9 @@ "texteditor.qrc" "4" "/texteditor" "5" "images" "6" -"finddirectory.png" "7" "finddocuments.png" "7" -"lightbulb.png" "7" -"lightbulb@2x.png" "7" -"lightbulbcap.png" "7" -"lightbulbcap@2x.png" "7" +"settingscategory_texteditor.png" "7" +"settingscategory_texteditor@2x.png" "7" "snippet.png" "7" "Other files" "3" "texteditor.qbs" "4" @@ -11629,9 +12329,10 @@ "bug@2x.png" "7" "bugfill.png" "7" "bugfill@2x.png" "7" +"settingscategory_todo.png" "7" +"settingscategory_todo@2x.png" "7" "tasklist.png" "7" "tasklist@2x.png" "7" -"todo.png" "7" "Other files" "3" "todo.qbs" "4" "todo_dependencies" "2" @@ -11669,11 +12370,6 @@ "updateinfoplugin.cpp" "4" "Forms" "3" "settingspage.ui" "4" -"Resources" "3" -"updateinfo.qrc" "4" -"/updateinfo" "5" -"images" "6" -"update_available_logo.png" "7" "Other files" "3" "updateinfo.qbs" "4" "updateinfo_dependencies" "2" @@ -11794,7 +12490,6 @@ "callgrindtextmark.h" "4" "callgrindtool.h" "4" "callgrindvisualisation.h" "4" -"memcheckengine.h" "4" "memcheckerrorview.h" "4" "memchecktool.h" "4" "suppressiondialog.h" "4" @@ -11805,7 +12500,6 @@ "valgrindrunner.h" "4" "valgrindsettings.h" "4" "valgrindtestrunnertest.h" "4" -"workarounds.h" "4" "Sources" "3" "callgrindcostdelegate.cpp" "4" "callgrindcostview.cpp" "4" @@ -11815,7 +12509,6 @@ "callgrindtextmark.cpp" "4" "callgrindtool.cpp" "4" "callgrindvisualisation.cpp" "4" -"memcheckengine.cpp" "4" "memcheckerrorview.cpp" "4" "memchecktool.cpp" "4" "suppressiondialog.cpp" "4" @@ -11826,7 +12519,6 @@ "valgrindrunner.cpp" "4" "valgrindsettings.cpp" "4" "valgrindtestrunnertest.cpp" "4" -"workarounds.cpp" "4" "Forms" "3" "valgrindconfigwidget.ui" "4" "Resources" "3" @@ -11955,10 +12647,16 @@ "vcsbase.qrc" "4" "/vcsbase" "5" "images" "6" -"category_vcs.png" "7" -"diff.png" "7" -"removesubmitfield.png" "7" -"submit.png" "7" +"diff_arrows.png" "7" +"diff_arrows@2x.png" "7" +"diff_documents.png" "7" +"diff_documents@2x.png" "7" +"settingscategory_vcs.png" "7" +"settingscategory_vcs@2x.png" "7" +"submit_arrow.png" "7" +"submit_arrow@2x.png" "7" +"submit_db.png" "7" +"submit_db@2x.png" "7" "Other files" "3" "vcsbase.qbs" "4" "vcsbase_dependencies" "2" @@ -12000,7 +12698,6 @@ "community@2x.png" "7" "expandarrow.png" "7" "expandarrow@2x.png" "7" -"mode_edit_mask.png" "7" "mode_welcome.png" "7" "mode_welcome@2x.png" "7" "mode_welcome_mask.png" "7" @@ -12031,8 +12728,6 @@ "debugger_dependencies.pri" "5" "projectexplorer_dependencies" "4" "projectexplorer_dependencies.pri" "5" -"qmakeprojectmanager_dependencies" "4" -"qmakeprojectmanager_dependencies.pri" "5" "qtcreator" "4" "qtcreator.pri" "5" "aggregation_dependencies" "5" @@ -12051,16 +12746,12 @@ "languageutils_dependencies.pri" "6" "projectexplorer_dependencies" "5" "projectexplorer_dependencies.pri" "6" -"qmakeprojectmanager_dependencies" "5" -"qmakeprojectmanager_dependencies.pri" "6" "qmldebug_dependencies" "5" "qmldebug_dependencies.pri" "6" "qmljs_dependencies" "5" "qmljs_dependencies.pri" "6" "qtsupport_dependencies" "5" "qtsupport_dependencies.pri" "6" -"resourceeditor_dependencies" "5" -"resourceeditor_dependencies.pri" "6" "ssh_dependencies" "5" "ssh_dependencies.pri" "6" "texteditor_dependencies" "5" @@ -12091,9 +12782,7 @@ "winrtqtversion.h" "4" "winrtqtversionfactory.h" "4" "winrtrunconfiguration.h" "4" -"winrtrunconfigurationwidget.h" "4" "winrtruncontrol.h" "4" -"winrtrunfactories.h" "4" "winrtrunnerhelper.h" "4" "Sources" "3" "winrtdebugsupport.cpp" "4" @@ -12107,9 +12796,7 @@ "winrtqtversion.cpp" "4" "winrtqtversionfactory.cpp" "4" "winrtrunconfiguration.cpp" "4" -"winrtrunconfigurationwidget.cpp" "4" "winrtruncontrol.cpp" "4" -"winrtrunfactories.cpp" "4" "winrtrunnerhelper.cpp" "4" "Forms" "3" "winrtpackagedeploymentstepwidget.ui" "4" @@ -12150,8 +12837,33 @@ "Sources" "4" "clangcompilationdbgenerator.cpp" "5" "clangcompilationdbgeneratorplugin.cpp" "5" +"makefilegenerator" "3" +"makefilegenerator.pro" "4" +"plugins" "4" +"plugins.pri" "5" +"install_prefix" "5" +"install_prefix.pri" "6" +"library_dirname" "5" +"library_dirname.pri" "6" +"use_corelib" "5" +"use_corelib.pri" "6" +"library_dirname" "6" +"library_dirname.pri" "7" +"qbs_version" "6" +"qbs_version.pri" "7" +"Headers" "4" +"makefilegenerator.h" "5" +"Sources" "4" +"makefilegenerator.cpp" "5" +"makefilegeneratorplugin.cpp" "5" "visualstudio" "3" "visualstudio.pro" "4" +"json" "4" +"json.pri" "5" +"Headers" "5" +"json.h" "6" +"Sources" "5" +"json.cpp" "6" "plugins" "4" "plugins.pri" "5" "install_prefix" "5" @@ -12308,9 +13020,11 @@ "Headers" "2" "qtenvironment.h" "3" "qtmoduleinfo.h" "3" +"qtmsvctools.h" "3" "qtprofilesetup.h" "3" "Sources" "2" "qtmoduleinfo.cpp" "3" +"qtmsvctools.cpp" "3" "qtprofilesetup.cpp" "3" "Resources" "2" "templates.qrc" "3" @@ -12322,13 +13036,15 @@ "gui.qbs" "6" "moc.js" "6" "module.qbs" "6" -"phonon.qbs" "6" "plugin.qbs" "6" "qdoc.js" "6" "qml.js" "6" "qml.qbs" "6" +"qmlcache.qbs" "6" "QtModule.qbs" "6" "QtPlugin.qbs" "6" +"quick.js" "6" +"quick.qbs" "6" "scxml.qbs" "6" "Other files" "2" "templates" "3" @@ -12338,19 +13054,24 @@ "gui.qbs" "4" "moc.js" "4" "module.qbs" "4" -"phonon.qbs" "4" "plugin.qbs" "4" "qdoc.js" "4" "qml.js" "4" "qml.qbs" "4" +"qmlcache.qbs" "4" "QtModule.qbs" "4" "QtPlugin.qbs" "4" +"quick.js" "4" +"quick.qbs" "4" "scxml.qbs" "4" "static" "1" "static.pro" "2" "install_prefix" "2" "install_prefix.pri" "3" "Sources" "2" +"bin" "3" +"ibmsvc.xml" "4" +"ibqbs.bat" "4" "base" "5" "AndroidApk.qbs" "6" "AppleApplicationDiskImage.qbs" "6" @@ -12389,11 +13110,14 @@ "AndroidSdkProbe.qbs" "6" "BinaryProbe.qbs" "6" "FrameworkProbe.qbs" "6" +"GccBinaryProbe.qbs" "6" "GccProbe.qbs" "6" "GccVersionProbe.qbs" "6" +"IcoUtilsVersionProbe.qbs" "6" "IncludeProbe.qbs" "6" "InnoSetupProbe.qbs" "6" "JdkProbe.qbs" "6" +"JdkVersionProbe.qbs" "6" "MsvcProbe.qbs" "6" "NodeJsProbe.qbs" "6" "NpmProbe.qbs" "6" @@ -12422,7 +13146,6 @@ "BundleModule.qbs" "6" "MacOSX-Package-Types.xcspec" "6" "MacOSX-Product-Types.xcspec" "6" -"update-specs.sh" "6" "cli" "5" "cli.js" "6" "CLIModule.qbs" "6" @@ -12430,6 +13153,7 @@ "windows-dotnet.qbs" "6" "cpp" "5" "android-gcc.qbs" "6" +"cpp.js" "6" "CppModule.qbs" "6" "darwin.js" "6" "DarwinGCC.qbs" "6" @@ -12437,23 +13161,35 @@ "freebsd.js" "6" "gcc.js" "6" "GenericGCC.qbs" "6" -"genericunix-gcc.qbs" "6" "ios-gcc.qbs" "6" "LinuxGCC.qbs" "6" "macos-gcc.qbs" "6" "msvc.js" "6" "qnx-qcc.qbs" "6" +"setuprunenv.js" "6" "tvos-gcc.qbs" "6" "UnixGCC.qbs" "6" "watchos-gcc.qbs" "6" "windows-mingw.qbs" "6" "windows-msvc.qbs" "6" +"cpufeatures" "5" +"cpufeatures.qbs" "6" "dmg" "5" "dmg.js" "6" "DMGModule.qbs" "6" +"Exporter" "5" +"pkgconfig" "6" +"pkgconfig.js" "7" +"pkgconfig.qbs" "7" +"qbs" "6" +"qbsexporter.js" "7" +"qbsexporter.qbs" "7" "ib" "5" "ib.js" "6" "IBModule.qbs" "6" +"ico" "5" +"ico.js" "6" +"IcoModule.qbs" "6" "innosetup" "5" "InnoSetupModule.qbs" "6" "java" "5" @@ -12485,6 +13221,8 @@ "qbs-tsc-scan.ts" "7" "typescript.js" "6" "TypeScriptModule.qbs" "6" +"vcs" "5" +"vcs-module.qbs" "6" "wix" "5" "WiXModule.qbs" "6" "xcode" "5" @@ -12519,7 +13257,13 @@ "osx.py" "6" "qt_attribution.json" "6" "utils.py" "6" +"QML" "2" +"main.qml" "4" +"MainForm.ui.qml" "4" "Other files" "2" +"bin" "3" +"ibmsvc.xml" "4" +"ibqbs.bat" "4" "examples" "3" "app-and-lib" "4" "app" "5" @@ -12609,6 +13353,15 @@ "cheese.jpg" "8" "mouse.cpp" "5" "mouse.h" "5" +"compiled-qml" "4" +"cheese.jpg" "5" +"main.cpp" "5" +"myapp.qbs" "5" +"qml.qrc" "5" +"/" "6" +"cheese.jpg" "7" +"main.qml" "7" +"MainForm.ui.qml" "7" "helloworld-complex" "4" "src" "5" "foo.cpp" "6" @@ -12678,11 +13431,14 @@ "AndroidSdkProbe.qbs" "6" "BinaryProbe.qbs" "6" "FrameworkProbe.qbs" "6" +"GccBinaryProbe.qbs" "6" "GccProbe.qbs" "6" "GccVersionProbe.qbs" "6" +"IcoUtilsVersionProbe.qbs" "6" "IncludeProbe.qbs" "6" "InnoSetupProbe.qbs" "6" "JdkProbe.qbs" "6" +"JdkVersionProbe.qbs" "6" "MsvcProbe.qbs" "6" "NodeJsProbe.qbs" "6" "NpmProbe.qbs" "6" @@ -12711,7 +13467,6 @@ "BundleModule.qbs" "6" "MacOSX-Package-Types.xcspec" "6" "MacOSX-Product-Types.xcspec" "6" -"update-specs.sh" "6" "cli" "5" "cli.js" "6" "CLIModule.qbs" "6" @@ -12719,6 +13474,7 @@ "windows-dotnet.qbs" "6" "cpp" "5" "android-gcc.qbs" "6" +"cpp.js" "6" "CppModule.qbs" "6" "darwin.js" "6" "DarwinGCC.qbs" "6" @@ -12726,23 +13482,35 @@ "freebsd.js" "6" "gcc.js" "6" "GenericGCC.qbs" "6" -"genericunix-gcc.qbs" "6" "ios-gcc.qbs" "6" "LinuxGCC.qbs" "6" "macos-gcc.qbs" "6" "msvc.js" "6" "qnx-qcc.qbs" "6" +"setuprunenv.js" "6" "tvos-gcc.qbs" "6" "UnixGCC.qbs" "6" "watchos-gcc.qbs" "6" "windows-mingw.qbs" "6" "windows-msvc.qbs" "6" +"cpufeatures" "5" +"cpufeatures.qbs" "6" "dmg" "5" "dmg.js" "6" "DMGModule.qbs" "6" +"Exporter" "5" +"pkgconfig" "6" +"pkgconfig.js" "7" +"pkgconfig.qbs" "7" +"qbs" "6" +"qbsexporter.js" "7" +"qbsexporter.qbs" "7" "ib" "5" "ib.js" "6" "IBModule.qbs" "6" +"ico" "5" +"ico.js" "6" +"IcoModule.qbs" "6" "innosetup" "5" "InnoSetupModule.qbs" "6" "java" "5" @@ -12774,6 +13542,8 @@ "qbs-tsc-scan.ts" "7" "typescript.js" "6" "TypeScriptModule.qbs" "6" +"vcs" "5" +"vcs-module.qbs" "6" "wix" "5" "WiXModule.qbs" "6" "xcode" "5" @@ -12812,6 +13582,22 @@ "tools.pro" "2" "3rdparty" "2" "3rdparty.pro" "3" +"cplusplus-keywordgen" "3" +"cplusplus-keywordgen.pro" "4" +"tool" "4" +"tool.pri" "5" +"qtcreator" "5" +"qtcreator.pri" "6" +"cplusplus_dependencies" "6" +"cplusplus_dependencies.pri" "7" +"utils_dependencies" "6" +"utils_dependencies.pri" "7" +"rpath" "5" +"rpath.pri" "6" +"Sources" "4" +"cplusplus-keywordgen.cpp" "5" +"Other files" "4" +"cplusplus-keywordgen.qbs" "5" "buildoutputparser" "2" "buildoutputparser.pro" "3" "qtcreatortool" "3" @@ -12855,6 +13641,354 @@ "outputprocessor.cpp" "4" "Other files" "3" "buildoutputparser.qbs" "4" +"clangbackend" "2" +"clangbackend.pro" "3" +"clang_installation" "3" +"clang_installation.pri" "4" +"clangbackendclangipc-source" "3" +"clangbackendclangipc-source.pri" "4" +"Headers" "4" +"clangasyncjob.h" "5" +"clangbackend_global.h" "5" +"clangclock.h" "5" +"clangcodecompleteresults.h" "5" +"clangcodemodelserver.h" "5" +"clangcompletecodejob.h" "5" +"clangdocument.h" "5" +"clangdocumentjob.h" "5" +"clangdocumentprocessor.h" "5" +"clangdocumentprocessors.h" "5" +"clangdocuments.h" "5" +"clangdocumentsuspenderresumer.h" "5" +"clangexceptions.h" "5" +"clangfilepath.h" "5" +"clangfilesystemwatcher.h" "5" +"clangfollowsymbol.h" "5" +"clangfollowsymboljob.h" "5" +"clangiasyncjob.h" "5" +"clangjobcontext.h" "5" +"clangjobqueue.h" "5" +"clangjobrequest.h" "5" +"clangjobs.h" "5" +"clangparsesupportivetranslationunitjob.h" "5" +"clangreferencescollector.h" "5" +"clangrequestannotationsjob.h" "5" +"clangrequestreferencesjob.h" "5" +"clangrequesttooltipjob.h" "5" +"clangresumedocumentjob.h" "5" +"clangstring.h" "5" +"clangsupportivetranslationunitinitializer.h" "5" +"clangsuspenddocumentjob.h" "5" +"clangtooltipinfocollector.h" "5" +"clangtranslationunit.h" "5" +"clangtranslationunits.h" "5" +"clangtranslationunitupdater.h" "5" +"clangtype.h" "5" +"clangunsavedfilesshallowarguments.h" "5" +"clangupdateannotationsjob.h" "5" +"clangupdateextraannotationsjob.h" "5" +"codecompleter.h" "5" +"codecompletionchunkconverter.h" "5" +"codecompletionsextractor.h" "5" +"commandlinearguments.h" "5" +"cursor.h" "5" +"diagnostic.h" "5" +"diagnosticset.h" "5" +"diagnosticsetiterator.h" "5" +"fixit.h" "5" +"fulltokeninfo.h" "5" +"projectpart.h" "5" +"projects.h" "5" +"skippedsourceranges.h" "5" +"sourcelocation.h" "5" +"sourcerange.h" "5" +"tokeninfo.h" "5" +"tokenprocessor.h" "5" +"tokenprocessoriterator.h" "5" +"unsavedfile.h" "5" +"unsavedfiles.h" "5" +"utf8positionfromlinecolumn.h" "5" +"Sources" "4" +"clangcodecompleteresults.cpp" "5" +"clangcodemodelserver.cpp" "5" +"clangcompletecodejob.cpp" "5" +"clangdocument.cpp" "5" +"clangdocumentprocessor.cpp" "5" +"clangdocumentprocessors.cpp" "5" +"clangdocuments.cpp" "5" +"clangdocumentsuspenderresumer.cpp" "5" +"clangexceptions.cpp" "5" +"clangfilepath.cpp" "5" +"clangfilesystemwatcher.cpp" "5" +"clangfollowsymbol.cpp" "5" +"clangfollowsymboljob.cpp" "5" +"clangiasyncjob.cpp" "5" +"clangjobcontext.cpp" "5" +"clangjobqueue.cpp" "5" +"clangjobrequest.cpp" "5" +"clangjobs.cpp" "5" +"clangparsesupportivetranslationunitjob.cpp" "5" +"clangreferencescollector.cpp" "5" +"clangrequestannotationsjob.cpp" "5" +"clangrequestreferencesjob.cpp" "5" +"clangrequesttooltipjob.cpp" "5" +"clangresumedocumentjob.cpp" "5" +"clangsupportivetranslationunitinitializer.cpp" "5" +"clangsuspenddocumentjob.cpp" "5" +"clangtooltipinfocollector.cpp" "5" +"clangtranslationunit.cpp" "5" +"clangtranslationunits.cpp" "5" +"clangtranslationunitupdater.cpp" "5" +"clangtype.cpp" "5" +"clangunsavedfilesshallowarguments.cpp" "5" +"clangupdateannotationsjob.cpp" "5" +"clangupdateextraannotationsjob.cpp" "5" +"codecompleter.cpp" "5" +"codecompletionchunkconverter.cpp" "5" +"codecompletionsextractor.cpp" "5" +"commandlinearguments.cpp" "5" +"cursor.cpp" "5" +"diagnostic.cpp" "5" +"diagnosticset.cpp" "5" +"fixit.cpp" "5" +"fulltokeninfo.cpp" "5" +"projectpart.cpp" "5" +"projects.cpp" "5" +"skippedsourceranges.cpp" "5" +"sourcelocation.cpp" "5" +"sourcerange.cpp" "5" +"tokeninfo.cpp" "5" +"unsavedfile.cpp" "5" +"unsavedfiles.cpp" "5" +"utf8positionfromlinecolumn.cpp" "5" +"qtcreatortool" "3" +"qtcreatortool.pri" "4" +"qtcreator" "4" +"qtcreator.pri" "5" +"clangsupport_dependencies" "5" +"clangsupport_dependencies.pri" "6" +"sqlite_dependencies" "5" +"sqlite_dependencies.pri" "6" +"utils_dependencies" "5" +"utils_dependencies.pri" "6" +"rpath" "4" +"rpath.pri" "5" +"Headers" "3" +"crashhandlersetup.h" "5" +"Sources" "3" +"crashhandlersetup.cpp" "5" +"clangbackendmain.cpp" "4" +"Other files" "3" +"clangbackend.qbs" "4" +"clangpchmanagerbackend" "2" +"clangpchmanagerbackend.pro" "3" +"clang_installation" "3" +"clang_installation.pri" "4" +"clangpchmanagerbackend-source" "3" +"clangpchmanagerbackend-source.pri" "4" +"Headers" "4" +"clangpchmanagerbackend_global.h" "5" +"collectincludesaction.h" "5" +"collectincludespreprocessorcallbacks.h" "5" +"collectincludestoolaction.h" "5" +"environment.h" "5" +"includecollector.h" "5" +"pchcreator.h" "5" +"pchcreatorinterface.h" "5" +"pchgenerator.h" "5" +"pchgeneratorinterface.h" "5" +"pchgeneratornotifierinterface.h" "5" +"pchmanagerserver.h" "5" +"pchnotcreatederror.h" "5" +"projectparts.h" "5" +"projectpartsinterface.h" "5" +"Sources" "4" +"includecollector.cpp" "5" +"pchcreator.cpp" "5" +"pchmanagerserver.cpp" "5" +"projectparts.cpp" "5" +"qtcreatortool" "3" +"qtcreatortool.pri" "4" +"qtcreator" "4" +"qtcreator.pri" "5" +"clangsupport_dependencies" "5" +"clangsupport_dependencies.pri" "6" +"sqlite_dependencies" "5" +"sqlite_dependencies.pri" "6" +"utils_dependencies" "5" +"utils_dependencies.pri" "6" +"rpath" "4" +"rpath.pri" "5" +"Sources" "3" +"clangtool.cpp" "5" +"refactoringcompilationdatabase.cpp" "5" +"clangpchmanagerbackendmain.cpp" "4" +"Other files" "3" +"clangpchmanagerbackend.qbs" "4" +"clangrefactoringbackend" "2" +"clangrefactoringbackend.pro" "3" +"clang_installation" "3" +"clang_installation.pri" "4" +"clangrefactoringbackend-source" "3" +"clangrefactoringbackend-source.pri" "4" +"Headers" "4" +"clangquery.h" "5" +"clangquerygatherer.h" "5" +"clangrefactoringbackend_global.h" "5" +"clangtool.h" "5" +"collectmacrospreprocessorcallbacks.h" "5" +"collectmacrossourcefilecallbacks.h" "5" +"collectsymbolsaction.h" "5" +"filestatus.h" "5" +"filestatuscache.h" "5" +"findcursorusr.h" "5" +"findlocationsofusrs.h" "5" +"findusrforcursoraction.h" "5" +"indexdataconsumer.h" "5" +"locationsourcefilecallbacks.h" "5" +"macropreprocessorcallbacks.h" "5" +"projectpartartefact.h" "5" +"projectpartartefactexception.h" "5" +"projectpartentry.h" "5" +"refactoringcompilationdatabase.h" "5" +"refactoringserver.h" "5" +"sourcedependency.h" "5" +"sourcelocationentry.h" "5" +"sourcelocationsutils.h" "5" +"sourcerangeextractor.h" "5" +"sourcerangefilter.h" "5" +"storagesqlitestatementfactory.h" "5" +"symbolentry.h" "5" +"symbolfinder.h" "5" +"symbolindexer.h" "5" +"symbolindexing.h" "5" +"symbolindexinginterface.h" "5" +"symbollocationfinderaction.h" "5" +"symbolscollector.h" "5" +"symbolscollectorinterface.h" "5" +"symbolstorage.h" "5" +"symbolstorageinterface.h" "5" +"symbolsvisitorbase.h" "5" +"usedmacro.h" "5" +"Sources" "4" +"clangquery.cpp" "5" +"clangquerygatherer.cpp" "5" +"clangtool.cpp" "5" +"collectmacrossourcefilecallbacks.cpp" "5" +"collectsymbolsaction.cpp" "5" +"filestatuscache.cpp" "5" +"findusrforcursoraction.cpp" "5" +"indexdataconsumer.cpp" "5" +"locationsourcefilecallbacks.cpp" "5" +"macropreprocessorcallbacks.cpp" "5" +"projectpartartefact.cpp" "5" +"refactoringcompilationdatabase.cpp" "5" +"refactoringserver.cpp" "5" +"sourcerangeextractor.cpp" "5" +"sourcerangefilter.cpp" "5" +"symbolfinder.cpp" "5" +"symbolindexer.cpp" "5" +"symbolindexing.cpp" "5" +"symbollocationfinderaction.cpp" "5" +"symbolscollector.cpp" "5" +"qtcreatortool" "3" +"qtcreatortool.pri" "4" +"qtcreator" "4" +"qtcreator.pri" "5" +"clangsupport_dependencies" "5" +"clangsupport_dependencies.pri" "6" +"sqlite_dependencies" "5" +"sqlite_dependencies.pri" "6" +"utils_dependencies" "5" +"utils_dependencies.pri" "6" +"rpath" "4" +"rpath.pri" "5" +"Sources" "3" +"clangrefactoringbackendmain.cpp" "4" +"Other files" "3" +"clangrefactoringbackend.qbs" "4" +"cplusplus-ast2png" "2" +"cplusplus-ast2png.pro" "3" +"tool" "3" +"tool.pri" "4" +"qtcreator" "4" +"qtcreator.pri" "5" +"cplusplus_dependencies" "5" +"cplusplus_dependencies.pri" "6" +"utils_dependencies" "5" +"utils_dependencies.pri" "6" +"rpath" "4" +"rpath.pri" "5" +"utils" "3" +"utils.pri" "4" +"Headers" "4" +"utils.h" "5" +"Sources" "4" +"utils.cpp" "5" +"Sources" "3" +"cplusplus-ast2png.cpp" "4" +"Other files" "3" +"cplusplus-ast2png.qbs" "4" +"cplusplus-frontend" "2" +"cplusplus-frontend.pro" "3" +"tool" "3" +"tool.pri" "4" +"qtcreator" "4" +"qtcreator.pri" "5" +"cplusplus_dependencies" "5" +"cplusplus_dependencies.pri" "6" +"utils_dependencies" "5" +"utils_dependencies.pri" "6" +"rpath" "4" +"rpath.pri" "5" +"utils" "3" +"utils.pri" "4" +"Headers" "4" +"utils.h" "5" +"Sources" "4" +"utils.cpp" "5" +"Sources" "3" +"cplusplus-frontend.cpp" "4" +"Other files" "3" +"cplusplus-frontend.qbs" "4" +"cplusplus-mkvisitor" "2" +"cplusplus-mkvisitor.pro" "3" +"tool" "3" +"tool.pri" "4" +"qtcreator" "4" +"qtcreator.pri" "5" +"cplusplus_dependencies" "5" +"cplusplus_dependencies.pri" "6" +"utils_dependencies" "5" +"utils_dependencies.pri" "6" +"rpath" "4" +"rpath.pri" "5" +"utils" "3" +"utils.pri" "4" +"Headers" "4" +"utils.h" "5" +"Sources" "4" +"utils.cpp" "5" +"Sources" "3" +"cplusplus-mkvisitor.cpp" "4" +"Other files" "3" +"cplusplus-mkvisitor.qbs" "4" +"cplusplus-update-frontend" "2" +"cplusplus-update-frontend.pro" "3" +"tool" "3" +"tool.pri" "4" +"qtcreator" "4" +"qtcreator.pri" "5" +"cplusplus_dependencies" "5" +"cplusplus_dependencies.pri" "6" +"utils_dependencies" "5" +"utils_dependencies.pri" "6" +"rpath" "4" +"rpath.pri" "5" +"Sources" "3" +"cplusplus-update-frontend.cpp" "4" +"Other files" "3" +"cplusplus-update-frontend.qbs" "4" "frontend" "2" "frontend.pro" "3" "qtcreatortool" "3" @@ -12889,6 +14023,20 @@ "main.cpp" "4" "Other files" "3" "frontend.qbs" "4" +"iostool" "2" +"iostool.pro" "3" +"qtcreator" "3" +"qtcreator.pri" "4" +"rpath" "3" +"rpath.pri" "4" +"Headers" "3" +"iosdevicemanager.h" "4" +"Sources" "3" +"iosdevicemanager.cpp" "4" +"main.cpp" "4" +"Other files" "3" +"Info.plist" "4" +"iostool.qbs" "4" "qml2puppet" "2" "qml2puppet.pro" "3" "qml2puppet" "3" @@ -12976,6 +14124,8 @@ "propertybindingcontainer.cpp" "7" "propertyvaluecontainer.cpp" "7" "reparentcontainer.cpp" "7" +"sharedmemory_qt.cpp" "7" +"sharedmemory_unix.cpp" "7" "instances" "5" "instances.pri" "6" "Headers" "6" @@ -13042,8 +14192,13 @@ "qmlprivategate" "5" "qmlprivategate.pri" "6" "Headers" "6" +"designercustomobjectdata.h" "7" +"metaobject.h" "7" "qmlprivategate.h" "7" "Sources" "6" +"designercustomobjectdata.cpp" "7" +"metaobject.cpp" "7" +"qmlprivategate.cpp" "7" "qmlprivategate_56.cpp" "7" "types" "5" "types.pri" "6" @@ -13074,6 +14229,61 @@ "qtcreator.pri" "4" "Other files" "3" "qml2puppet.qbs" "4" +"qtcdebugger" "2" +"qtcdebugger.pro" "3" +"qtcreatortool" "3" +"qtcreatortool.pri" "4" +"qtcreator" "4" +"qtcreator.pri" "5" +"rpath" "4" +"rpath.pri" "5" +"registryaccess" "3" +"registryaccess.pri" "4" +"Headers" "4" +"registryaccess.h" "5" +"Sources" "4" +"registryaccess.cpp" "5" +"Sources" "3" +"main.cpp" "4" +"Other files" "3" +"qtcdebugger.qbs" "4" +"qtcrashhandler" "2" +"qtcrashhandler.pro" "3" +"qtcrashhandler" "3" +"qtcrashhandler.pri" "4" +"qtcreatortool" "3" +"qtcreatortool.pri" "4" +"qtcreator" "4" +"qtcreator.pri" "5" +"rpath" "4" +"rpath.pri" "5" +"qtcreatorcrashhandler" "2" +"qtcreatorcrashhandler.pro" "3" +"qtcreatortool" "3" +"qtcreatortool.pri" "4" +"qtcreator" "4" +"qtcreator.pri" "5" +"utils_dependencies" "5" +"utils_dependencies.pri" "6" +"rpath" "4" +"rpath.pri" "5" +"Headers" "3" +"backtracecollector.h" "4" +"crashhandler.h" "4" +"crashhandlerdialog.h" "4" +"utils.h" "4" +"Sources" "3" +"backtracecollector.cpp" "4" +"crashhandler.cpp" "4" +"crashhandlerdialog.cpp" "4" +"main.cpp" "4" +"utils.cpp" "4" +"Forms" "3" +"crashhandlerdialog.ui" "4" +"Other files" "3" +"qtcreatorcrashhandler.qbs" "4" +"qtpromaker" "2" +"qtpromaker.pro" "3" "qtcreatortool" "3" "qtcreatortool.pri" "4" "qtcreator" "4" @@ -13083,6 +14293,9 @@ "Sources" "3" "main.cpp" "4" "Other files" "3" +"qtpromaker.qbs" "4" +"sdktool" "2" +"sdktool.pro" "3" "qtcreatortool" "3" "qtcreatortool.pri" "4" "qtcreator" "4" @@ -13091,7 +14304,9 @@ "rpath.pri" "5" "Headers" "3" "fileutils.h" "6" +"fileutils_mac.h" "6" "hostosinfo.h" "6" +"persistentsettings.h" "6" "qtcassert.h" "6" "savefile.h" "6" "shared" "5" @@ -13142,6 +14357,7 @@ "rmtoolchainoperation.cpp" "4" "settings.cpp" "4" "Other files" "3" +"sdktool.qbs" "4" "valgrindfake" "2" "valgrindfake.pro" "3" "qtcreator" "3" @@ -13153,6 +14369,28 @@ "outputgenerator.cpp" "4" "Other files" "3" "valgrindfake.qbs" "4" +"wininterrupt" "2" +"wininterrupt.pro" "3" +"qtcreatortool" "3" +"qtcreatortool.pri" "4" +"qtcreator" "4" +"qtcreator.pri" "5" +"rpath" "4" +"rpath.pri" "5" +"Sources" "3" +"wininterrupt.c" "4" +"winrtdebughelper" "2" +"winrtdebughelper.pro" "3" +"qtcreatortool" "3" +"qtcreatortool.pri" "4" +"qtcreator" "4" +"qtcreator.pri" "5" +"rpath" "4" +"rpath.pri" "5" +"Sources" "3" +"winrtdebughelper.cpp" "4" +"Other files" "3" +"winrtdebughelper.qbs" "4" "Other files" "1" "src.qbs" "2" "tests" "0" @@ -13200,12 +14438,12 @@ "tst_changeset.cpp" "4" "Other files" "3" "changeset.qbs" "4" -"clangstaticanalyzer" "2" -"clangstaticanalyzer.pro" "3" -"clangstaticanalyzerlogfilereader" "3" -"clangstaticanalyzerlogfilereader.pro" "4" -"clangstaticanalyzertest" "4" -"clangstaticanalyzertest.pri" "5" +"cplusplus" "2" +"cplusplus.pro" "3" +"ast" "3" +"ast.pro" "4" +"shared" "4" +"shared.pri" "5" "qttest" "5" "qttest.pri" "6" "qtcreator" "6" @@ -13218,20 +14456,10 @@ "cplusplus_dependencies.pri" "8" "cpptools_dependencies" "7" "cpptools_dependencies.pri" "8" -"debugger_dependencies" "7" -"debugger_dependencies.pri" "8" "extensionsystem_dependencies" "7" "extensionsystem_dependencies.pri" "8" -"languageutils_dependencies" "7" -"languageutils_dependencies.pri" "8" "projectexplorer_dependencies" "7" "projectexplorer_dependencies.pri" "8" -"qmldebug_dependencies" "7" -"qmldebug_dependencies.pri" "8" -"qmljs_dependencies" "7" -"qmljs_dependencies.pri" "8" -"qtsupport_dependencies" "7" -"qtsupport_dependencies.pri" "8" "ssh_dependencies" "7" "ssh_dependencies.pri" "8" "texteditor_dependencies" "7" @@ -13240,19 +14468,16 @@ "utils_dependencies.pri" "8" "qttestrpath" "6" "qttestrpath.pri" "7" -"Headers" "4" -"clangstaticanalyzerdiagnostic.h" "6" -"clangstaticanalyzerlogfilereader.h" "6" +"rpath" "5" +"rpath.pri" "6" "Sources" "4" -"clangstaticanalyzerdiagnostic.cpp" "6" -"clangstaticanalyzerlogfilereader.cpp" "6" -"tst_clangstaticanalyzerlogfilereader.cpp" "5" +"tst_ast.cpp" "5" "Other files" "4" -"clangstaticanalyzerlogfilereader.qbs" "5" -"clangstaticanalyzerrunner" "3" -"clangstaticanalyzerrunner.pro" "4" -"clangstaticanalyzertest" "4" -"clangstaticanalyzertest.pri" "5" +"ast.qbs" "5" +"c99" "3" +"c99.pro" "4" +"shared" "4" +"shared.pri" "5" "qttest" "5" "qttest.pri" "6" "qtcreator" "6" @@ -13265,20 +14490,10 @@ "cplusplus_dependencies.pri" "8" "cpptools_dependencies" "7" "cpptools_dependencies.pri" "8" -"debugger_dependencies" "7" -"debugger_dependencies.pri" "8" "extensionsystem_dependencies" "7" "extensionsystem_dependencies.pri" "8" -"languageutils_dependencies" "7" -"languageutils_dependencies.pri" "8" "projectexplorer_dependencies" "7" "projectexplorer_dependencies.pri" "8" -"qmldebug_dependencies" "7" -"qmldebug_dependencies.pri" "8" -"qmljs_dependencies" "7" -"qmljs_dependencies.pri" "8" -"qtsupport_dependencies" "7" -"qtsupport_dependencies.pri" "8" "ssh_dependencies" "7" "ssh_dependencies.pri" "8" "texteditor_dependencies" "7" @@ -13287,81 +14502,10 @@ "utils_dependencies.pri" "8" "qttestrpath" "6" "qttestrpath.pri" "7" -"Headers" "4" -"clangstaticanalyzerrunner.h" "6" +"rpath" "5" +"rpath.pri" "6" "Sources" "4" -"clangstaticanalyzerrunner.cpp" "6" -"tst_clangstaticanalyzerrunner.cpp" "5" -"Other files" "4" -"clangstaticanalyzerrunner.qbs" "5" -"cplusplus" "2" -"cplusplus.pro" "3" -"ast" "3" -"ast.pro" "4" -"shared" "4" -"shared.pri" "5" -"qttest" "5" -"qttest.pri" "6" -"qtcreator" "6" -"qtcreator.pri" "7" -"aggregation_dependencies" "7" -"aggregation_dependencies.pri" "8" -"coreplugin_dependencies" "7" -"coreplugin_dependencies.pri" "8" -"cplusplus_dependencies" "7" -"cplusplus_dependencies.pri" "8" -"cpptools_dependencies" "7" -"cpptools_dependencies.pri" "8" -"extensionsystem_dependencies" "7" -"extensionsystem_dependencies.pri" "8" -"projectexplorer_dependencies" "7" -"projectexplorer_dependencies.pri" "8" -"ssh_dependencies" "7" -"ssh_dependencies.pri" "8" -"texteditor_dependencies" "7" -"texteditor_dependencies.pri" "8" -"utils_dependencies" "7" -"utils_dependencies.pri" "8" -"qttestrpath" "6" -"qttestrpath.pri" "7" -"rpath" "5" -"rpath.pri" "6" -"Sources" "4" -"tst_ast.cpp" "5" -"Other files" "4" -"ast.qbs" "5" -"c99" "3" -"c99.pro" "4" -"shared" "4" -"shared.pri" "5" -"qttest" "5" -"qttest.pri" "6" -"qtcreator" "6" -"qtcreator.pri" "7" -"aggregation_dependencies" "7" -"aggregation_dependencies.pri" "8" -"coreplugin_dependencies" "7" -"coreplugin_dependencies.pri" "8" -"cplusplus_dependencies" "7" -"cplusplus_dependencies.pri" "8" -"cpptools_dependencies" "7" -"cpptools_dependencies.pri" "8" -"extensionsystem_dependencies" "7" -"extensionsystem_dependencies.pri" "8" -"projectexplorer_dependencies" "7" -"projectexplorer_dependencies.pri" "8" -"ssh_dependencies" "7" -"ssh_dependencies.pri" "8" -"texteditor_dependencies" "7" -"texteditor_dependencies.pri" "8" -"utils_dependencies" "7" -"utils_dependencies.pri" "8" -"qttestrpath" "6" -"qttestrpath.pri" "7" -"rpath" "5" -"rpath.pri" "6" -"Sources" "4" -"tst_c99.cpp" "5" +"tst_c99.cpp" "5" "Other files" "4" "data" "5" "designatedInitializer.1.c" "6" @@ -13507,6 +14651,8 @@ "data" "5" "inlineNamespace.1.cpp" "6" "inlineNamespace.1.errors.txt" "6" +"nestedNamespace.1.cpp" "6" +"nestedNamespace.1.errors.txt" "6" "noExcept.1.cpp" "6" "noExcept.1.errors.txt" "6" "staticAssert.1.cpp" "6" @@ -13879,7 +15025,21 @@ "rpath" "4" "rpath.pri" "5" "Headers" "4" +"processhandle.h" "7" +"qtcassert.h" "7" +"treemodel.h" "7" +"debuggerprotocol.h" "7" +"simplifytype.h" "7" +"watchdata.h" "7" +"watchutils.h" "7" "Sources" "4" +"processhandle.cpp" "7" +"qtcassert.cpp" "7" +"treemodel.cpp" "7" +"debuggerprotocol.cpp" "7" +"simplifytype.cpp" "7" +"watchdata.cpp" "7" +"watchutils.cpp" "7" "tst_dumpers.cpp" "5" "Other files" "4" "dumpers.qbs" "5" @@ -14224,20 +15384,6 @@ "Other files" "3" "filesearch.qbs" "4" "testfile.txt" "4" -"flamegraph" "2" -"flamegraph.pro" "3" -"qttest" "3" -"qttest.pri" "4" -"qtcreator" "4" -"qtcreator.pri" "5" -"flamegraph_dependencies" "5" -"flamegraph_dependencies.pri" "6" -"qttestrpath" "4" -"qttestrpath.pri" "5" -"Sources" "3" -"tst_flamegraph.cpp" "4" -"Other files" "3" -"flamegraph.qbs" "4" "generichighlighter" "2" "generichighlighter.pro" "3" "highlighterengine" "3" @@ -14339,6 +15485,19 @@ "Other files" "3" "mapreduce.h" "5" "mapreduce.qbs" "4" +"pointeralgorithm" "2" +"pointeralgorithm.pro" "3" +"qttest" "3" +"qttest.pri" "4" +"qtcreator" "4" +"qtcreator.pri" "5" +"qttestrpath" "4" +"qttestrpath.pri" "5" +"Sources" "3" +"tst_pointeralgorithm.cpp" "4" +"Other files" "3" +"pointeralgorithm.h" "5" +"pointeralgorithm.qbs" "4" "profilewriter" "2" "profilewriter.pro" "3" "proparser" "3" @@ -14730,6 +15889,8 @@ "propertybindingcontainer.cpp" "8" "propertyvaluecontainer.cpp" "8" "reparentcontainer.cpp" "8" +"sharedmemory_qt.cpp" "8" +"sharedmemory_unix.cpp" "8" "filemanager" "6" "filemanager.pri" "7" "Headers" "7" @@ -14842,6 +16003,8 @@ "qmlmodelnodefacade.h" "8" "qmlobjectnode.h" "8" "qmlstate.h" "8" +"qmltimeline.h" "8" +"qmltimelinekeyframegroup.h" "8" "removebasestateexception.h" "8" "rewriterview.h" "8" "rewritingexception.h" "8" @@ -14900,6 +16063,7 @@ "abstractproperty.cpp" "8" "abstractview.cpp" "8" "anchorline.cpp" "8" +"basetexteditmodifier.cpp" "8" "bindingproperty.cpp" "8" "componenttextmodifier.cpp" "8" "documentmessage.cpp" "8" @@ -14932,6 +16096,8 @@ "qmlobjectnode.cpp" "8" "qmlstate.cpp" "8" "qmltextgenerator.cpp" "8" +"qmltimeline.cpp" "8" +"qmltimelinekeyframegroup.cpp" "8" "rewriteaction.cpp" "8" "rewriteactioncompressor.cpp" "8" "rewriterview.cpp" "8" @@ -15220,8 +16386,56 @@ "tst_sdktool.cpp" "4" "Other files" "3" "sdktool.qbs" "4" -"timeline" "2" -"timeline.pro" "3" +"toolchaincache" "2" +"toolchaincache.pro" "3" +"qttest" "3" +"qttest.pri" "4" +"qtcreator" "4" +"qtcreator.pri" "5" +"qttestrpath" "4" +"qttestrpath.pri" "5" +"Sources" "3" +"tst_toolchaincache.cpp" "4" +"Other files" "3" +"toolchaincache.qbs" "4" +"tracing" "2" +"tracing.pro" "3" +"flamegraph" "3" +"flamegraph.pro" "4" +"qttest" "4" +"qttest.pri" "5" +"qtcreator" "5" +"qtcreator.pri" "6" +"tracing_dependencies" "6" +"tracing_dependencies.pri" "7" +"utils_dependencies" "6" +"utils_dependencies.pri" "7" +"qttestrpath" "5" +"qttestrpath.pri" "6" +"Sources" "4" +"tst_flamegraph.cpp" "5" +"Other files" "4" +"flamegraph.qbs" "5" +"flamegraphview" "3" +"flamegraphview.pro" "4" +"qttest" "4" +"qttest.pri" "5" +"qtcreator" "5" +"qtcreator.pri" "6" +"tracing_dependencies" "6" +"tracing_dependencies.pri" "7" +"utils_dependencies" "6" +"utils_dependencies.pri" "7" +"qttestrpath" "5" +"qttestrpath.pri" "6" +"Sources" "4" +"tst_flamegraphview.cpp" "5" +"Resources" "4" +"flamegraphview.qrc" "5" +"/tracingtest" "6" +"TestFlameGraphView.qml" "7" +"Other files" "4" +"flamegraphview.qbs" "5" "qtcreator" "3" "qtcreator.pri" "4" "timelineabstractrenderer" "3" @@ -15230,8 +16444,8 @@ "qttest.pri" "5" "qtcreator" "5" "qtcreator.pri" "6" -"timeline_dependencies" "6" -"timeline_dependencies.pri" "7" +"tracing_dependencies" "6" +"tracing_dependencies.pri" "7" "utils_dependencies" "6" "utils_dependencies.pri" "7" "qttestrpath" "5" @@ -15246,8 +16460,8 @@ "qttest.pri" "5" "qtcreator" "5" "qtcreator.pri" "6" -"timeline_dependencies" "6" -"timeline_dependencies.pri" "7" +"tracing_dependencies" "6" +"tracing_dependencies.pri" "7" "utils_dependencies" "6" "utils_dependencies.pri" "7" "qttestrpath" "5" @@ -15262,8 +16476,8 @@ "qttest.pri" "5" "qtcreator" "5" "qtcreator.pri" "6" -"timeline_dependencies" "6" -"timeline_dependencies.pri" "7" +"tracing_dependencies" "6" +"tracing_dependencies.pri" "7" "utils_dependencies" "6" "utils_dependencies.pri" "7" "qttestrpath" "5" @@ -15278,8 +16492,8 @@ "qttest.pri" "5" "qtcreator" "5" "qtcreator.pri" "6" -"timeline_dependencies" "6" -"timeline_dependencies.pri" "7" +"tracing_dependencies" "6" +"tracing_dependencies.pri" "7" "utils_dependencies" "6" "utils_dependencies.pri" "7" "qttestrpath" "5" @@ -15294,8 +16508,8 @@ "qttest.pri" "5" "qtcreator" "5" "qtcreator.pri" "6" -"timeline_dependencies" "6" -"timeline_dependencies.pri" "7" +"tracing_dependencies" "6" +"tracing_dependencies.pri" "7" "utils_dependencies" "6" "utils_dependencies.pri" "7" "qttestrpath" "5" @@ -15310,8 +16524,8 @@ "qttest.pri" "5" "qtcreator" "5" "qtcreator.pri" "6" -"timeline_dependencies" "6" -"timeline_dependencies.pri" "7" +"tracing_dependencies" "6" +"tracing_dependencies.pri" "7" "utils_dependencies" "6" "utils_dependencies.pri" "7" "qttestrpath" "5" @@ -15326,8 +16540,8 @@ "qttest.pri" "5" "qtcreator" "5" "qtcreator.pri" "6" -"timeline_dependencies" "6" -"timeline_dependencies.pri" "7" +"tracing_dependencies" "6" +"tracing_dependencies.pri" "7" "utils_dependencies" "6" "utils_dependencies.pri" "7" "qttestrpath" "5" @@ -15342,8 +16556,8 @@ "qttest.pri" "5" "qtcreator" "5" "qtcreator.pri" "6" -"timeline_dependencies" "6" -"timeline_dependencies.pri" "7" +"tracing_dependencies" "6" +"tracing_dependencies.pri" "7" "utils_dependencies" "6" "utils_dependencies.pri" "7" "qttestrpath" "5" @@ -15358,8 +16572,8 @@ "qttest.pri" "5" "qtcreator" "5" "qtcreator.pri" "6" -"timeline_dependencies" "6" -"timeline_dependencies.pri" "7" +"tracing_dependencies" "6" +"tracing_dependencies.pri" "7" "utils_dependencies" "6" "utils_dependencies.pri" "7" "qttestrpath" "5" @@ -15374,8 +16588,8 @@ "qttest.pri" "5" "qtcreator" "5" "qtcreator.pri" "6" -"timeline_dependencies" "6" -"timeline_dependencies.pri" "7" +"tracing_dependencies" "6" +"tracing_dependencies.pri" "7" "utils_dependencies" "6" "utils_dependencies.pri" "7" "qttestrpath" "5" @@ -15390,8 +16604,8 @@ "qttest.pri" "5" "qtcreator" "5" "qtcreator.pri" "6" -"timeline_dependencies" "6" -"timeline_dependencies.pri" "7" +"tracing_dependencies" "6" +"tracing_dependencies.pri" "7" "utils_dependencies" "6" "utils_dependencies.pri" "7" "qttestrpath" "5" @@ -15406,8 +16620,8 @@ "qttest.pri" "5" "qtcreator" "5" "qtcreator.pri" "6" -"timeline_dependencies" "6" -"timeline_dependencies.pri" "7" +"tracing_dependencies" "6" +"tracing_dependencies.pri" "7" "utils_dependencies" "6" "utils_dependencies.pri" "7" "qttestrpath" "5" @@ -15417,8 +16631,8 @@ "Other files" "4" "timelinezoomcontrol.qbs" "5" "Other files" "3" -"timeline.qbs" "4" -"timelineautotest.qbs" "4" +"tracing.qbs" "4" +"tracingautotest.qbs" "4" "treeviewfind" "2" "treeviewfind.pro" "3" "qttest" "3" @@ -15469,8 +16683,22 @@ "tst_fileutils.cpp" "5" "Other files" "4" "fileutils.qbs" "5" -"objectpool" "3" -"objectpool.pro" "4" +"fuzzymatcher" "3" +"fuzzymatcher.pro" "4" +"qttest" "4" +"qttest.pri" "5" +"qtcreator" "5" +"qtcreator.pri" "6" +"utils_dependencies" "6" +"utils_dependencies.pri" "7" +"qttestrpath" "5" +"qttestrpath.pri" "6" +"Sources" "4" +"tst_fuzzymatcher.cpp" "5" +"Other files" "4" +"fuzzymatcher.qbs" "5" +"settings" "3" +"settings.pro" "4" "qttest" "4" "qttest.pri" "5" "qtcreator" "5" @@ -15480,9 +16708,9 @@ "qttestrpath" "5" "qttestrpath.pri" "6" "Sources" "4" -"tst_objectpool.cpp" "5" +"tst_settings.cpp" "5" "Other files" "4" -"objectpool.qbs" "5" +"settings.qbs" "5" "stringutils" "3" "stringutils.pro" "4" "qttest" "4" @@ -15901,10 +17129,117 @@ "plugin3.cpp" "6" "Other files" "5" "plugin3.json" "6" +"process" "2" +"process.pro" "3" +"qtcreator" "3" +"qtcreator.pri" "4" +"utils_dependencies" "4" +"utils_dependencies.pri" "5" +"Headers" "3" +"mainwindow.h" "4" +"Sources" "3" +"main.cpp" "4" +"mainwindow.cpp" "4" "shootout" "2" "shootout.pro" "3" "Sources" "3" "tst_codesize.cpp" "4" +"ssh" "2" +"ssh.pro" "3" +"errorhandling" "3" +"errorhandling.pro" "4" +"ssh" "4" +"ssh.pri" "5" +"qtcreator" "5" +"qtcreator.pri" "6" +"ssh_dependencies" "6" +"ssh_dependencies.pri" "7" +"Sources" "4" +"main.cpp" "5" +"remoteprocess" "3" +"remoteprocess.pro" "4" +"ssh" "4" +"ssh.pri" "5" +"qtcreator" "5" +"qtcreator.pri" "6" +"ssh_dependencies" "6" +"ssh_dependencies.pri" "7" +"Headers" "4" +"argumentscollector.h" "5" +"remoteprocesstest.h" "5" +"Sources" "4" +"argumentscollector.cpp" "5" +"main.cpp" "5" +"remoteprocesstest.cpp" "5" +"sftp" "3" +"sftp.pro" "4" +"ssh" "4" +"ssh.pri" "5" +"qtcreator" "5" +"qtcreator.pri" "6" +"ssh_dependencies" "6" +"ssh_dependencies.pri" "7" +"Headers" "4" +"argumentscollector.h" "5" +"parameters.h" "5" +"sftptest.h" "5" +"Sources" "4" +"argumentscollector.cpp" "5" +"main.cpp" "5" +"sftptest.cpp" "5" +"sftpfsmodel" "3" +"sftpfsmodel.pro" "4" +"modeltest" "4" +"modeltest.pri" "5" +"Headers" "5" +"modeltest.h" "6" +"Sources" "5" +"modeltest.cpp" "6" +"ssh" "4" +"ssh.pri" "5" +"qtcreator" "5" +"qtcreator.pri" "6" +"ssh_dependencies" "6" +"ssh_dependencies.pri" "7" +"Headers" "4" +"window.h" "5" +"Sources" "4" +"main.cpp" "5" +"window.cpp" "5" +"Forms" "4" +"window.ui" "5" +"shell" "3" +"shell.pro" "4" +"ssh" "4" +"ssh.pri" "5" +"qtcreator" "5" +"qtcreator.pri" "6" +"ssh_dependencies" "6" +"ssh_dependencies.pri" "7" +"Headers" "4" +"argumentscollector.h" "6" +"shell.h" "5" +"Sources" "4" +"argumentscollector.cpp" "6" +"main.cpp" "5" +"shell.cpp" "5" +"tunnel" "3" +"tunnel.pro" "4" +"ssh" "4" +"ssh.pri" "5" +"qtcreator" "5" +"qtcreator.pri" "6" +"ssh_dependencies" "6" +"ssh_dependencies.pri" "7" +"Headers" "4" +"argumentscollector.h" "5" +"directtunnel.h" "5" +"forwardtunnel.h" "5" +"Sources" "4" +"argumentscollector.cpp" "5" +"directtunnel.cpp" "5" +"forwardtunnel.cpp" "5" +"main.cpp" "5" "testreader" "2" "testreader.pro" "3" "Headers" "3" @@ -15933,6 +17268,34 @@ "spec_pre.prf" "6" "/qmake/override_features" "5" "objective_c.prf" "6" +"widgets" "2" +"widgets.pro" "3" +"crumblepath" "3" +"crumblepath.pro" "4" +"qttest" "4" +"qttest.pri" "5" +"qtcreator" "5" +"qtcreator.pri" "6" +"aggregation_dependencies" "6" +"aggregation_dependencies.pri" "7" +"coreplugin_dependencies" "6" +"coreplugin_dependencies.pri" "7" +"extensionsystem_dependencies" "6" +"extensionsystem_dependencies.pri" "7" +"utils_dependencies" "6" +"utils_dependencies.pri" "7" +"qttestrpath" "5" +"qttestrpath.pri" "6" +"Sources" "4" +"tst_crumblepath.cpp" "5" +"Resources" "4" +"tst_crumblepath.qrc" "5" +"/" "6" +"dark.creatortheme" "7" +"default.creatortheme" "7" +"flat-dark.creatortheme" "7" +"flat-light.creatortheme" "7" +"flat.creatortheme" "7" "tools" "1" "tools.pro" "2" "qml-ast2dot" "2" @@ -15953,16 +17316,2270 @@ "utils_dependencies.pri" "5" "Sources" "3" "main.cpp" "4" +"unit" "1" +"unit.pro" "2" +"echoserver" "2" +"echoserver.pro" "3" +"clangsupport-lib" "3" +"clangsupport-lib.pri" "4" +"Headers" "4" +"alivemessage.h" "5" +"annotationsmessage.h" "5" +"baseserverproxy.h" "5" +"cancelmessage.h" "5" +"clangcodemodelclientinterface.h" "5" +"clangcodemodelclientmessages.h" "5" +"clangcodemodelclientproxy.h" "5" +"clangcodemodelconnectionclient.h" "5" +"clangcodemodelserverinterface.h" "5" +"clangcodemodelservermessages.h" "5" +"clangcodemodelserverproxy.h" "5" +"clangpathwatcher.h" "5" +"clangpathwatcherinterface.h" "5" +"clangpathwatchernotifier.h" "5" +"clangrefactoringclientmessages.h" "5" +"clangrefactoringmessages.h" "5" +"clangrefactoringservermessages.h" "5" +"clangsupport_global.h" "5" +"clangsupportdebugutils.h" "5" +"codecompletion.h" "5" +"codecompletionchunk.h" "5" +"compilermacro.h" "5" +"completionsmessage.h" "5" +"connectionclient.h" "5" +"connectionserver.h" "5" +"diagnosticcontainer.h" "5" +"documentschangedmessage.h" "5" +"documentsclosedmessage.h" "5" +"documentsopenedmessage.h" "5" +"documentvisibilitychangedmessage.h" "5" +"dynamicastmatcherdiagnosticcontainer.h" "5" +"dynamicastmatcherdiagnosticcontextcontainer.h" "5" +"dynamicastmatcherdiagnosticmessagecontainer.h" "5" +"dynamicmatcherdiagnostics.h" "5" +"echomessage.h" "5" +"endmessage.h" "5" +"filecontainer.h" "5" +"filecontainerv2.h" "5" +"filepath.h" "5" +"filepathcache.h" "5" +"filepathcaching.h" "5" +"filepathcachingfwd.h" "5" +"filepathcachinginterface.h" "5" +"filepathexceptions.h" "5" +"filepathid.h" "5" +"filepathstorage.h" "5" +"filepathstoragesources.h" "5" +"filepathstoragesqlitestatementfactory.h" "5" +"filepathview.h" "5" +"fixitcontainer.h" "5" +"followsymbolmessage.h" "5" +"idpaths.h" "5" +"ipcclientinterface.h" "5" +"ipcclientprovider.h" "5" +"ipcinterface.h" "5" +"ipcserverinterface.h" "5" +"lineprefixer.h" "5" +"messageenvelop.h" "5" +"nativefilepath.h" "5" +"pchmanagerclientinterface.h" "5" +"pchmanagerclientproxy.h" "5" +"pchmanagerserverinterface.h" "5" +"pchmanagerserverproxy.h" "5" +"precompiledheadersupdatedmessage.h" "5" +"processcreator.h" "5" +"processexception.h" "5" +"processhandle.h" "5" +"processstartedevent.h" "5" +"projectmanagementserverinterface.h" "5" +"projectpartcontainer.h" "5" +"projectpartcontainerv2.h" "5" +"projectpartpch.h" "5" +"projectpartpchproviderinterface.h" "5" +"projectpartsremovedmessage.h" "5" +"projectpartsupdatedmessage.h" "5" +"readmessageblock.h" "5" +"refactoringclientinterface.h" "5" +"refactoringclientproxy.h" "5" +"refactoringdatabaseinitializer.h" "5" +"refactoringserverinterface.h" "5" +"refactoringserverproxy.h" "5" +"referencesmessage.h" "5" +"removeprojectpartsmessage.h" "5" +"requestannotationsmessage.h" "5" +"requestcompletionsmessage.h" "5" +"requestfollowsymbolmessage.h" "5" +"requestreferencesmessage.h" "5" +"requestsourcelocationforrenamingmessage.h" "5" +"requestsourcerangesanddiagnosticsforquerymessage.h" "5" +"requestsourcerangesforquerymessage.h" "5" +"requesttooltipmessage.h" "5" +"sourcelocationcontainer.h" "5" +"sourcelocationcontainerv2.h" "5" +"sourcelocationscontainer.h" "5" +"sourcelocationsforrenamingmessage.h" "5" +"sourcerangecontainer.h" "5" +"sourcerangecontainerv2.h" "5" +"sourcerangesanddiagnosticsforquerymessage.h" "5" +"sourcerangescontainer.h" "5" +"sourcerangesforquerymessage.h" "5" +"sourcerangewithtextcontainer.h" "5" +"stringcache.h" "5" +"stringcachealgorithms.h" "5" +"stringcachefwd.h" "5" +"tokeninfocontainer.h" "5" +"tooltipinfo.h" "5" +"tooltipmessage.h" "5" +"unsavedfilesremovedmessage.h" "5" +"unsavedfilesupdatedmessage.h" "5" +"updateprojectpartsmessage.h" "5" +"writemessageblock.h" "5" +"Sources" "4" +"alivemessage.cpp" "5" +"annotationsmessage.cpp" "5" +"baseserverproxy.cpp" "5" +"cancelmessage.cpp" "5" +"clangcodemodelclientinterface.cpp" "5" +"clangcodemodelclientproxy.cpp" "5" +"clangcodemodelconnectionclient.cpp" "5" +"clangcodemodelserverinterface.cpp" "5" +"clangcodemodelserverproxy.cpp" "5" +"clangsupportdebugutils.cpp" "5" +"codecompletion.cpp" "5" +"codecompletionchunk.cpp" "5" +"completionsmessage.cpp" "5" +"connectionclient.cpp" "5" +"connectionserver.cpp" "5" +"diagnosticcontainer.cpp" "5" +"documentschangedmessage.cpp" "5" +"documentsclosedmessage.cpp" "5" +"documentsopenedmessage.cpp" "5" +"documentvisibilitychangedmessage.cpp" "5" +"dynamicastmatcherdiagnosticcontainer.cpp" "5" +"dynamicastmatcherdiagnosticcontextcontainer.cpp" "5" +"dynamicastmatcherdiagnosticmessagecontainer.cpp" "5" +"echomessage.cpp" "5" +"endmessage.cpp" "5" +"filecontainer.cpp" "5" +"filecontainerv2.cpp" "5" +"filepath.cpp" "5" +"filepathcaching.cpp" "5" +"filepathid.cpp" "5" +"fixitcontainer.cpp" "5" +"followsymbolmessage.cpp" "5" +"lineprefixer.cpp" "5" +"messageenvelop.cpp" "5" +"pchmanagerclientinterface.cpp" "5" +"pchmanagerclientproxy.cpp" "5" +"pchmanagerserverinterface.cpp" "5" +"pchmanagerserverproxy.cpp" "5" +"precompiledheadersupdatedmessage.cpp" "5" +"processcreator.cpp" "5" +"processexception.cpp" "5" +"processstartedevent.cpp" "5" +"projectpartcontainer.cpp" "5" +"projectpartcontainerv2.cpp" "5" +"projectpartpch.cpp" "5" +"projectpartsremovedmessage.cpp" "5" +"projectpartsupdatedmessage.cpp" "5" +"readmessageblock.cpp" "5" +"refactoringclientinterface.cpp" "5" +"refactoringclientproxy.cpp" "5" +"refactoringserverinterface.cpp" "5" +"refactoringserverproxy.cpp" "5" +"referencesmessage.cpp" "5" +"removeprojectpartsmessage.cpp" "5" +"requestannotationsmessage.cpp" "5" +"requestcompletionsmessage.cpp" "5" +"requestfollowsymbolmessage.cpp" "5" +"requestreferencesmessage.cpp" "5" +"requestsourcelocationforrenamingmessage.cpp" "5" +"requestsourcerangesanddiagnosticsforquerymessage.cpp" "5" +"requestsourcerangesforquerymessage.cpp" "5" +"requesttooltipmessage.cpp" "5" +"sourcelocationcontainer.cpp" "5" +"sourcelocationcontainerv2.cpp" "5" +"sourcelocationscontainer.cpp" "5" +"sourcelocationsforrenamingmessage.cpp" "5" +"sourcerangecontainer.cpp" "5" +"sourcerangecontainerv2.cpp" "5" +"sourcerangesanddiagnosticsforquerymessage.cpp" "5" +"sourcerangescontainer.cpp" "5" +"sourcerangesforquerymessage.cpp" "5" +"sourcerangewithtextcontainer.cpp" "5" +"tokeninfocontainer.cpp" "5" +"tooltipinfo.cpp" "5" +"tooltipmessage.cpp" "5" +"unsavedfilesremovedmessage.cpp" "5" +"unsavedfilesupdatedmessage.cpp" "5" +"updateprojectpartsmessage.cpp" "5" +"writemessageblock.cpp" "5" +"qtcreator" "3" +"qtcreator.pri" "4" +"sqlite-lib" "3" +"sqlite-lib.pri" "4" +"sqlite" "4" +"sqlite.pri" "5" +"Headers" "5" +"okapi_bm25.h" "6" +"sqlite3.h" "6" +"sqlite3ext.h" "6" +"Sources" "5" +"sqlite3.c" "6" +"Headers" "4" +"createtablesqlstatementbuilder.h" "5" +"sqlitebasestatement.h" "5" +"sqlitecolumn.h" "5" +"sqlitedatabase.h" "5" +"sqlitedatabasebackend.h" "5" +"sqliteexception.h" "5" +"sqliteglobal.h" "5" +"sqliteindex.h" "5" +"sqlitereadstatement.h" "5" +"sqlitereadwritestatement.h" "5" +"sqlitetable.h" "5" +"sqlitetransaction.h" "5" +"sqlitewritestatement.h" "5" +"sqlstatementbuilder.h" "5" +"sqlstatementbuilderexception.h" "5" +"utf8string.h" "5" +"utf8stringvector.h" "5" +"Sources" "4" +"createtablesqlstatementbuilder.cpp" "5" +"sqlitebasestatement.cpp" "5" +"sqlitecolumn.cpp" "5" +"sqlitedatabase.cpp" "5" +"sqlitedatabasebackend.cpp" "5" +"sqliteexception.cpp" "5" +"sqliteglobal.cpp" "5" +"sqlitereadstatement.cpp" "5" +"sqlitereadwritestatement.cpp" "5" +"sqlitetable.cpp" "5" +"sqlitewritestatement.cpp" "5" +"sqlstatementbuilder.cpp" "5" +"sqlstatementbuilderexception.cpp" "5" +"utf8string.cpp" "5" +"utf8stringvector.cpp" "5" +"utils-lib" "3" +"utils-lib.pri" "4" +"mimetypes" "4" +"mimetypes.pri" "5" +"Headers" "5" +"mimedatabase.h" "6" +"mimedatabase_p.h" "6" +"mimeglobpattern_p.h" "6" +"mimemagicrule_p.h" "6" +"mimemagicrulematcher_p.h" "6" +"mimeprovider_p.h" "6" +"mimetype.h" "6" +"mimetype_p.h" "6" +"mimetypeparser_p.h" "6" +"Sources" "5" +"mimedatabase.cpp" "6" +"mimeglobpattern.cpp" "6" +"mimemagicrule.cpp" "6" +"mimemagicrulematcher.cpp" "6" +"mimeprovider.cpp" "6" +"mimetype.cpp" "6" +"mimetypeparser.cpp" "6" +"Headers" "4" +"optional" "6" +"optional.hpp" "7" +"variant" "6" +"variant.hpp" "7" +"theme" "5" +"theme.h" "6" +"theme_p.h" "6" +"tooltip" "5" +"effects.h" "6" +"reuse.h" "6" +"tips.h" "6" +"tooltip.h" "6" +"algorithm.h" "5" +"annotateditemdelegate.h" "5" +"ansiescapecodehandler.h" "5" +"appmainwindow.h" "5" +"basetreeview.h" "5" +"benchmarker.h" "5" +"buildablehelperlibrary.h" "5" +"categorysortfiltermodel.h" "5" +"changeset.h" "5" +"checkablemessagebox.h" "5" +"classnamevalidatinglineedit.h" "5" +"codegeneration.h" "5" +"completinglineedit.h" "5" +"completingtextedit.h" "5" +"consoleprocess.h" "5" +"consoleprocess_p.h" "5" +"crumblepath.h" "5" +"declarationmacros.h" "5" +"detailsbutton.h" "5" +"detailswidget.h" "5" +"dropsupport.h" "5" +"elfreader.h" "5" +"elidinglabel.h" "5" +"environment.h" "5" +"environmentdialog.h" "5" +"environmentmodel.h" "5" +"execmenu.h" "5" +"executeondestruction.h" "5" +"fadingindicator.h" "5" +"faketooltip.h" "5" +"fancylineedit.h" "5" +"fancymainwindow.h" "5" +"filecrumblabel.h" "5" +"fileinprojectfinder.h" "5" +"filenamevalidatinglineedit.h" "5" +"filesearch.h" "5" +"filesystemwatcher.h" "5" +"fileutils.h" "5" +"fileutils_mac.h" "5" +"filewizardpage.h" "5" +"fixedsizeclicklabel.h" "5" +"flowlayout.h" "5" +"functiontraits.h" "5" +"fuzzymatcher.h" "5" +"guard.h" "5" +"headerviewstretcher.h" "5" +"highlightingitemdelegate.h" "5" +"historycompleter.h" "5" +"hostosinfo.h" "5" +"htmldocextractor.h" "5" +"icon.h" "5" +"itemviews.h" "5" +"json.h" "5" +"linecolumn.h" "5" +"link.h" "5" +"listutils.h" "5" +"macroexpander.h" "5" +"mapreduce.h" "5" +"navigationtreeview.h" "5" +"networkaccessmanager.h" "5" +"newclasswidget.h" "5" +"optional.h" "5" +"osspecificaspects.h" "5" +"outputformat.h" "5" +"outputformatter.h" "5" +"overridecursor.h" "5" +"parameteraction.h" "5" +"pathchooser.h" "5" +"pathlisteditor.h" "5" +"persistentsettings.h" "5" +"pointeralgorithm.h" "5" +"port.h" "5" +"portlist.h" "5" +"predicates.h" "5" +"processhandle.h" "5" +"progressindicator.h" "5" +"projectintropage.h" "5" +"proxyaction.h" "5" +"proxycredentialsdialog.h" "5" +"qtcassert.h" "5" +"qtcolorbutton.h" "5" +"QtConcurrentTools" "5" +"qtcprocess.h" "5" +"reloadpromptutils.h" "5" +"removefiledialog.h" "5" +"runextensions.h" "5" +"savedaction.h" "5" +"savefile.h" "5" +"scopedswap.h" "5" +"settingsaccessor.h" "5" +"settingsselector.h" "5" +"shellcommand.h" "5" +"shellcommandpage.h" "5" +"sizedarray.h" "5" +"smallstring.h" "5" +"smallstringfwd.h" "5" +"smallstringio.h" "5" +"smallstringiterator.h" "5" +"smallstringlayout.h" "5" +"smallstringliteral.h" "5" +"smallstringmemory.h" "5" +"smallstringvector.h" "5" +"statuslabel.h" "5" +"stringutils.h" "5" +"styledbar.h" "5" +"stylehelper.h" "5" +"synchronousprocess.h" "5" +"templateengine.h" "5" +"temporarydirectory.h" "5" +"temporaryfile.h" "5" +"textfieldcheckbox.h" "5" +"textfieldcombobox.h" "5" +"textfileformat.h" "5" +"textutils.h" "5" +"treemodel.h" "5" +"treeviewcombobox.h" "5" +"uncommentselection.h" "5" +"unixutils.h" "5" +"url.h" "5" +"utils_global.h" "5" +"utilsicons.h" "5" +"variant.h" "5" +"winutils.h" "5" +"wizard.h" "5" +"wizardpage.h" "5" +"Sources" "4" +"theme" "5" +"theme.cpp" "6" +"tooltip" "5" +"tips.cpp" "6" +"tooltip.cpp" "6" +"annotateditemdelegate.cpp" "5" +"ansiescapecodehandler.cpp" "5" +"appmainwindow.cpp" "5" +"basetreeview.cpp" "5" +"benchmarker.cpp" "5" +"buildablehelperlibrary.cpp" "5" +"categorysortfiltermodel.cpp" "5" +"changeset.cpp" "5" +"checkablemessagebox.cpp" "5" +"classnamevalidatinglineedit.cpp" "5" +"codegeneration.cpp" "5" +"completinglineedit.cpp" "5" +"completingtextedit.cpp" "5" +"consoleprocess.cpp" "5" +"consoleprocess_unix.cpp" "5" +"consoleprocess_win.cpp" "5" +"crumblepath.cpp" "5" +"detailsbutton.cpp" "5" +"detailswidget.cpp" "5" +"dropsupport.cpp" "5" +"elfreader.cpp" "5" +"elidinglabel.cpp" "5" +"environment.cpp" "5" +"environmentdialog.cpp" "5" +"environmentmodel.cpp" "5" +"execmenu.cpp" "5" +"fadingindicator.cpp" "5" +"faketooltip.cpp" "5" +"fancylineedit.cpp" "5" +"fancymainwindow.cpp" "5" +"filecrumblabel.cpp" "5" +"fileinprojectfinder.cpp" "5" +"filenamevalidatinglineedit.cpp" "5" +"filesearch.cpp" "5" +"filesystemwatcher.cpp" "5" +"fileutils.cpp" "5" +"filewizardpage.cpp" "5" +"fixedsizeclicklabel.cpp" "5" +"flowlayout.cpp" "5" +"fuzzymatcher.cpp" "5" +"guard.cpp" "5" +"headerviewstretcher.cpp" "5" +"highlightingitemdelegate.cpp" "5" +"historycompleter.cpp" "5" +"hostosinfo.cpp" "5" +"htmldocextractor.cpp" "5" +"icon.cpp" "5" +"itemviews.cpp" "5" +"json.cpp" "5" +"macroexpander.cpp" "5" +"navigationtreeview.cpp" "5" +"networkaccessmanager.cpp" "5" +"newclasswidget.cpp" "5" +"outputformatter.cpp" "5" +"overridecursor.cpp" "5" +"parameteraction.cpp" "5" +"pathchooser.cpp" "5" +"pathlisteditor.cpp" "5" +"persistentsettings.cpp" "5" +"port.cpp" "5" +"portlist.cpp" "5" +"processhandle.cpp" "5" +"progressindicator.cpp" "5" +"projectintropage.cpp" "5" +"proxyaction.cpp" "5" +"proxycredentialsdialog.cpp" "5" +"qtcassert.cpp" "5" +"qtcolorbutton.cpp" "5" +"qtcprocess.cpp" "5" +"reloadpromptutils.cpp" "5" +"removefiledialog.cpp" "5" +"runextensions.cpp" "5" +"savedaction.cpp" "5" +"savefile.cpp" "5" +"settingsaccessor.cpp" "5" +"settingsselector.cpp" "5" +"shellcommand.cpp" "5" +"shellcommandpage.cpp" "5" +"statuslabel.cpp" "5" +"stringutils.cpp" "5" +"styledbar.cpp" "5" +"stylehelper.cpp" "5" +"synchronousprocess.cpp" "5" +"templateengine.cpp" "5" +"temporarydirectory.cpp" "5" +"temporaryfile.cpp" "5" +"textfieldcheckbox.cpp" "5" +"textfieldcombobox.cpp" "5" +"textfileformat.cpp" "5" +"textutils.cpp" "5" +"treemodel.cpp" "5" +"treeviewcombobox.cpp" "5" +"uncommentselection.cpp" "5" +"unixutils.cpp" "5" +"url.cpp" "5" +"utilsicons.cpp" "5" +"winutils.cpp" "5" +"wizard.cpp" "5" +"wizardpage.cpp" "5" +"Forms" "4" +"filewizardpage.ui" "5" +"newclasswidget.ui" "5" +"projectintropage.ui" "5" +"proxycredentialsdialog.ui" "5" +"removefiledialog.ui" "5" +"Resources" "4" +"utils.qrc" "5" +"/utils" "6" +"images" "7" +"app-on-top.png" "8" +"app-on-top@2x.png" "8" +"arrow.png" "8" +"arrowdown.png" "8" +"arrowdown@2x.png" "8" +"arrowup.png" "8" +"arrowup@2x.png" "8" +"bookmark.png" "8" +"bookmark@2x.png" "8" +"boundingrect.png" "8" +"boundingrect@2x.png" "8" +"broken.png" "8" +"broken@2x.png" "8" +"clean_pane_small.png" "8" +"clean_pane_small@2x.png" "8" +"close.png" "8" +"close@2x.png" "8" +"codemodelerror.png" "8" +"codemodelerror@2x.png" "8" +"codemodelwarning.png" "8" +"codemodelwarning@2x.png" "8" +"collapse.png" "8" +"collapse@2x.png" "8" +"compile_error_taskbar.png" "8" +"compile_error_taskbar@2x.png" "8" +"crumblepath-segment-first-hover.png" "8" +"crumblepath-segment-first-hover@2x.png" "8" +"crumblepath-segment-first.png" "8" +"crumblepath-segment-first@2x.png" "8" +"crumblepath-segment-last-hover.png" "8" +"crumblepath-segment-last-hover@2x.png" "8" +"crumblepath-segment-last.png" "8" +"crumblepath-segment-last@2x.png" "8" +"crumblepath-segment-middle-hover.png" "8" +"crumblepath-segment-middle-hover@2x.png" "8" +"crumblepath-segment-middle.png" "8" +"crumblepath-segment-middle@2x.png" "8" +"crumblepath-segment-single-hover.png" "8" +"crumblepath-segment-single-hover@2x.png" "8" +"crumblepath-segment-single.png" "8" +"crumblepath-segment-single@2x.png" "8" +"dark_fileicon.png" "8" +"dark_foldericon.png" "8" +"Desktop.png" "8" +"desktopdevicesmall.png" "8" +"desktopdevicesmall@2x.png" "8" +"editclear.png" "8" +"editclear@2x.png" "8" +"editcopy.png" "8" +"editcopy@2x.png" "8" +"editcut.png" "8" +"editcut@2x.png" "8" +"editpaste.png" "8" +"editpaste@2x.png" "8" +"empty14.png" "8" +"empty16.png" "8" +"error.png" "8" +"error@2x.png" "8" +"expand.png" "8" +"expand@2x.png" "8" +"extension.png" "8" +"extension@2x.png" "8" +"eye_closed.png" "8" +"eye_closed@2x.png" "8" +"eye_open.png" "8" +"eye_open@2x.png" "8" +"fileexport.png" "8" +"fileexport@2x.png" "8" +"filemultiexport.png" "8" +"filemultiexport@2x.png" "8" +"filenew.png" "8" +"filenew@2x.png" "8" +"fileopen.png" "8" +"fileopen@2x.png" "8" +"filesave.png" "8" +"filesave@2x.png" "8" +"filledcircle.png" "8" +"filledcircle@2x.png" "8" +"filtericon.png" "8" +"filtericon@2x.png" "8" +"fittoview.png" "8" +"fittoview@2x.png" "8" +"home.png" "8" +"home@2x.png" "8" +"iconoverlay_add.png" "8" +"iconoverlay_add@2x.png" "8" +"iconoverlay_add_background.png" "8" +"iconoverlay_add_background@2x.png" "8" +"iconoverlay_add_small.png" "8" +"iconoverlay_add_small@2x.png" "8" +"iconoverlay_error.png" "8" +"iconoverlay_error@2x.png" "8" +"iconoverlay_error_background.png" "8" +"iconoverlay_error_background@2x.png" "8" +"iconoverlay_reset.png" "8" +"iconoverlay_reset@2x.png" "8" +"iconoverlay_warning.png" "8" +"iconoverlay_warning@2x.png" "8" +"iconoverlay_warning_background.png" "8" +"iconoverlay_warning_background@2x.png" "8" +"info.png" "8" +"info@2x.png" "8" +"inputfield.png" "8" +"inputfield@2x.png" "8" +"inputfield_disabled.png" "8" +"inputfield_disabled@2x.png" "8" +"interrupt_small.png" "8" +"interrupt_small@2x.png" "8" +"leftsidebaricon.png" "8" +"leftsidebaricon@2x.png" "8" +"lightbulb.png" "8" +"lightbulb@2x.png" "8" +"lightbulbcap.png" "8" +"lightbulbcap@2x.png" "8" +"linkicon.png" "8" +"linkicon@2x.png" "8" +"locked.png" "8" +"locked@2x.png" "8" +"magnifier.png" "8" +"magnifier@2x.png" "8" +"minus.png" "8" +"minus@2x.png" "8" +"namespace.png" "8" +"namespace@2x.png" "8" +"next.png" "8" +"next@2x.png" "8" +"notloaded.png" "8" +"notloaded@2x.png" "8" +"ok.png" "8" +"ok@2x.png" "8" +"pan.png" "8" +"pan@2x.png" "8" +"panel_button.png" "8" +"panel_button@2x.png" "8" +"panel_button_checked.png" "8" +"panel_button_checked@2x.png" "8" +"panel_button_checked_hover.png" "8" +"panel_button_checked_hover@2x.png" "8" +"panel_button_hover.png" "8" +"panel_button_hover@2x.png" "8" +"panel_button_pressed.png" "8" +"panel_button_pressed@2x.png" "8" +"panel_manage_button.png" "8" +"panel_manage_button@2x.png" "8" +"plus.png" "8" +"plus@2x.png" "8" +"prev.png" "8" +"prev@2x.png" "8" +"progressbar.png" "8" +"progressbar@2x.png" "8" +"progressindicator_big.png" "8" +"progressindicator_big@2x.png" "8" +"progressindicator_medium.png" "8" +"progressindicator_medium@2x.png" "8" +"progressindicator_small.png" "8" +"progressindicator_small@2x.png" "8" +"project.png" "8" +"project@2x.png" "8" +"redo.png" "8" +"redo@2x.png" "8" +"reload_gray.png" "8" +"reload_gray@2x.png" "8" +"replace_a.png" "8" +"replace_a@2x.png" "8" +"replace_b.png" "8" +"replace_b@2x.png" "8" +"reset.png" "8" +"reset@2x.png" "8" +"rightsidebaricon.png" "8" +"rightsidebaricon@2x.png" "8" +"run_small.png" "8" +"run_small@2x.png" "8" +"select.png" "8" +"select@2x.png" "8" +"snapshot.png" "8" +"snapshot@2x.png" "8" +"splitbutton_closebottom.png" "8" +"splitbutton_closebottom@2x.png" "8" +"splitbutton_closeleft.png" "8" +"splitbutton_closeleft@2x.png" "8" +"splitbutton_closeright.png" "8" +"splitbutton_closeright@2x.png" "8" +"splitbutton_closetop.png" "8" +"splitbutton_closetop@2x.png" "8" +"splitbutton_horizontal.png" "8" +"splitbutton_horizontal@2x.png" "8" +"splitbutton_vertical.png" "8" +"splitbutton_vertical@2x.png" "8" +"stop_small.png" "8" +"stop_small@2x.png" "8" +"toolbuttonexpandarrow.png" "8" +"toolbuttonexpandarrow@2x.png" "8" +"undo.png" "8" +"undo@2x.png" "8" +"unlocked.png" "8" +"unlocked@2x.png" "8" +"warning.png" "8" +"warning@2x.png" "8" +"warningfill.png" "8" +"warningfill@2x.png" "8" +"wizardicon-file.png" "8" +"wizardicon-file@2x.png" "8" +"zoom.png" "8" +"zoom@2x.png" "8" +"zoomin_overlay.png" "8" +"zoomin_overlay@2x.png" "8" +"zoomout_overlay.png" "8" +"zoomout_overlay@2x.png" "8" +"tooltip" "7" +"images" "8" +"f1.png" "9" +"Headers" "3" +"echoclangcodemodelserver.h" "4" +"Sources" "3" +"echoclangcodemodelserver.cpp" "4" +"echoserverprocessmain.cpp" "4" +"unittest" "2" +"unittest.pro" "3" +"benchmark_dependency" "3" +"benchmark_dependency.pri" "4" +"clang_dependency" "3" +"clang_dependency.pri" "4" +"clang_installation" "4" +"clang_installation.pri" "5" +"creator_dependency" "3" +"creator_dependency.pri" "4" +"clang_defines" "4" +"clang_defines.pri" "5" +"clangbackendclangipc-source" "4" +"clangbackendclangipc-source.pri" "5" +"Headers" "5" +"clangasyncjob.h" "6" +"clangbackend_global.h" "6" +"clangclock.h" "6" +"clangcodecompleteresults.h" "6" +"clangcodemodelserver.h" "6" +"clangcompletecodejob.h" "6" +"clangdocument.h" "6" +"clangdocumentjob.h" "6" +"clangdocumentprocessor.h" "6" +"clangdocumentprocessors.h" "6" +"clangdocuments.h" "6" +"clangdocumentsuspenderresumer.h" "6" +"clangexceptions.h" "6" +"clangfilepath.h" "6" +"clangfilesystemwatcher.h" "6" +"clangfollowsymbol.h" "6" +"clangfollowsymboljob.h" "6" +"clangiasyncjob.h" "6" +"clangjobcontext.h" "6" +"clangjobqueue.h" "6" +"clangjobrequest.h" "6" +"clangjobs.h" "6" +"clangparsesupportivetranslationunitjob.h" "6" +"clangreferencescollector.h" "6" +"clangrequestannotationsjob.h" "6" +"clangrequestreferencesjob.h" "6" +"clangrequesttooltipjob.h" "6" +"clangresumedocumentjob.h" "6" +"clangstring.h" "6" +"clangsupportivetranslationunitinitializer.h" "6" +"clangsuspenddocumentjob.h" "6" +"clangtooltipinfocollector.h" "6" +"clangtranslationunit.h" "6" +"clangtranslationunits.h" "6" +"clangtranslationunitupdater.h" "6" +"clangtype.h" "6" +"clangunsavedfilesshallowarguments.h" "6" +"clangupdateannotationsjob.h" "6" +"clangupdateextraannotationsjob.h" "6" +"codecompleter.h" "6" +"codecompletionchunkconverter.h" "6" +"codecompletionsextractor.h" "6" +"commandlinearguments.h" "6" +"cursor.h" "6" +"diagnostic.h" "6" +"diagnosticset.h" "6" +"diagnosticsetiterator.h" "6" +"fixit.h" "6" +"fulltokeninfo.h" "6" +"projectpart.h" "6" +"projects.h" "6" +"skippedsourceranges.h" "6" +"sourcelocation.h" "6" +"sourcerange.h" "6" +"tokeninfo.h" "6" +"tokenprocessor.h" "6" +"tokenprocessoriterator.h" "6" +"unsavedfile.h" "6" +"unsavedfiles.h" "6" +"utf8positionfromlinecolumn.h" "6" +"Sources" "5" +"clangcodecompleteresults.cpp" "6" +"clangcodemodelserver.cpp" "6" +"clangcompletecodejob.cpp" "6" +"clangdocument.cpp" "6" +"clangdocumentprocessor.cpp" "6" +"clangdocumentprocessors.cpp" "6" +"clangdocuments.cpp" "6" +"clangdocumentsuspenderresumer.cpp" "6" +"clangexceptions.cpp" "6" +"clangfilepath.cpp" "6" +"clangfilesystemwatcher.cpp" "6" +"clangfollowsymbol.cpp" "6" +"clangfollowsymboljob.cpp" "6" +"clangiasyncjob.cpp" "6" +"clangjobcontext.cpp" "6" +"clangjobqueue.cpp" "6" +"clangjobrequest.cpp" "6" +"clangjobs.cpp" "6" +"clangparsesupportivetranslationunitjob.cpp" "6" +"clangreferencescollector.cpp" "6" +"clangrequestannotationsjob.cpp" "6" +"clangrequestreferencesjob.cpp" "6" +"clangrequesttooltipjob.cpp" "6" +"clangresumedocumentjob.cpp" "6" +"clangsupportivetranslationunitinitializer.cpp" "6" +"clangsuspenddocumentjob.cpp" "6" +"clangtooltipinfocollector.cpp" "6" +"clangtranslationunit.cpp" "6" +"clangtranslationunits.cpp" "6" +"clangtranslationunitupdater.cpp" "6" +"clangtype.cpp" "6" +"clangunsavedfilesshallowarguments.cpp" "6" +"clangupdateannotationsjob.cpp" "6" +"clangupdateextraannotationsjob.cpp" "6" +"codecompleter.cpp" "6" +"codecompletionchunkconverter.cpp" "6" +"codecompletionsextractor.cpp" "6" +"commandlinearguments.cpp" "6" +"cursor.cpp" "6" +"diagnostic.cpp" "6" +"diagnosticset.cpp" "6" +"fixit.cpp" "6" +"fulltokeninfo.cpp" "6" +"projectpart.cpp" "6" +"projects.cpp" "6" +"skippedsourceranges.cpp" "6" +"sourcelocation.cpp" "6" +"sourcerange.cpp" "6" +"tokeninfo.cpp" "6" +"unsavedfile.cpp" "6" +"unsavedfiles.cpp" "6" +"utf8positionfromlinecolumn.cpp" "6" +"clangcodemodelunittestfiles" "4" +"clangcodemodelunittestfiles.pri" "5" +"Headers" "5" +"clangactivationsequencecontextprocessor.h" "6" +"clangactivationsequenceprocessor.h" "6" +"clangcompletionchunkstotextconverter.h" "6" +"clangcompletioncontextanalyzer.h" "6" +"clangdiagnosticfilter.h" "6" +"clangfixitoperation.h" "6" +"clanghighlightingresultreporter.h" "6" +"clangisdiagnosticrelatedtolocation.h" "6" +"Sources" "5" +"clangactivationsequencecontextprocessor.cpp" "6" +"clangactivationsequenceprocessor.cpp" "6" +"clangcompletionchunkstotextconverter.cpp" "6" +"clangcompletioncontextanalyzer.cpp" "6" +"clangdiagnosticfilter.cpp" "6" +"clangfixitoperation.cpp" "6" +"clanghighlightingresultreporter.cpp" "6" +"clangpchmanager-source" "4" +"clangpchmanager-source.pri" "5" +"Headers" "5" +"clangpchmanager_global.h" "6" +"pchmanagerclient.h" "6" +"pchmanagerconnectionclient.h" "6" +"pchmanagernotifierinterface.h" "6" +"pchmanagerprojectupdater.h" "6" +"precompiledheaderstorage.h" "6" +"precompiledheaderstorageinterface.h" "6" +"projectupdater.h" "6" +"Sources" "5" +"pchmanagerclient.cpp" "6" +"pchmanagerconnectionclient.cpp" "6" +"pchmanagernotifierinterface.cpp" "6" +"pchmanagerprojectupdater.cpp" "6" +"projectupdater.cpp" "6" +"clangpchmanagerbackend-source" "4" +"clangpchmanagerbackend-source.pri" "5" +"Headers" "5" +"clangpchmanagerbackend_global.h" "6" +"collectincludesaction.h" "6" +"collectincludespreprocessorcallbacks.h" "6" +"collectincludestoolaction.h" "6" +"environment.h" "6" +"includecollector.h" "6" +"pchcreator.h" "6" +"pchcreatorinterface.h" "6" +"pchgenerator.h" "6" +"pchgeneratorinterface.h" "6" +"pchgeneratornotifierinterface.h" "6" +"pchmanagerserver.h" "6" +"pchnotcreatederror.h" "6" +"projectparts.h" "6" +"projectpartsinterface.h" "6" +"Sources" "5" +"includecollector.cpp" "6" +"pchcreator.cpp" "6" +"pchmanagerserver.cpp" "6" +"projectparts.cpp" "6" +"clangrefactoring-source" "4" +"clangrefactoring-source.pri" "5" +"Headers" "5" +"clangqueryexamplehighlighter.h" "6" +"clangqueryexamplehighlightmarker.h" "6" +"clangqueryhighlighter.h" "6" +"clangqueryhighlightmarker.h" "6" +"clangqueryprojectsfindfilter.h" "6" +"editormanagerinterface.h" "6" +"locatorfilter.h" "6" +"projectpartproviderinterface.h" "6" +"projectpartutilities.h" "6" +"refactoringclient.h" "6" +"refactoringconnectionclient.h" "6" +"refactoringengine.h" "6" +"refactoringprojectupdater.h" "6" +"searchhandle.h" "6" +"searchinterface.h" "6" +"symbol.h" "6" +"symbolqueryinterface.h" "6" +"symbolsfindfilter.h" "6" +"Sources" "5" +"clangqueryexamplehighlighter.cpp" "6" +"clangqueryhighlighter.cpp" "6" +"clangqueryprojectsfindfilter.cpp" "6" +"locatorfilter.cpp" "6" +"projectpartutilities.cpp" "6" +"refactoringclient.cpp" "6" +"refactoringconnectionclient.cpp" "6" +"refactoringengine.cpp" "6" +"refactoringprojectupdater.cpp" "6" +"searchhandle.cpp" "6" +"symbolsfindfilter.cpp" "6" +"clangrefactoringbackend-source" "4" +"clangrefactoringbackend-source.pri" "5" +"Headers" "5" +"clangquery.h" "6" +"clangquerygatherer.h" "6" +"clangrefactoringbackend_global.h" "6" +"clangtool.h" "6" +"collectmacrospreprocessorcallbacks.h" "6" +"collectmacrossourcefilecallbacks.h" "6" +"collectsymbolsaction.h" "6" +"filestatus.h" "6" +"filestatuscache.h" "6" +"findcursorusr.h" "6" +"findlocationsofusrs.h" "6" +"findusrforcursoraction.h" "6" +"indexdataconsumer.h" "6" +"locationsourcefilecallbacks.h" "6" +"macropreprocessorcallbacks.h" "6" +"projectpartartefact.h" "6" +"projectpartartefactexception.h" "6" +"projectpartentry.h" "6" +"refactoringcompilationdatabase.h" "6" +"refactoringserver.h" "6" +"sourcedependency.h" "6" +"sourcelocationentry.h" "6" +"sourcelocationsutils.h" "6" +"sourcerangeextractor.h" "6" +"sourcerangefilter.h" "6" +"storagesqlitestatementfactory.h" "6" +"symbolentry.h" "6" +"symbolfinder.h" "6" +"symbolindexer.h" "6" +"symbolindexing.h" "6" +"symbolindexinginterface.h" "6" +"symbollocationfinderaction.h" "6" +"symbolscollector.h" "6" +"symbolscollectorinterface.h" "6" +"symbolstorage.h" "6" +"symbolstorageinterface.h" "6" +"symbolsvisitorbase.h" "6" +"usedmacro.h" "6" +"Sources" "5" +"clangquery.cpp" "6" +"clangquerygatherer.cpp" "6" +"clangtool.cpp" "6" +"collectmacrossourcefilecallbacks.cpp" "6" +"collectsymbolsaction.cpp" "6" +"filestatuscache.cpp" "6" +"findusrforcursoraction.cpp" "6" +"indexdataconsumer.cpp" "6" +"locationsourcefilecallbacks.cpp" "6" +"macropreprocessorcallbacks.cpp" "6" +"projectpartartefact.cpp" "6" +"refactoringcompilationdatabase.cpp" "6" +"refactoringserver.cpp" "6" +"sourcerangeextractor.cpp" "6" +"sourcerangefilter.cpp" "6" +"symbolfinder.cpp" "6" +"symbolindexer.cpp" "6" +"symbolindexing.cpp" "6" +"symbollocationfinderaction.cpp" "6" +"symbolscollector.cpp" "6" +"clangsupport-lib" "4" +"clangsupport-lib.pri" "5" +"Headers" "5" +"alivemessage.h" "6" +"annotationsmessage.h" "6" +"baseserverproxy.h" "6" +"cancelmessage.h" "6" +"clangcodemodelclientinterface.h" "6" +"clangcodemodelclientmessages.h" "6" +"clangcodemodelclientproxy.h" "6" +"clangcodemodelconnectionclient.h" "6" +"clangcodemodelserverinterface.h" "6" +"clangcodemodelservermessages.h" "6" +"clangcodemodelserverproxy.h" "6" +"clangpathwatcher.h" "6" +"clangpathwatcherinterface.h" "6" +"clangpathwatchernotifier.h" "6" +"clangrefactoringclientmessages.h" "6" +"clangrefactoringmessages.h" "6" +"clangrefactoringservermessages.h" "6" +"clangsupport_global.h" "6" +"clangsupportdebugutils.h" "6" +"codecompletion.h" "6" +"codecompletionchunk.h" "6" +"compilermacro.h" "6" +"completionsmessage.h" "6" +"connectionclient.h" "6" +"connectionserver.h" "6" +"diagnosticcontainer.h" "6" +"documentschangedmessage.h" "6" +"documentsclosedmessage.h" "6" +"documentsopenedmessage.h" "6" +"documentvisibilitychangedmessage.h" "6" +"dynamicastmatcherdiagnosticcontainer.h" "6" +"dynamicastmatcherdiagnosticcontextcontainer.h" "6" +"dynamicastmatcherdiagnosticmessagecontainer.h" "6" +"dynamicmatcherdiagnostics.h" "6" +"echomessage.h" "6" +"endmessage.h" "6" +"filecontainer.h" "6" +"filecontainerv2.h" "6" +"filepath.h" "6" +"filepathcache.h" "6" +"filepathcaching.h" "6" +"filepathcachingfwd.h" "6" +"filepathcachinginterface.h" "6" +"filepathexceptions.h" "6" +"filepathid.h" "6" +"filepathstorage.h" "6" +"filepathstoragesources.h" "6" +"filepathstoragesqlitestatementfactory.h" "6" +"filepathview.h" "6" +"fixitcontainer.h" "6" +"followsymbolmessage.h" "6" +"idpaths.h" "6" +"ipcclientinterface.h" "6" +"ipcclientprovider.h" "6" +"ipcinterface.h" "6" +"ipcserverinterface.h" "6" +"lineprefixer.h" "6" +"messageenvelop.h" "6" +"nativefilepath.h" "6" +"pchmanagerclientinterface.h" "6" +"pchmanagerclientproxy.h" "6" +"pchmanagerserverinterface.h" "6" +"pchmanagerserverproxy.h" "6" +"precompiledheadersupdatedmessage.h" "6" +"processcreator.h" "6" +"processexception.h" "6" +"processhandle.h" "6" +"processstartedevent.h" "6" +"projectmanagementserverinterface.h" "6" +"projectpartcontainer.h" "6" +"projectpartcontainerv2.h" "6" +"projectpartpch.h" "6" +"projectpartpchproviderinterface.h" "6" +"projectpartsremovedmessage.h" "6" +"projectpartsupdatedmessage.h" "6" +"readmessageblock.h" "6" +"refactoringclientinterface.h" "6" +"refactoringclientproxy.h" "6" +"refactoringdatabaseinitializer.h" "6" +"refactoringserverinterface.h" "6" +"refactoringserverproxy.h" "6" +"referencesmessage.h" "6" +"removeprojectpartsmessage.h" "6" +"requestannotationsmessage.h" "6" +"requestcompletionsmessage.h" "6" +"requestfollowsymbolmessage.h" "6" +"requestreferencesmessage.h" "6" +"requestsourcelocationforrenamingmessage.h" "6" +"requestsourcerangesanddiagnosticsforquerymessage.h" "6" +"requestsourcerangesforquerymessage.h" "6" +"requesttooltipmessage.h" "6" +"sourcelocationcontainer.h" "6" +"sourcelocationcontainerv2.h" "6" +"sourcelocationscontainer.h" "6" +"sourcelocationsforrenamingmessage.h" "6" +"sourcerangecontainer.h" "6" +"sourcerangecontainerv2.h" "6" +"sourcerangesanddiagnosticsforquerymessage.h" "6" +"sourcerangescontainer.h" "6" +"sourcerangesforquerymessage.h" "6" +"sourcerangewithtextcontainer.h" "6" +"stringcache.h" "6" +"stringcachealgorithms.h" "6" +"stringcachefwd.h" "6" +"tokeninfocontainer.h" "6" +"tooltipinfo.h" "6" +"tooltipmessage.h" "6" +"unsavedfilesremovedmessage.h" "6" +"unsavedfilesupdatedmessage.h" "6" +"updateprojectpartsmessage.h" "6" +"writemessageblock.h" "6" +"Sources" "5" +"alivemessage.cpp" "6" +"annotationsmessage.cpp" "6" +"baseserverproxy.cpp" "6" +"cancelmessage.cpp" "6" +"clangcodemodelclientinterface.cpp" "6" +"clangcodemodelclientproxy.cpp" "6" +"clangcodemodelconnectionclient.cpp" "6" +"clangcodemodelserverinterface.cpp" "6" +"clangcodemodelserverproxy.cpp" "6" +"clangsupportdebugutils.cpp" "6" +"codecompletion.cpp" "6" +"codecompletionchunk.cpp" "6" +"completionsmessage.cpp" "6" +"connectionclient.cpp" "6" +"connectionserver.cpp" "6" +"diagnosticcontainer.cpp" "6" +"documentschangedmessage.cpp" "6" +"documentsclosedmessage.cpp" "6" +"documentsopenedmessage.cpp" "6" +"documentvisibilitychangedmessage.cpp" "6" +"dynamicastmatcherdiagnosticcontainer.cpp" "6" +"dynamicastmatcherdiagnosticcontextcontainer.cpp" "6" +"dynamicastmatcherdiagnosticmessagecontainer.cpp" "6" +"echomessage.cpp" "6" +"endmessage.cpp" "6" +"filecontainer.cpp" "6" +"filecontainerv2.cpp" "6" +"filepath.cpp" "6" +"filepathcaching.cpp" "6" +"filepathid.cpp" "6" +"fixitcontainer.cpp" "6" +"followsymbolmessage.cpp" "6" +"lineprefixer.cpp" "6" +"messageenvelop.cpp" "6" +"pchmanagerclientinterface.cpp" "6" +"pchmanagerclientproxy.cpp" "6" +"pchmanagerserverinterface.cpp" "6" +"pchmanagerserverproxy.cpp" "6" +"precompiledheadersupdatedmessage.cpp" "6" +"processcreator.cpp" "6" +"processexception.cpp" "6" +"processstartedevent.cpp" "6" +"projectpartcontainer.cpp" "6" +"projectpartcontainerv2.cpp" "6" +"projectpartpch.cpp" "6" +"projectpartsremovedmessage.cpp" "6" +"projectpartsupdatedmessage.cpp" "6" +"readmessageblock.cpp" "6" +"refactoringclientinterface.cpp" "6" +"refactoringclientproxy.cpp" "6" +"refactoringserverinterface.cpp" "6" +"refactoringserverproxy.cpp" "6" +"referencesmessage.cpp" "6" +"removeprojectpartsmessage.cpp" "6" +"requestannotationsmessage.cpp" "6" +"requestcompletionsmessage.cpp" "6" +"requestfollowsymbolmessage.cpp" "6" +"requestreferencesmessage.cpp" "6" +"requestsourcelocationforrenamingmessage.cpp" "6" +"requestsourcerangesanddiagnosticsforquerymessage.cpp" "6" +"requestsourcerangesforquerymessage.cpp" "6" +"requesttooltipmessage.cpp" "6" +"sourcelocationcontainer.cpp" "6" +"sourcelocationcontainerv2.cpp" "6" +"sourcelocationscontainer.cpp" "6" +"sourcelocationsforrenamingmessage.cpp" "6" +"sourcerangecontainer.cpp" "6" +"sourcerangecontainerv2.cpp" "6" +"sourcerangesanddiagnosticsforquerymessage.cpp" "6" +"sourcerangescontainer.cpp" "6" +"sourcerangesforquerymessage.cpp" "6" +"sourcerangewithtextcontainer.cpp" "6" +"tokeninfocontainer.cpp" "6" +"tooltipinfo.cpp" "6" +"tooltipmessage.cpp" "6" +"unsavedfilesremovedmessage.cpp" "6" +"unsavedfilesupdatedmessage.cpp" "6" +"updateprojectpartsmessage.cpp" "6" +"writemessageblock.cpp" "6" +"corepluginunittestfiles" "4" +"corepluginunittestfiles.pri" "5" +"Headers" "5" +"find" "6" +"ifindfilter.h" "7" +"locator" "6" +"ilocatorfilter.h" "7" +"coreicons.h" "6" +"id.h" "6" +"Sources" "5" +"find" "6" +"ifindfilter.cpp" "7" +"locator" "6" +"ilocatorfilter.cpp" "7" +"coreicons.cpp" "6" +"id.cpp" "6" +"cplusplus" "4" +"cplusplus.pri" "5" +"cplusplus-lib" "5" +"cplusplus-lib.pri" "6" +"cplusplus" "6" +"cplusplus.pri" "7" +"Headers" "7" +"AST.h" "8" +"ASTfwd.h" "8" +"ASTMatcher.h" "8" +"ASTPatternBuilder.h" "8" +"ASTVisitor.h" "8" +"Bind.h" "8" +"Control.h" "8" +"CoreTypes.h" "8" +"CPlusPlus.h" "8" +"CPlusPlusForwardDeclarations.h" "8" +"cppassert.h" "8" +"DiagnosticClient.h" "8" +"FullySpecifiedType.h" "8" +"Lexer.h" "8" +"Literals.h" "8" +"LiteralTable.h" "8" +"Matcher.h" "8" +"MemoryPool.h" "8" +"Name.h" "8" +"Names.h" "8" +"NameVisitor.h" "8" +"ObjectiveCTypeQualifiers.h" "8" +"Parser.h" "8" +"QtContextKeywords.h" "8" +"SafeMatcher.h" "8" +"Scope.h" "8" +"Symbol.h" "8" +"Symbols.h" "8" +"SymbolVisitor.h" "8" +"Templates.h" "8" +"Token.h" "8" +"TranslationUnit.h" "8" +"Type.h" "8" +"TypeVisitor.h" "8" +"Sources" "7" +"AST.cpp" "8" +"ASTClone.cpp" "8" +"ASTMatch0.cpp" "8" +"ASTMatcher.cpp" "8" +"ASTVisit.cpp" "8" +"ASTVisitor.cpp" "8" +"Bind.cpp" "8" +"Control.cpp" "8" +"CoreTypes.cpp" "8" +"DiagnosticClient.cpp" "8" +"FullySpecifiedType.cpp" "8" +"Keywords.cpp" "8" +"Lexer.cpp" "8" +"Literals.cpp" "8" +"Matcher.cpp" "8" +"MemoryPool.cpp" "8" +"Name.cpp" "8" +"Names.cpp" "8" +"NameVisitor.cpp" "8" +"ObjectiveCAtKeywords.cpp" "8" +"ObjectiveCTypeQualifiers.cpp" "8" +"Parser.cpp" "8" +"QtContextKeywords.cpp" "8" +"SafeMatcher.cpp" "8" +"Scope.cpp" "8" +"Symbol.cpp" "8" +"Symbols.cpp" "8" +"Templates.cpp" "8" +"Token.cpp" "8" +"TranslationUnit.cpp" "8" +"Type.cpp" "8" +"TypeVisitor.cpp" "8" +"Headers" "6" +"AlreadyConsideredClassContainer.h" "7" +"ASTParent.h" "7" +"ASTPath.h" "7" +"BackwardsScanner.h" "7" +"CppDocument.h" "7" +"cppmodelmanagerbase.h" "7" +"CppRewriter.h" "7" +"DependencyTable.h" "7" +"DeprecatedGenTemplateInstance.h" "7" +"ExpressionUnderCursor.h" "7" +"FastPreprocessor.h" "7" +"findcdbbreakpoint.h" "7" +"FindUsages.h" "7" +"Icons.h" "7" +"LookupContext.h" "7" +"LookupItem.h" "7" +"Macro.h" "7" +"MatchingText.h" "7" +"NamePrettyPrinter.h" "7" +"Overview.h" "7" +"pp-cctype.h" "7" +"pp-engine.h" "7" +"pp-scanner.h" "7" +"pp.h" "7" +"PPToken.h" "7" +"PreprocessorClient.h" "7" +"PreprocessorEnvironment.h" "7" +"ResolveExpression.h" "7" +"SimpleLexer.h" "7" +"SnapshotSymbolVisitor.h" "7" +"SymbolNameVisitor.h" "7" +"TypeOfExpression.h" "7" +"TypePrettyPrinter.h" "7" +"Sources" "6" +"ASTParent.cpp" "7" +"ASTPath.cpp" "7" +"BackwardsScanner.cpp" "7" +"CppDocument.cpp" "7" +"cppmodelmanagerbase.cpp" "7" +"CppRewriter.cpp" "7" +"DependencyTable.cpp" "7" +"DeprecatedGenTemplateInstance.cpp" "7" +"ExpressionUnderCursor.cpp" "7" +"FastPreprocessor.cpp" "7" +"findcdbbreakpoint.cpp" "7" +"FindUsages.cpp" "7" +"Icons.cpp" "7" +"LookupContext.cpp" "7" +"LookupItem.cpp" "7" +"Macro.cpp" "7" +"MatchingText.cpp" "7" +"NamePrettyPrinter.cpp" "7" +"Overview.cpp" "7" +"pp-engine.cpp" "7" +"pp-scanner.cpp" "7" +"PPToken.cpp" "7" +"PreprocessorClient.cpp" "7" +"PreprocessorEnvironment.cpp" "7" +"ResolveExpression.cpp" "7" +"SimpleLexer.cpp" "7" +"SnapshotSymbolVisitor.cpp" "7" +"SymbolNameVisitor.cpp" "7" +"TypeOfExpression.cpp" "7" +"TypePrettyPrinter.cpp" "7" +"Resources" "6" +"cplusplus.qrc" "7" +"/codemodel" "8" +"images" "9" +"classmemberfunction.png" "10" +"classmemberfunction@2x.png" "10" +"classmembervariable.png" "10" +"classmembervariable@2x.png" "10" +"classparent.png" "10" +"classparent@2x.png" "10" +"classrelation.png" "10" +"classrelation@2x.png" "10" +"classrelationbackground.png" "10" +"classrelationbackground@2x.png" "10" +"enum.png" "10" +"enum@2x.png" "10" +"enumerator.png" "10" +"enumerator@2x.png" "10" +"keyword.png" "10" +"keyword@2x.png" "10" +"macro.png" "10" +"macro@2x.png" "10" +"member.png" "10" +"member@2x.png" "10" +"private.png" "10" +"private@2x.png" "10" +"privatebackground.png" "10" +"privatebackground@2x.png" "10" +"property.png" "10" +"property@2x.png" "10" +"propertybackground.png" "10" +"propertybackground@2x.png" "10" +"protected.png" "10" +"protected@2x.png" "10" +"protectedbackground.png" "10" +"protectedbackground@2x.png" "10" +"signal.png" "10" +"signal@2x.png" "10" +"slot.png" "10" +"slot@2x.png" "10" +"static.png" "10" +"static@2x.png" "10" +"staticbackground.png" "10" +"staticbackground@2x.png" "10" +"cpptoolsunittestfiles" "4" +"cpptoolsunittestfiles.pri" "5" +"Headers" "5" +"compileroptionsbuilder.h" "6" +"cppprojectfile.h" "6" +"cppprojectfilecategorizer.h" "6" +"cppprojectinfogenerator.cpp" "6" +"cppprojectpartchooser.h" "6" +"projectinfo.h" "6" +"projectpart.h" "6" +"senddocumenttracker.h" "6" +"Sources" "5" +"compileroptionsbuilder.cpp" "6" +"cppprojectfile.cpp" "6" +"cppprojectfilecategorizer.cpp" "6" +"cppprojectinfogenerator.cpp" "6" +"cppprojectpartchooser.cpp" "6" +"projectinfo.cpp" "6" +"projectpart.cpp" "6" +"senddocumenttracker.cpp" "6" +"projectexplorerunittestfiles" "4" +"projectexplorerunittestfiles.pri" "5" +"Headers" "5" +"projectmacro.h" "6" +"Sources" "5" +"projectmacro.cpp" "6" +"sqlite-lib" "4" +"sqlite-lib.pri" "5" +"sqlite" "5" +"sqlite.pri" "6" +"Headers" "6" +"okapi_bm25.h" "7" +"sqlite3.h" "7" +"sqlite3ext.h" "7" +"Sources" "6" +"sqlite3.c" "7" +"Headers" "5" +"createtablesqlstatementbuilder.h" "6" +"sqlitebasestatement.h" "6" +"sqlitecolumn.h" "6" +"sqlitedatabase.h" "6" +"sqlitedatabasebackend.h" "6" +"sqliteexception.h" "6" +"sqliteglobal.h" "6" +"sqliteindex.h" "6" +"sqlitereadstatement.h" "6" +"sqlitereadwritestatement.h" "6" +"sqlitetable.h" "6" +"sqlitetransaction.h" "6" +"sqlitewritestatement.h" "6" +"sqlstatementbuilder.h" "6" +"sqlstatementbuilderexception.h" "6" +"utf8string.h" "6" +"utf8stringvector.h" "6" +"Sources" "5" +"createtablesqlstatementbuilder.cpp" "6" +"sqlitebasestatement.cpp" "6" +"sqlitecolumn.cpp" "6" +"sqlitedatabase.cpp" "6" +"sqlitedatabasebackend.cpp" "6" +"sqliteexception.cpp" "6" +"sqliteglobal.cpp" "6" +"sqlitereadstatement.cpp" "6" +"sqlitereadwritestatement.cpp" "6" +"sqlitetable.cpp" "6" +"sqlitewritestatement.cpp" "6" +"sqlstatementbuilder.cpp" "6" +"sqlstatementbuilderexception.cpp" "6" +"utf8string.cpp" "6" +"utf8stringvector.cpp" "6" +"utils-lib" "4" +"utils-lib.pri" "5" +"mimetypes" "5" +"mimetypes.pri" "6" +"Headers" "6" +"mimedatabase.h" "7" +"mimedatabase_p.h" "7" +"mimeglobpattern_p.h" "7" +"mimemagicrule_p.h" "7" +"mimemagicrulematcher_p.h" "7" +"mimeprovider_p.h" "7" +"mimetype.h" "7" +"mimetype_p.h" "7" +"mimetypeparser_p.h" "7" +"Sources" "6" +"mimedatabase.cpp" "7" +"mimeglobpattern.cpp" "7" +"mimemagicrule.cpp" "7" +"mimemagicrulematcher.cpp" "7" +"mimeprovider.cpp" "7" +"mimetype.cpp" "7" +"mimetypeparser.cpp" "7" +"Headers" "5" +"optional" "7" +"optional.hpp" "8" +"variant" "7" +"variant.hpp" "8" +"theme" "6" +"theme.h" "7" +"theme_p.h" "7" +"tooltip" "6" +"effects.h" "7" +"reuse.h" "7" +"tips.h" "7" +"tooltip.h" "7" +"algorithm.h" "6" +"annotateditemdelegate.h" "6" +"ansiescapecodehandler.h" "6" +"appmainwindow.h" "6" +"basetreeview.h" "6" +"benchmarker.h" "6" +"buildablehelperlibrary.h" "6" +"categorysortfiltermodel.h" "6" +"changeset.h" "6" +"checkablemessagebox.h" "6" +"classnamevalidatinglineedit.h" "6" +"codegeneration.h" "6" +"completinglineedit.h" "6" +"completingtextedit.h" "6" +"consoleprocess.h" "6" +"consoleprocess_p.h" "6" +"crumblepath.h" "6" +"declarationmacros.h" "6" +"detailsbutton.h" "6" +"detailswidget.h" "6" +"dropsupport.h" "6" +"elfreader.h" "6" +"elidinglabel.h" "6" +"environment.h" "6" +"environmentdialog.h" "6" +"environmentmodel.h" "6" +"execmenu.h" "6" +"executeondestruction.h" "6" +"fadingindicator.h" "6" +"faketooltip.h" "6" +"fancylineedit.h" "6" +"fancymainwindow.h" "6" +"filecrumblabel.h" "6" +"fileinprojectfinder.h" "6" +"filenamevalidatinglineedit.h" "6" +"filesearch.h" "6" +"filesystemwatcher.h" "6" +"fileutils.h" "6" +"fileutils_mac.h" "6" +"filewizardpage.h" "6" +"fixedsizeclicklabel.h" "6" +"flowlayout.h" "6" +"functiontraits.h" "6" +"fuzzymatcher.h" "6" +"guard.h" "6" +"headerviewstretcher.h" "6" +"highlightingitemdelegate.h" "6" +"historycompleter.h" "6" +"hostosinfo.h" "6" +"htmldocextractor.h" "6" +"icon.h" "6" +"itemviews.h" "6" +"json.h" "6" +"linecolumn.h" "6" +"link.h" "6" +"listutils.h" "6" +"macroexpander.h" "6" +"mapreduce.h" "6" +"navigationtreeview.h" "6" +"networkaccessmanager.h" "6" +"newclasswidget.h" "6" +"optional.h" "6" +"osspecificaspects.h" "6" +"outputformat.h" "6" +"outputformatter.h" "6" +"overridecursor.h" "6" +"parameteraction.h" "6" +"pathchooser.h" "6" +"pathlisteditor.h" "6" +"persistentsettings.h" "6" +"pointeralgorithm.h" "6" +"port.h" "6" +"portlist.h" "6" +"predicates.h" "6" +"processhandle.h" "6" +"progressindicator.h" "6" +"projectintropage.h" "6" +"proxyaction.h" "6" +"proxycredentialsdialog.h" "6" +"qtcassert.h" "6" +"qtcolorbutton.h" "6" +"QtConcurrentTools" "6" +"qtcprocess.h" "6" +"reloadpromptutils.h" "6" +"removefiledialog.h" "6" +"runextensions.h" "6" +"savedaction.h" "6" +"savefile.h" "6" +"scopedswap.h" "6" +"settingsaccessor.h" "6" +"settingsselector.h" "6" +"shellcommand.h" "6" +"shellcommandpage.h" "6" +"sizedarray.h" "6" +"smallstring.h" "6" +"smallstringfwd.h" "6" +"smallstringio.h" "6" +"smallstringiterator.h" "6" +"smallstringlayout.h" "6" +"smallstringliteral.h" "6" +"smallstringmemory.h" "6" +"smallstringvector.h" "6" +"statuslabel.h" "6" +"stringutils.h" "6" +"styledbar.h" "6" +"stylehelper.h" "6" +"synchronousprocess.h" "6" +"templateengine.h" "6" +"temporarydirectory.h" "6" +"temporaryfile.h" "6" +"textfieldcheckbox.h" "6" +"textfieldcombobox.h" "6" +"textfileformat.h" "6" +"textutils.h" "6" +"treemodel.h" "6" +"treeviewcombobox.h" "6" +"uncommentselection.h" "6" +"unixutils.h" "6" +"url.h" "6" +"utils_global.h" "6" +"utilsicons.h" "6" +"variant.h" "6" +"winutils.h" "6" +"wizard.h" "6" +"wizardpage.h" "6" +"Sources" "5" +"theme" "6" +"theme.cpp" "7" +"tooltip" "6" +"tips.cpp" "7" +"tooltip.cpp" "7" +"annotateditemdelegate.cpp" "6" +"ansiescapecodehandler.cpp" "6" +"appmainwindow.cpp" "6" +"basetreeview.cpp" "6" +"benchmarker.cpp" "6" +"buildablehelperlibrary.cpp" "6" +"categorysortfiltermodel.cpp" "6" +"changeset.cpp" "6" +"checkablemessagebox.cpp" "6" +"classnamevalidatinglineedit.cpp" "6" +"codegeneration.cpp" "6" +"completinglineedit.cpp" "6" +"completingtextedit.cpp" "6" +"consoleprocess.cpp" "6" +"consoleprocess_unix.cpp" "6" +"consoleprocess_win.cpp" "6" +"crumblepath.cpp" "6" +"detailsbutton.cpp" "6" +"detailswidget.cpp" "6" +"dropsupport.cpp" "6" +"elfreader.cpp" "6" +"elidinglabel.cpp" "6" +"environment.cpp" "6" +"environmentdialog.cpp" "6" +"environmentmodel.cpp" "6" +"execmenu.cpp" "6" +"fadingindicator.cpp" "6" +"faketooltip.cpp" "6" +"fancylineedit.cpp" "6" +"fancymainwindow.cpp" "6" +"filecrumblabel.cpp" "6" +"fileinprojectfinder.cpp" "6" +"filenamevalidatinglineedit.cpp" "6" +"filesearch.cpp" "6" +"filesystemwatcher.cpp" "6" +"fileutils.cpp" "6" +"filewizardpage.cpp" "6" +"fixedsizeclicklabel.cpp" "6" +"flowlayout.cpp" "6" +"fuzzymatcher.cpp" "6" +"guard.cpp" "6" +"headerviewstretcher.cpp" "6" +"highlightingitemdelegate.cpp" "6" +"historycompleter.cpp" "6" +"hostosinfo.cpp" "6" +"htmldocextractor.cpp" "6" +"icon.cpp" "6" +"itemviews.cpp" "6" +"json.cpp" "6" +"macroexpander.cpp" "6" +"navigationtreeview.cpp" "6" +"networkaccessmanager.cpp" "6" +"newclasswidget.cpp" "6" +"outputformatter.cpp" "6" +"overridecursor.cpp" "6" +"parameteraction.cpp" "6" +"pathchooser.cpp" "6" +"pathlisteditor.cpp" "6" +"persistentsettings.cpp" "6" +"port.cpp" "6" +"portlist.cpp" "6" +"processhandle.cpp" "6" +"progressindicator.cpp" "6" +"projectintropage.cpp" "6" +"proxyaction.cpp" "6" +"proxycredentialsdialog.cpp" "6" +"qtcassert.cpp" "6" +"qtcolorbutton.cpp" "6" +"qtcprocess.cpp" "6" +"reloadpromptutils.cpp" "6" +"removefiledialog.cpp" "6" +"runextensions.cpp" "6" +"savedaction.cpp" "6" +"savefile.cpp" "6" +"settingsaccessor.cpp" "6" +"settingsselector.cpp" "6" +"shellcommand.cpp" "6" +"shellcommandpage.cpp" "6" +"statuslabel.cpp" "6" +"stringutils.cpp" "6" +"styledbar.cpp" "6" +"stylehelper.cpp" "6" +"synchronousprocess.cpp" "6" +"templateengine.cpp" "6" +"temporarydirectory.cpp" "6" +"temporaryfile.cpp" "6" +"textfieldcheckbox.cpp" "6" +"textfieldcombobox.cpp" "6" +"textfileformat.cpp" "6" +"textutils.cpp" "6" +"treemodel.cpp" "6" +"treeviewcombobox.cpp" "6" +"uncommentselection.cpp" "6" +"unixutils.cpp" "6" +"url.cpp" "6" +"utilsicons.cpp" "6" +"winutils.cpp" "6" +"wizard.cpp" "6" +"wizardpage.cpp" "6" +"Forms" "5" +"filewizardpage.ui" "6" +"newclasswidget.ui" "6" +"projectintropage.ui" "6" +"proxycredentialsdialog.ui" "6" +"removefiledialog.ui" "6" +"Resources" "5" +"utils.qrc" "6" +"/utils" "7" +"images" "8" +"app-on-top.png" "9" +"app-on-top@2x.png" "9" +"arrow.png" "9" +"arrowdown.png" "9" +"arrowdown@2x.png" "9" +"arrowup.png" "9" +"arrowup@2x.png" "9" +"bookmark.png" "9" +"bookmark@2x.png" "9" +"boundingrect.png" "9" +"boundingrect@2x.png" "9" +"broken.png" "9" +"broken@2x.png" "9" +"clean_pane_small.png" "9" +"clean_pane_small@2x.png" "9" +"close.png" "9" +"close@2x.png" "9" +"codemodelerror.png" "9" +"codemodelerror@2x.png" "9" +"codemodelwarning.png" "9" +"codemodelwarning@2x.png" "9" +"collapse.png" "9" +"collapse@2x.png" "9" +"compile_error_taskbar.png" "9" +"compile_error_taskbar@2x.png" "9" +"crumblepath-segment-first-hover.png" "9" +"crumblepath-segment-first-hover@2x.png" "9" +"crumblepath-segment-first.png" "9" +"crumblepath-segment-first@2x.png" "9" +"crumblepath-segment-last-hover.png" "9" +"crumblepath-segment-last-hover@2x.png" "9" +"crumblepath-segment-last.png" "9" +"crumblepath-segment-last@2x.png" "9" +"crumblepath-segment-middle-hover.png" "9" +"crumblepath-segment-middle-hover@2x.png" "9" +"crumblepath-segment-middle.png" "9" +"crumblepath-segment-middle@2x.png" "9" +"crumblepath-segment-single-hover.png" "9" +"crumblepath-segment-single-hover@2x.png" "9" +"crumblepath-segment-single.png" "9" +"crumblepath-segment-single@2x.png" "9" +"dark_fileicon.png" "9" +"dark_foldericon.png" "9" +"Desktop.png" "9" +"desktopdevicesmall.png" "9" +"desktopdevicesmall@2x.png" "9" +"editclear.png" "9" +"editclear@2x.png" "9" +"editcopy.png" "9" +"editcopy@2x.png" "9" +"editcut.png" "9" +"editcut@2x.png" "9" +"editpaste.png" "9" +"editpaste@2x.png" "9" +"empty14.png" "9" +"empty16.png" "9" +"error.png" "9" +"error@2x.png" "9" +"expand.png" "9" +"expand@2x.png" "9" +"extension.png" "9" +"extension@2x.png" "9" +"eye_closed.png" "9" +"eye_closed@2x.png" "9" +"eye_open.png" "9" +"eye_open@2x.png" "9" +"fileexport.png" "9" +"fileexport@2x.png" "9" +"filemultiexport.png" "9" +"filemultiexport@2x.png" "9" +"filenew.png" "9" +"filenew@2x.png" "9" +"fileopen.png" "9" +"fileopen@2x.png" "9" +"filesave.png" "9" +"filesave@2x.png" "9" +"filledcircle.png" "9" +"filledcircle@2x.png" "9" +"filtericon.png" "9" +"filtericon@2x.png" "9" +"fittoview.png" "9" +"fittoview@2x.png" "9" +"home.png" "9" +"home@2x.png" "9" +"iconoverlay_add.png" "9" +"iconoverlay_add@2x.png" "9" +"iconoverlay_add_background.png" "9" +"iconoverlay_add_background@2x.png" "9" +"iconoverlay_add_small.png" "9" +"iconoverlay_add_small@2x.png" "9" +"iconoverlay_error.png" "9" +"iconoverlay_error@2x.png" "9" +"iconoverlay_error_background.png" "9" +"iconoverlay_error_background@2x.png" "9" +"iconoverlay_reset.png" "9" +"iconoverlay_reset@2x.png" "9" +"iconoverlay_warning.png" "9" +"iconoverlay_warning@2x.png" "9" +"iconoverlay_warning_background.png" "9" +"iconoverlay_warning_background@2x.png" "9" +"info.png" "9" +"info@2x.png" "9" +"inputfield.png" "9" +"inputfield@2x.png" "9" +"inputfield_disabled.png" "9" +"inputfield_disabled@2x.png" "9" +"interrupt_small.png" "9" +"interrupt_small@2x.png" "9" +"leftsidebaricon.png" "9" +"leftsidebaricon@2x.png" "9" +"lightbulb.png" "9" +"lightbulb@2x.png" "9" +"lightbulbcap.png" "9" +"lightbulbcap@2x.png" "9" +"linkicon.png" "9" +"linkicon@2x.png" "9" +"locked.png" "9" +"locked@2x.png" "9" +"magnifier.png" "9" +"magnifier@2x.png" "9" +"minus.png" "9" +"minus@2x.png" "9" +"namespace.png" "9" +"namespace@2x.png" "9" +"next.png" "9" +"next@2x.png" "9" +"notloaded.png" "9" +"notloaded@2x.png" "9" +"ok.png" "9" +"ok@2x.png" "9" +"pan.png" "9" +"pan@2x.png" "9" +"panel_button.png" "9" +"panel_button@2x.png" "9" +"panel_button_checked.png" "9" +"panel_button_checked@2x.png" "9" +"panel_button_checked_hover.png" "9" +"panel_button_checked_hover@2x.png" "9" +"panel_button_hover.png" "9" +"panel_button_hover@2x.png" "9" +"panel_button_pressed.png" "9" +"panel_button_pressed@2x.png" "9" +"panel_manage_button.png" "9" +"panel_manage_button@2x.png" "9" +"plus.png" "9" +"plus@2x.png" "9" +"prev.png" "9" +"prev@2x.png" "9" +"progressbar.png" "9" +"progressbar@2x.png" "9" +"progressindicator_big.png" "9" +"progressindicator_big@2x.png" "9" +"progressindicator_medium.png" "9" +"progressindicator_medium@2x.png" "9" +"progressindicator_small.png" "9" +"progressindicator_small@2x.png" "9" +"project.png" "9" +"project@2x.png" "9" +"redo.png" "9" +"redo@2x.png" "9" +"reload_gray.png" "9" +"reload_gray@2x.png" "9" +"replace_a.png" "9" +"replace_a@2x.png" "9" +"replace_b.png" "9" +"replace_b@2x.png" "9" +"reset.png" "9" +"reset@2x.png" "9" +"rightsidebaricon.png" "9" +"rightsidebaricon@2x.png" "9" +"run_small.png" "9" +"run_small@2x.png" "9" +"select.png" "9" +"select@2x.png" "9" +"snapshot.png" "9" +"snapshot@2x.png" "9" +"splitbutton_closebottom.png" "9" +"splitbutton_closebottom@2x.png" "9" +"splitbutton_closeleft.png" "9" +"splitbutton_closeleft@2x.png" "9" +"splitbutton_closeright.png" "9" +"splitbutton_closeright@2x.png" "9" +"splitbutton_closetop.png" "9" +"splitbutton_closetop@2x.png" "9" +"splitbutton_horizontal.png" "9" +"splitbutton_horizontal@2x.png" "9" +"splitbutton_vertical.png" "9" +"splitbutton_vertical@2x.png" "9" +"stop_small.png" "9" +"stop_small@2x.png" "9" +"toolbuttonexpandarrow.png" "9" +"toolbuttonexpandarrow@2x.png" "9" +"undo.png" "9" +"undo@2x.png" "9" +"unlocked.png" "9" +"unlocked@2x.png" "9" +"warning.png" "9" +"warning@2x.png" "9" +"warningfill.png" "9" +"warningfill@2x.png" "9" +"wizardicon-file.png" "9" +"wizardicon-file@2x.png" "9" +"zoom.png" "9" +"zoom@2x.png" "9" +"zoomin_overlay.png" "9" +"zoomin_overlay@2x.png" "9" +"zoomout_overlay.png" "9" +"zoomout_overlay@2x.png" "9" +"tooltip" "8" +"images" "9" +"f1.png" "10" +"gmock_dependency" "3" +"gmock_dependency.pri" "4" +"Headers" "4" +"gtest-qt-printing.h" "5" +"Headers" "3" +"chunksreportedmonitor.h" "4" +"clangasyncjob-base.h" "4" +"clangcompareoperators.h" "4" +"compare-operators.h" "4" +"conditionally-disabled-tests.h" "4" +"diagnosticcontainer-matcher.h" "4" +"dummyclangipcclient.h" "4" +"dynamicastmatcherdiagnosticcontainer-matcher.h" "4" +"eventspy.h" "4" +"fakeprocess.h" "4" +"filesystem-utilities.h" "4" +"google-using-declarations.h" "4" +"googletest.h" "4" +"gtest-clang-printing.h" "4" +"gtest-creator-printing.h" "4" +"gtest-qt-printing.h" "4" +"mimedatabase-utilities.h" "4" +"mockclangcodemodelclient.h" "4" +"mockclangcodemodelserver.h" "4" +"mockclangpathwatcher.h" "4" +"mockclangpathwatchernotifier.h" "4" +"mockeditormanager.h" "4" +"mockfilepathcaching.h" "4" +"mockfilepathstorage.h" "4" +"mockmutex.h" "4" +"mockpchcreator.h" "4" +"mockpchgeneratornotifier.h" "4" +"mockpchmanagerclient.h" "4" +"mockpchmanagernotifier.h" "4" +"mockpchmanagerserver.h" "4" +"mockprecompiledheaderstorage.h" "4" +"mockprojectpartprovider.h" "4" +"mockprojectparts.h" "4" +"mockqfilesystemwatcher.h" "4" +"mockrefactoringclient.h" "4" +"mockrefactoringserver.h" "4" +"mocksearch.h" "4" +"mocksearchhandle.h" "4" +"mocksearchresult.h" "4" +"mocksqlitedatabase.h" "4" +"mocksqlitereadstatement.h" "4" +"mocksqlitestatement.h" "4" +"mocksqlitetransactionbackend.h" "4" +"mocksqlitewritestatement.h" "4" +"mocksymbolindexing.h" "4" +"mocksymbolquery.h" "4" +"mocksymbolscollector.h" "4" +"mocksymbolstorage.h" "4" +"mocksyntaxhighligher.h" "4" +"mocktimer.h" "4" +"processevents-utilities.h" "4" +"rundocumentparse-utility.h" "4" +"runprojectcreateorupdate-utility.h" "4" +"sourcerangecontainer-matcher.h" "4" +"spydummy.h" "4" +"sqliteteststatement.h" "4" +"testclangtool.h" "4" +"testenvironment.h" "4" +"unittest-utility-functions.h" "4" +"Sources" "3" +"activationsequencecontextprocessor-test.cpp" "4" +"activationsequenceprocessor-test.cpp" "4" +"changedfilepathcompressor-test.cpp" "4" +"chunksreportedmonitor.cpp" "4" +"clangasyncjob-base.cpp" "4" +"clangcodecompleteresults-test.cpp" "4" +"clangcodemodelserver-test.cpp" "4" +"clangcompletecodejob-test.cpp" "4" +"clangcompletioncontextanalyzer-test.cpp" "4" +"clangdiagnosticfilter-test.cpp" "4" +"clangdocument-test.cpp" "4" +"clangdocumentprocessor-test.cpp" "4" +"clangdocumentprocessors-test.cpp" "4" +"clangdocuments-test.cpp" "4" +"clangdocumentsuspenderresumer-test.cpp" "4" +"clangfixitoperation-test.cpp" "4" +"clangfollowsymbol-test.cpp" "4" +"clangisdiagnosticrelatedtolocation-test.cpp" "4" +"clangjobqueue-test.cpp" "4" +"clangjobs-test.cpp" "4" +"clangparsesupportivetranslationunitjob-test.cpp" "4" +"clangpathwatcher-test.cpp" "4" +"clangquery-test.cpp" "4" +"clangqueryexamplehighlightmarker-test.cpp" "4" +"clangquerygatherer-test.cpp" "4" +"clangqueryhighlightmarker-test.cpp" "4" +"clangqueryprojectfindfilter-test.cpp" "4" +"clangreferencescollector-test.cpp" "4" +"clangrequestannotationsjob-test.cpp" "4" +"clangrequestreferencesjob-test.cpp" "4" +"clangresumedocumentjob-test.cpp" "4" +"clangstring-test.cpp" "4" +"clangsupportivetranslationunitinitializer-test.cpp" "4" +"clangsuspenddocumentjob-test.cpp" "4" +"clangtooltipinfo-test.cpp" "4" +"clangtranslationunit-test.cpp" "4" +"clangtranslationunits-test.cpp" "4" +"clangupdateannotationsjob-test.cpp" "4" +"clientserverinprocess-test.cpp" "4" +"clientserveroutsideprocess-test.cpp" "4" +"codecompleter-test.cpp" "4" +"codecompletionsextractor-test.cpp" "4" +"completionchunkstotextconverter-test.cpp" "4" +"cppprojectfilecategorizer-test.cpp" "4" +"cppprojectinfogenerator-test.cpp" "4" +"cppprojectpartchooser-test.cpp" "4" +"createtablesqlstatementbuilder-test.cpp" "4" +"cursor-test.cpp" "4" +"diagnostic-test.cpp" "4" +"diagnosticset-test.cpp" "4" +"eventspy.cpp" "4" +"fakeprocess.cpp" "4" +"filepath-test.cpp" "4" +"filepathcache-test.cpp" "4" +"filepathstorage-test.cpp" "4" +"filepathstoragesqlitestatementfactory-test.cpp" "4" +"filepathview-test.cpp" "4" +"filestatuscache-test.cpp" "4" +"fixit-test.cpp" "4" +"gtest-clang-printing.cpp" "4" +"gtest-creator-printing.cpp" "4" +"gtest-qt-printing.cpp" "4" +"highlightingresultreporter-test.cpp" "4" +"includecollector-test.cpp" "4" +"lineprefixer-test.cpp" "4" +"locatorfilter-test.cpp" "4" +"matchingtext-test.cpp" "4" +"mimedatabase-utilities.cpp" "4" +"mocksqlitereadstatement.cpp" "4" +"mocktimer.cpp" "4" +"nativefilepath-test.cpp" "4" +"nativefilepathview-test.cpp" "4" +"pchcreator-test.cpp" "4" +"pchgenerator-test.cpp" "4" +"pchmanagerclient-test.cpp" "4" +"pchmanagerclientserverinprocess-test.cpp" "4" +"pchmanagerserver-test.cpp" "4" +"precompiledheaderstorage-test.cpp" "4" +"processcreator-test.cpp" "4" +"processevents-utilities.cpp" "4" +"projectpart-test.cpp" "4" +"projectpartartefact-test.cpp" "4" +"projectparts-test.cpp" "4" +"projectupdater-test.cpp" "4" +"readandwritemessageblock-test.cpp" "4" +"refactoringclient-test.cpp" "4" +"refactoringclientserverinprocess-test.cpp" "4" +"refactoringcompilationdatabase-test.cpp" "4" +"refactoringdatabaseinitializer-test.cpp" "4" +"refactoringengine-test.cpp" "4" +"refactoringserver-test.cpp" "4" +"senddocumenttracker-test.cpp" "4" +"sizedarray-test.cpp" "4" +"skippedsourceranges-test.cpp" "4" +"smallstring-benchmark.cpp" "4" +"smallstring-test.cpp" "4" +"sourcelocation-test.cpp" "4" +"sourcerange-test.cpp" "4" +"sourcerangeextractor-test.cpp" "4" +"sourcerangefilter-test.cpp" "4" +"spydummy.cpp" "4" +"sqlitecolumn-test.cpp" "4" +"sqlitedatabase-test.cpp" "4" +"sqlitedatabasebackend-test.cpp" "4" +"sqliteindex-test.cpp" "4" +"sqlitestatement-test.cpp" "4" +"sqlitetable-test.cpp" "4" +"sqlitetransaction-test.cpp" "4" +"sqlstatementbuilder-test.cpp" "4" +"storagesqlitestatementfactory-test.cpp" "4" +"stringcache-test.cpp" "4" +"symbolfinder-test.cpp" "4" +"symbolindexer-test.cpp" "4" +"symbolindexing-test.cpp" "4" +"symbolquery-test.cpp" "4" +"symbolscollector-test.cpp" "4" +"symbolsfindfilter-test.cpp" "4" +"symbolstorage-test.cpp" "4" +"testclangtool.cpp" "4" +"tokenprocessor-test.cpp" "4" +"translationunitupdater-test.cpp" "4" +"unittests-main.cpp" "4" +"unsavedfile-test.cpp" "4" +"unsavedfiles-test.cpp" "4" +"utf8-test.cpp" "4" +"utf8positionfromlinecolumn-test.cpp" "4" +"Other files" "3" +"data" "4" +"complete_arrow.cpp" "5" +"complete_completer_main.cpp" "5" +"complete_completer_main_unsaved.cpp" "5" +"complete_extractor_brief_comment.cpp" "5" +"complete_extractor_class.cpp" "5" +"complete_extractor_constructor.cpp" "5" +"complete_extractor_enumeration.cpp" "5" +"complete_extractor_function.cpp" "5" +"complete_extractor_function_unsaved.cpp" "5" +"complete_extractor_function_unsaved_2.cpp" "5" +"complete_extractor_functionoverload.cpp" "5" +"complete_extractor_namespace.cpp" "5" +"complete_extractor_variable.cpp" "5" +"complete_forwarding_header_1.h" "5" +"complete_forwarding_header_2.h" "5" +"complete_smartpointer.cpp" "5" +"complete_target_header.h" "5" +"complete_target_header_changed.h" "5" +"complete_target_header_unsaved.h" "5" +"complete_testfile_1.cpp" "5" +"complete_translationunit_parse_error.cpp" "5" +"complete_withDotArrowCorrectionForForwardDeclaredClassPointer.cpp" "5" +"complete_withDotArrowCorrectionForPointer.cpp" "5" +"complete_withDotArrowCorrectionForPointer_afterTyping.cpp" "5" +"complete_withDotArrowCorrectionForPointer_beforeTyping.cpp" "5" +"complete_withDotArrowCorrectionForPointerInitial.cpp" "5" +"complete_withDotArrowCorrectionForPointerUpdated.cpp" "5" +"complete_withGlobalCompletionAfterForwardDeclaredClassPointer.cpp" "5" +"complete_withNoDotArrowCorrectionForArrowDot.cpp" "5" +"complete_withNoDotArrowCorrectionForColonColon.cpp" "5" +"complete_withNoDotArrowCorrectionForDotDot.cpp" "5" +"complete_withNoDotArrowCorrectionForFloat.cpp" "5" +"complete_withNoDotArrowCorrectionForObject.cpp" "5" +"complete_withNoDotArrowCorrectionForObjectWithArrowOperator.cpp" "5" +"complete_withNoDotArrowCorrectionForOnlyDot.cpp" "5" +"cursor.cpp" "5" +"cursor.h" "5" +"diagnostic_comparison_fixit.cpp" "5" +"diagnostic_comparison_fixit_expected1.cpp" "5" +"diagnostic_comparison_fixit_expected2.cpp" "5" +"diagnostic_diagnostic.cpp" "5" +"diagnostic_diagnosticset.cpp" "5" +"diagnostic_diagnosticset_header.cpp" "5" +"diagnostic_diagnosticset_mainfile.cpp" "5" +"diagnostic_erroneous_header.h" "5" +"diagnostic_erroneous_source.cpp" "5" +"diagnostic_semicolon_fixit.cpp" "5" +"diagnostic_semicolon_fixit_expected.cpp" "5" +"diagnostic_source_location.cpp" "5" +"diagnostic_source_range.cpp" "5" +"empty1.cpp" "5" +"empty2.cpp" "5" +"empty3.cpp" "5" +"filestatuscache_header.cpp" "5" +"filestatuscache_header.h" "5" +"followsymbol_header.h" "5" +"followsymbol_main.cpp" "5" +"highlightingmarks.cpp" "5" +"highlightingmarks.h" "5" +"include_testfile.cpp" "5" +"includecollector_external1.h" "5" +"includecollector_external2.h" "5" +"includecollector_external3.h" "5" +"includecollector_false.h" "5" +"includecollector_header1.h" "5" +"includecollector_header2.h" "5" +"includecollector_if.cpp" "5" +"includecollector_indirect_external.h" "5" +"includecollector_indirect_external2.h" "5" +"includecollector_main.cpp" "5" +"includecollector_main2.cpp" "5" +"includecollector_main3.cpp" "5" +"includecollector_missingfile.cpp" "5" +"includecollector_true.h" "5" +"query_simpleclass.cpp" "5" +"query_simplefunction.cpp" "5" +"query_simplefunction2.cpp" "5" +"query_simplefunction2.h" "5" +"query_simplefunction3.cpp" "5" +"references.cpp" "5" +"renamevariable.cpp" "5" +"skippedsourceranges.cpp" "5" +"sourcerangeextractor_location.cpp" "5" +"symbolfinder_macro.cpp" "5" +"symbolindexer_header1.h" "5" +"symbolindexer_header2.h" "5" +"symbolindexer_main1.cpp" "5" +"symbolindexer_main2.cpp" "5" +"symbolindexer_pathChanged.cpp" "5" +"symbolindexing_main1.cpp" "5" +"symbolscollector_defines.h" "5" +"symbolscollector_header1.h" "5" +"symbolscollector_header2.h" "5" +"symbolscollector_header3.h" "5" +"symbolscollector_main.cpp" "5" +"symbolscollector_main2.cpp" "5" +"symbolscollector_simple.cpp" "5" +"symbolscollector_symbolkind.cpp" "5" +"symbolscollector_unsaved.cpp" "5" +"tooltipinfo.cpp" "5" +"tooltipinfo.h" "5" +"translationunits.cpp" "5" +"translationunits.h" "5" "Other files" "0" "dist" "1" -"config" "3" -"config-linux.xml.in" "4" -"config-mac.xml.in" "4" -"config-windows.xml.in" "4" -"packages" "3" -"installscript.qs" "5" -"package.xml.in" "5" -"package.xml.in" "5" "changes-1.1.0" "2" "changes-1.1.1" "2" "changes-1.2.0" "2" @@ -16015,12 +19632,21 @@ "changes-4.3.1.md" "2" "changes-4.4.0.md" "2" "changes-4.4.1.md" "2" +"changes-4.5.0.md" "2" +"changes-4.5.1.md" "2" +"changes-4.5.2.md" "2" +"changes-4.6.0.md" "2" +"changes-4.6.1.md" "2" +"changes-4.6.2.md" "2" +"changes-4.7.0.md" "2" "copyright_template.txt" "2" "scripts" "1" "checkInstalledFiles.py" "2" "clangCompleteAt.sh" "2" +"clazyweb2tasks.pl" "2" "common.py" "2" "createDevPackage.py" "2" +"createDistPackage.py" "2" "createSourcePackages.py" "2" "dependencyinfo.py" "2" "deployqt.py" "2" @@ -16028,18 +19654,19 @@ "fix_makefile_header_dependencies.sh" "2" "fixCopyright.sh" "2" "gcc2tasks.pl" "2" +"generateClangTidyChecks.py" "2" "hasCopyright.pl" "2" "krazy2tasks.pl" "2" -"makedmg.sh" "2" +"makedmg.py" "2" "msanalyzer2tasks.pl" "2" "msvc2tasks.pl" "2" "mytasks.pl" "2" "ninjawrapper.py" "2" -"packageIfw.py" "2" "packagePlugins.py" "2" "perltest2tasks.pl" "2" "purify2tasks.pl" "2" "qdoc2tasks.pl" "2" +"sphinx2tasks.pl" "2" "test2tasks.pl" "2" "uichanges.py" "2" "updateCopyright.pl" "2" -- cgit v1.2.1 From 42e20ce0c3c5374a07d0d99c000a3fe62fc7e4c0 Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Wed, 15 Aug 2018 06:55:02 +0200 Subject: TextEditor: Fix compile on macOS Change-Id: I78929b2d3f6e7803879e63ba5611e5210cc53f90 Reviewed-by: David Schulz --- src/plugins/texteditor/generichighlighter/highlighter.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/plugins/texteditor/generichighlighter/highlighter.cpp b/src/plugins/texteditor/generichighlighter/highlighter.cpp index 055f390261..e7e5e713ab 100644 --- a/src/plugins/texteditor/generichighlighter/highlighter.cpp +++ b/src/plugins/texteditor/generichighlighter/highlighter.cpp @@ -38,6 +38,8 @@ #include +#include + using namespace TextEditor; using namespace Internal; -- cgit v1.2.1 From 8fee3dd4b16da75f621455ff0b2386f819f47c91 Mon Sep 17 00:00:00 2001 From: Marco Benelli Date: Tue, 14 Aug 2018 15:24:04 +0200 Subject: qmljs: update some module versions Update module version for import completion. Task-number: QTCREATORBUG-20785 Change-Id: I11761854bd5c7c4ce832f39b815f7bbf710db5e8 Reviewed-by: Thomas Hartmann --- share/qtcreator/qml-type-descriptions/qt5QtQuick2-bundle.json | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/share/qtcreator/qml-type-descriptions/qt5QtQuick2-bundle.json b/share/qtcreator/qml-type-descriptions/qt5QtQuick2-bundle.json index 84509537cf..12683dc1af 100644 --- a/share/qtcreator/qml-type-descriptions/qt5QtQuick2-bundle.json +++ b/share/qtcreator/qml-type-descriptions/qt5QtQuick2-bundle.json @@ -81,12 +81,16 @@ "QtQuick.Controls 2.0", "QtQuick.Controls 2.1", "QtQuick.Controls 2.2", + "QtQuick.Controls 2.3", + "QtQuick.Controls 2.4", "QtQuick.Controls.Material 2.0", "QtQuick.Controls.Material 2.1", "QtQuick.Controls.Material 2.2", + "QtQuick.Controls.Material 2.3", "QtQuick.Controls.Universal 2.0", "QtQuick.Controls.Universal 2.1", "QtQuick.Controls.Universal 2.2", + "QtQuick.Controls.Universal 2.3", "QtQuick.Controls.Styles 1.0", "QtQuick.Controls.Styles 1.1", "QtQuick.Controls.Styles 1.2", @@ -109,6 +113,8 @@ "QtQuick.Window 2.1", "QtQuick.Window 2.2", "QtQuick.Window 2.3", + "QtQuick.Window 2.10", + "QtQuick.Window 2.11", "QtQuick.XmlListModel 2.0", "QtSensors 5.0", "QtSensors 5.1", @@ -130,6 +136,8 @@ "QtQuick 2.7", "QtQuick 2.8", "QtQuick 2.9", + "QtQuick 2.10", + "QtQuick 2.11", "QtTest 1.0", "QtWebEngine 1.0", "QtWebEngine 1.1", -- cgit v1.2.1 From 58747b2de107e8f6ac00daeb431ecbf3e603fd34 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Tue, 14 Aug 2018 11:44:41 +0200 Subject: Fix hiding file system view's bread crumb When hiding the bread crumbs in the filter option dropdown, there was some spacing and the separator line left. With this patch, the spacing and line are hidden too, making the layout nicer and more similar to before the bread crumbs feature existed. Task-number: QTCREATORBUG-20733 Change-Id: I560b4414804c8cd25e88d645aa3042acb1b8e06c Reviewed-by: Christian Stenger --- src/plugins/projectexplorer/foldernavigationwidget.cpp | 12 +++++++++--- src/plugins/projectexplorer/foldernavigationwidget.h | 1 + 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/plugins/projectexplorer/foldernavigationwidget.cpp b/src/plugins/projectexplorer/foldernavigationwidget.cpp index 0df7005c56..d4c91d32b9 100644 --- a/src/plugins/projectexplorer/foldernavigationwidget.cpp +++ b/src/plugins/projectexplorer/foldernavigationwidget.cpp @@ -295,6 +295,7 @@ FolderNavigationWidget::FolderNavigationWidget(QWidget *parent) : QWidget(parent m_toggleSync(new QToolButton(this)), m_toggleRootSync(new QToolButton(this)), m_rootSelector(new QComboBox), + m_crumbContainer(new QWidget(this)), m_crumbLabel(new DelayedFileCrumbLabel(this)) { m_context = new Core::IContext(this); @@ -337,16 +338,21 @@ FolderNavigationWidget::FolderNavigationWidget(QWidget *parent) : QWidget(parent selectorLayout->setContentsMargins(0, 0, 0, 0); selectorLayout->addWidget(m_rootSelector, 10); + auto crumbContainerLayout = new QVBoxLayout; + crumbContainerLayout->setSpacing(0); + crumbContainerLayout->setContentsMargins(0, 0, 0, 0); + m_crumbContainer->setLayout(crumbContainerLayout); auto crumbLayout = new QVBoxLayout; crumbLayout->setSpacing(0); crumbLayout->setContentsMargins(4, 4, 4, 4); crumbLayout->addWidget(m_crumbLabel); + crumbContainerLayout->addLayout(crumbLayout); + crumbContainerLayout->addWidget(createHLine()); m_crumbLabel->setAlignment(Qt::AlignLeft | Qt::AlignTop); auto layout = new QVBoxLayout(); layout->addWidget(selectorWidget); - layout->addLayout(crumbLayout); - layout->addWidget(createHLine()); + layout->addWidget(m_crumbContainer); layout->addWidget(m_listView); layout->setSpacing(0); layout->setContentsMargins(0, 0, 0, 0); @@ -432,7 +438,7 @@ void FolderNavigationWidget::toggleAutoSynchronization() void FolderNavigationWidget::setShowBreadCrumbs(bool show) { m_showBreadCrumbsAction->setChecked(show); - m_crumbLabel->setVisible(show); + m_crumbContainer->setVisible(show); } void FolderNavigationWidget::setShowFoldersOnTop(bool onTop) diff --git a/src/plugins/projectexplorer/foldernavigationwidget.h b/src/plugins/projectexplorer/foldernavigationwidget.h index 1e55bbe83a..8f428863eb 100644 --- a/src/plugins/projectexplorer/foldernavigationwidget.h +++ b/src/plugins/projectexplorer/foldernavigationwidget.h @@ -145,6 +145,7 @@ private: QToolButton *m_toggleSync = nullptr; QToolButton *m_toggleRootSync = nullptr; QComboBox *m_rootSelector = nullptr; + QWidget *m_crumbContainer = nullptr; DelayedFileCrumbLabel *m_crumbLabel = nullptr; // FolderNavigationWidgetFactory needs private members to build a menu -- cgit v1.2.1